-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcolor.go
107 lines (90 loc) · 2.25 KB
/
color.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
package g
type Color struct{ R, G, B, A uint8 }
var (
White = Color{0xFF, 0xFF, 0xFF, 0xFF}
Black = Color{0x00, 0x00, 0x00, 0xFF}
Red = Color{0xFF, 0x00, 0x00, 0xFF}
Green = Color{0x00, 0xFF, 0x00, 0xFF}
Blue = Color{0x00, 0x00, 0xFF, 0xFF}
Yellow = Color{0xFF, 0xFF, 0x00, 0xFF}
)
func RGBAHex(hex uint32) Color {
return Color{
R: uint8(hex >> 24),
G: uint8(hex >> 16),
B: uint8(hex >> 8),
A: uint8(hex >> 0),
}
}
// RGBA returns color based on RGBA in range 0..1
func RGBA(r, g, b, a float32) Color { return Color{sat8(r), sat8(g), sat8(b), sat8(a)} }
// HSLA returns color based on HSLA in range 0..1
func HSLA(h, s, l, a float32) Color { return RGBA(hsla(h, s, l, a)) }
// HSL returns color based on HSL in range 0..1
func HSL(h, s, l float32) Color { return HSLA(h, s, l, 1) }
// WithAlpha returns new color with different alpha
func (c Color) WithAlpha(a uint8) Color {
c.A = a
return c
}
// Float returns RGBA scaled to 0..1
func (c Color) Float() (r, g, b, a float32) {
return float32(c.R) / 0xFF, float32(c.G) / 0xFF, float32(c.B) / 0xFF, float32(c.A) / 0xFF
}
// Bytes returns []byte{R, G, B, A}
func (c Color) Bytes() []byte { return []byte{c.R, c.G, c.B, c.A} }
// Lerp linearly interpolates each RGBA component separately
func (a Color) Lerp(b Color, p float32) Color {
ar, ag, ab, aa := a.Float()
br, bg, bb, ba := b.Float()
return RGBA(
LerpClamp(ar, br, p),
LerpClamp(ag, bg, p),
LerpClamp(ab, bb, p),
LerpClamp(aa, ba, p),
)
}
func hue(v1, v2, h float32) float32 {
if h < 0 {
h += 1
}
if h > 1 {
h -= 1
}
if 6*h < 1 {
return v1 + (v2-v1)*6*h
} else if 2*h < 1 {
return v2
} else if 3*h < 2 {
return v1 + (v2-v1)*(2.0/3.0-h)*6
}
return v1
}
func hsla(h, s, l, a float32) (r, g, b, ra float32) {
if s == 0 {
return l, l, l, a
}
h = Mod(h, 1)
var v2 float32
if l < 0.5 {
v2 = l * (1 + s)
} else {
v2 = (l + s) - s*l
}
v1 := 2*l - v2
r = hue(v1, v2, h+1.0/3.0)
g = hue(v1, v2, h)
b = hue(v1, v2, h-1.0/3.0)
ra = a
return
}
// sat8 converts 0..1 float to 0..255 uint8
func sat8(v float32) uint8 {
v *= 255.0
if v >= 255 {
return 255
} else if v <= 0 {
return 0
}
return uint8(v)
}