-
Notifications
You must be signed in to change notification settings - Fork 0
/
rgb.go
126 lines (103 loc) · 2.42 KB
/
rgb.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
package colorcode
import (
"fmt"
"math"
)
// RGB represents a traditional 24-bit color, having 8 bits
// for each of red, green, and blue. Implements fmt.Stringer
type RGB struct {
R, G, B uint8
}
// NewRGB returns a new RGB object constructured out of the
// values given to the constructor function
func NewRGB(r, g, b uint8) RGB {
return RGB{r, g, b}
}
// String returns a string representation of the RGB object
func (c RGB) String() string {
return fmt.Sprintf("rgb(%d, %d, %d)", c.R, c.G, c.B)
}
// ToHSL converts an RGB color to the HSL representation
func (c RGB) ToHSL() HSL {
var h, s, l float64
fracR := float64(c.R) / 255.0
fracG := float64(c.G) / 255.0
fracB := float64(c.B) / 255.0
max := math.Max(math.Max(fracR, fracG), fracB)
min := math.Min(math.Min(fracR, fracG), fracB)
// Luminosity is the average of the max and min rgb color intensities.
l = (max + min) / 2
// saturation
delta := max - min
if delta == 0 {
// it's gray
return HSL{0, 0, l * 100}
}
// it's not gray
if l < 0.5 {
s = delta / (max + min)
} else {
s = delta / (2 - max - min)
}
// hue
r2 := (((max - fracR) / 6) + (delta / 2)) / delta
g2 := (((max - fracG) / 6) + (delta / 2)) / delta
b2 := (((max - fracB) / 6) + (delta / 2)) / delta
switch {
case fracR == max:
h = b2 - g2
case fracG == max:
h = (1.0 / 3.0) + r2 - b2
case fracB == max:
h = (2.0 / 3.0) + g2 - r2
}
// fix wraparounds
switch {
case h < 0:
h++
case h > 1:
h--
}
return HSL{h * 360, s * 100, l * 100}
}
// ToHSV returns the HSV representation of the RGB color
func (c RGB) ToHSV() HSV {
var h, s, v float64
fracR := float64(c.R) / 255.0
fracG := float64(c.G) / 255.0
fracB := float64(c.B) / 255.0
max := math.Max(math.Max(fracR, fracG), fracB)
min := math.Min(math.Min(fracR, fracG), fracB)
diff := max - min
errorCorrect := func(g, b float64) float64 {
if g < b {
return 6
}
return 0
}
v = max
if max == 0 {
s = 0
} else {
s = diff / max
}
if max == min {
h = 0
} else {
switch {
case fracR == max:
h = ((fracG - fracB) / diff) + errorCorrect(fracG, fracB)
case fracG == max:
h = ((fracB - fracR) / diff) + 2
case fracB == max:
h = ((fracR - fracG) / diff) + 4
}
h /= 6
}
return HSV{h * 360.0, s * 100.0, v * 100.0}
}
// ToHexCode returns a Hex color string equivalent of the the
// RGB color
func (c RGB) ToHexCode() HexCode {
return HexCode(fmt.Sprintf("#%02x%02x%02x", c.R, c.G, c.B))
}