...
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.thumbBounds = image.Rectangle{}
41 }
42
43
44 func (s *Sprite) SetHorizontal(h Alignment) {
45 s.Lock()
46 defer s.Unlock()
47
48 s.horizontal = h
49 s.thumbBounds = image.Rectangle{}
50 }
51
52
53 func (s *Sprite) SetVertical(v Alignment) {
54 s.Lock()
55 defer s.Unlock()
56
57 s.vertical = v
58 s.thumbBounds = image.Rectangle{}
59 }
60
61
62 func (s *Sprite) Draw(screen *ebiten.Image) error {
63 s.Lock()
64 defer s.Unlock()
65
66 if s.rect.Dx() == 0 || s.rect.Dy() == 0 {
67 return nil
68 }
69
70 op := &ebiten.DrawImageOptions{}
71 op.GeoM.Translate(float64(s.rect.Min.X), float64(s.rect.Min.Y))
72 if s.imgBounds.Dx() == s.rect.Dx() && s.imgBounds.Dy() == s.rect.Dy() {
73 screen.DrawImage(s.img, op)
74 return nil
75 } else if s.thumb == nil || s.thumbBounds.Dx() != s.rect.Dx() || s.thumbBounds.Dy() != s.rect.Dy() {
76 scale, yScale := float64(s.rect.Dx())/float64(s.imgBounds.Dx()), float64(s.rect.Dy())/float64(s.imgBounds.Dy())
77 if yScale < scale {
78 scale = yScale
79 }
80 thumbOp := &ebiten.DrawImageOptions{}
81 thumbOp.GeoM.Scale(scale, scale)
82 if s.horizontal != AlignStart {
83 delta := float64(s.rect.Dx()) - float64(s.imgBounds.Dx())*scale
84 if s.horizontal == AlignCenter {
85 thumbOp.GeoM.Translate(delta/2, 0)
86 } else {
87 thumbOp.GeoM.Translate(delta, 0)
88 }
89 }
90 if s.vertical != AlignStart {
91 delta := float64(s.rect.Dy()) - float64(s.imgBounds.Dy())*scale
92 if s.vertical == AlignCenter {
93 thumbOp.GeoM.Translate(0, delta/2)
94 } else {
95 thumbOp.GeoM.Translate(0, delta)
96 }
97 }
98 createThumb := s.thumb == nil
99 if !createThumb {
100 bounds := s.thumb.Bounds()
101 createThumb = bounds.Dx() != s.rect.Dx() || bounds.Dy() != s.rect.Dy()
102 }
103 if createThumb {
104 s.thumb = ebiten.NewImage(s.rect.Dx(), s.rect.Dy())
105 }
106 s.thumb.DrawImage(s.img, thumbOp)
107 s.thumbBounds = s.thumb.Bounds()
108 }
109 screen.DrawImage(s.thumb, op)
110 return nil
111 }
112
View as plain text