forked from quasilyte/ge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathline.go
127 lines (104 loc) · 2.39 KB
/
line.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package ge
import (
"math"
"github.com/hajimehoshi/ebiten/v2"
"github.com/quasilyte/ge/internal/primitives"
"github.com/quasilyte/gmath"
)
type Line struct {
BeginPos Pos
EndPos Pos
Width float64
colorScale ColorScale
colorM ebiten.ColorM
colorsChanged bool
Visible bool
disposed bool
}
func NewLine(begin, end Pos) *Line {
return &Line{
Visible: true,
colorScale: defaultColorScale,
BeginPos: begin,
EndPos: end,
Width: 1,
}
}
func (l *Line) IsDisposed() bool {
return l.disposed
}
func (l *Line) Dispose() {
l.disposed = true
}
func (l *Line) BoundsRect() gmath.Rect {
pos1 := l.BeginPos.Resolve()
pos2 := l.EndPos.Resolve()
x0 := pos1.X
x1 := pos2.X
y0 := pos1.Y
y1 := pos2.Y
if x0 > x1 {
x0, x1 = x1, x0
}
if y0 > y1 {
y0, y1 = y1, y0
}
return gmath.Rect{Min: gmath.Vec{X: x0, Y: y0}, Max: gmath.Vec{X: x1, Y: y1}}
}
func (l *Line) Draw(screen *ebiten.Image) {
l.DrawWithOffset(screen, gmath.Vec{})
}
func (l *Line) DrawWithOffset(screen *ebiten.Image, offset gmath.Vec) {
if !l.Visible {
return
}
if l.colorsChanged {
l.colorsChanged = false
l.recalculateColorM()
}
pos1 := l.BeginPos.Resolve()
pos2 := l.EndPos.Resolve()
drawLine(screen, pos1.Add(offset), pos2.Add(offset), l.Width, l.colorM)
}
func (l *Line) SetColorScaleRGBA(r, g, b, a uint8) {
var scale ColorScale
scale.SetRGBA(r, g, b, a)
l.SetColorScale(scale)
}
func (l *Line) GetAlpha() float32 {
return l.colorScale.A
}
func (l *Line) SetAlpha(a float32) {
if l.colorScale.A == a {
return
}
l.colorScale.A = a
l.colorsChanged = true
}
func (l *Line) SetColorScale(colorScale ColorScale) {
if l.colorScale == colorScale {
return
}
l.colorScale = colorScale
l.colorsChanged = true
}
func (l *Line) recalculateColorM() {
var colorM ebiten.ColorM
if l.colorScale != defaultColorScale {
colorM.Scale(float64(l.colorScale.R), float64(l.colorScale.G), float64(l.colorScale.B), float64(l.colorScale.A))
}
l.colorM = colorM
}
func drawLine(dst *ebiten.Image, pos1, pos2 gmath.Vec, width float64, colorM ebiten.ColorM) {
x1 := pos1.X
y1 := pos1.Y
x2 := pos2.X
y2 := pos2.Y
length := math.Hypot(x2-x1, y2-y1)
var drawOptions ebiten.DrawImageOptions
drawOptions.GeoM.Scale(length, width)
drawOptions.GeoM.Rotate(math.Atan2(y2-y1, x2-x1))
drawOptions.GeoM.Translate(x1, y1)
drawOptions.ColorM = colorM
dst.DrawImage(primitives.WhitePixel, &drawOptions)
}