-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcolor_flow.go
137 lines (113 loc) · 3.08 KB
/
color_flow.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
128
129
130
131
132
133
134
135
136
137
package animations
import (
"image/color"
"github.com/AllenDang/cimgui-go/imgui"
"github.com/AllenDang/giu"
)
var _ Animation = &ColorFlowAnimation{}
// ColorFlowAnimation makes a smooth flow from one color to another
// on all specified StyleColor variables.
type ColorFlowAnimation struct {
id giu.ID
giu.Widget
applyingStyles []giu.StyleColorID
color []func() color.RGBA
}
// ColorFlowStyle wraps ColorFlow so that it automatically obtains the color for specified style values.
func ColorFlowStyle(
widget giu.Widget,
normal, destiny giu.StyleColorID,
) *ColorFlowAnimation {
return ColorFlow(
widget,
[]giu.StyleColorID{normal, destiny},
func() color.RGBA {
return giu.Vec4ToRGBA(*imgui.StyleColorVec4(imgui.Col(normal)))
},
func() color.RGBA {
return giu.Vec4ToRGBA(*imgui.StyleColorVec4(imgui.Col(destiny)))
},
)
}
// ColorFlowColors takes a colors list instead of list of functions returning colors.
func ColorFlowColors(
widget giu.Widget,
applying []giu.StyleColorID,
colors ...color.Color,
) *ColorFlowAnimation {
c := make([]func() color.RGBA, len(colors))
for i := range c {
c[i] = func() color.RGBA {
r, g, b, a := colors[i].RGBA()
return color.RGBA{
R: byte(r),
G: byte(g),
B: byte(b),
A: byte(a),
}
}
}
return ColorFlow(widget, applying, c...)
}
// ColorFlow creates a new ColorFlowAnimation.
func ColorFlow(
widget giu.Widget,
applying []giu.StyleColorID,
colors ...func() color.RGBA,
) *ColorFlowAnimation {
return &ColorFlowAnimation{
id: giu.GenAutoID("colorFlowAnimation"),
Widget: widget,
applyingStyles: applying,
color: colors,
}
}
// Reset implements Animation.
func (c *ColorFlowAnimation) Reset() {
// noop
}
// Init implements Animation.
func (c *ColorFlowAnimation) Init() {
// noop
}
// KeyFramesCount implements Animation.
func (c *ColorFlowAnimation) KeyFramesCount() int {
return len(c.color)
}
// BuildNormal builds animation in normal, not-triggered state.
func (c *ColorFlowAnimation) BuildNormal(currentKeyFrame KeyFrame, _ StarterFunc) {
normalColor := c.color[currentKeyFrame]()
c.build(normalColor)
}
// BuildAnimation implements Animation.
func (c *ColorFlowAnimation) BuildAnimation(
percentage, _ float32,
sourceKeyFrame, destinyKeyFrame KeyFrame,
_ PlayMode,
_ StarterFunc,
) {
normalColor := giu.ToVec4Color(c.color[sourceKeyFrame]())
destinationColor := giu.ToVec4Color(c.color[destinyKeyFrame]())
normalColor.X += (destinationColor.X - normalColor.X) * percentage
normalColor.X = clamp01(normalColor.X)
normalColor.Y += (destinationColor.Y - normalColor.Y) * percentage
normalColor.Y = clamp01(normalColor.Y)
normalColor.Z += (destinationColor.Z - normalColor.Z) * percentage
normalColor.Z = clamp01(normalColor.Z)
c.build(giu.Vec4ToRGBA(normalColor))
}
func (c *ColorFlowAnimation) build(col color.Color) {
for _, s := range c.applyingStyles {
giu.PushStyleColor(s, col)
}
defer giu.PopStyleColorV(len(c.applyingStyles))
c.Widget.Build()
}
func clamp01(val float32) float32 {
if val <= 0 {
return 0
} else if val >= 1 {
return 1
}
return val
}