...
1 package etk
2
3 import (
4 "image"
5
6 "github.com/hajimehoshi/ebiten/v2"
7 )
8
9
10 type Sprite struct {
11 *Box
12
13 img *ebiten.Image
14 imgBounds image.Rectangle
15
16 thumb *ebiten.Image
17 thumbBounds image.Rectangle
18
19 horizontal Alignment
20 vertical Alignment
21 }
22
23
24 func NewSprite(img *ebiten.Image) *Sprite {
25 return &Sprite{
26 Box: NewBox(),
27 img: img,
28 imgBounds: img.Bounds(),
29 horizontal: AlignCenter,
30 vertical: AlignCenter,
31 }
32 }
33
34
35 func (s *Sprite) SetImage(img *ebiten.Image) {
36 s.Lock()
37 defer s.Unlock()
38
39 s.img = img
40 s.imgBounds = s.img.Bounds()
41 s.thumbBounds = image.Rectangle{}
42 }
43
44
45 func (s *Sprite) SetHorizontal(h Alignment) {
46 s.Lock()
47 defer s.Unlock()
48
49 s.horizontal = h
50 s.thumbBounds = image.Rectangle{}
51 }
52
53
54 func (s *Sprite) SetVertical(v Alignment) {
55 s.Lock()
56 defer s.Unlock()
57
58 s.vertical = v
59 s.thumbBounds = image.Rectangle{}
60 }
61
62
63 func (s *Sprite) Draw(screen *ebiten.Image) error {
64 s.Lock()
65 defer s.Unlock()
66
67 if s.rect.Dx() == 0 || s.rect.Dy() == 0 {
68 return nil
69 }
70
71 op := &ebiten.DrawImageOptions{}
72 op.GeoM.Translate(float64(s.rect.Min.X), float64(s.rect.Min.Y))
73 if s.imgBounds.Dx() == s.rect.Dx() && s.imgBounds.Dy() == s.rect.Dy() {
74 screen.DrawImage(s.img, op)
75 return nil
76 } else if s.thumb == nil || s.thumbBounds.Dx() != s.rect.Dx() || s.thumbBounds.Dy() != s.rect.Dy() {
77 scale, yScale := float64(s.rect.Dx())/float64(s.imgBounds.Dx()), float64(s.rect.Dy())/float64(s.imgBounds.Dy())
78 if yScale < scale {
79 scale = yScale
80 }
81 thumbOp := &ebiten.DrawImageOptions{}
82 thumbOp.GeoM.Scale(scale, scale)
83 if s.horizontal != AlignStart {
84 delta := float64(s.rect.Dx()) - float64(s.imgBounds.Dx())*scale
85 if s.horizontal == AlignCenter {
86 thumbOp.GeoM.Translate(delta/2, 0)
87 } else {
88 thumbOp.GeoM.Translate(delta, 0)
89 }
90 }
91 if s.vertical != AlignStart {
92 delta := float64(s.rect.Dy()) - float64(s.imgBounds.Dy())*scale
93 if s.vertical == AlignCenter {
94 thumbOp.GeoM.Translate(0, delta/2)
95 } else {
96 thumbOp.GeoM.Translate(0, delta)
97 }
98 }
99 createThumb := s.thumb == nil
100 if !createThumb {
101 bounds := s.thumb.Bounds()
102 createThumb = bounds.Dx() != s.rect.Dx() || bounds.Dy() != s.rect.Dy()
103 }
104 if createThumb {
105 s.thumb = ebiten.NewImage(s.rect.Dx(), s.rect.Dy())
106 }
107 s.thumb.DrawImage(s.img, thumbOp)
108 s.thumbBounds = s.thumb.Bounds()
109 }
110 screen.DrawImage(s.thumb, op)
111 return nil
112 }
113
View as plain text