github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/pixel/flowers/color.go (about) 1 package main 2 3 import "math" 4 5 type RGBA uint32 6 type RGB struct{ R, G, B uint8 } 7 type HSL struct{ H, S, L float64 } 8 9 func (rgba RGBA) RGBA() (r, g, b, a uint32) { 10 r = uint32(rgba >> 24 & 0xFF) 11 g = uint32(rgba >> 16 & 0xFF) 12 b = uint32(rgba >> 8 & 0xFF) 13 a = uint32(rgba >> 0 & 0xFF) 14 r |= r << 8 15 g |= g << 8 16 b |= b << 8 17 a |= a << 8 18 return 19 } 20 21 func (rgb RGB) RGBA() (r, g, b, a uint32) { 22 r, g, b = uint32(rgb.R), uint32(rgb.G), uint32(rgb.B) 23 r |= r << 8 24 g |= g << 8 25 b |= b << 8 26 a = 0xFFFF 27 return 28 } 29 30 func (hsl HSL) RGBA() (r, g, b, a uint32) { 31 r1, g1, b1, _ := hsla(hsl.H, hsl.S, hsl.L, 1) 32 return sat16(r1), sat16(g1), sat16(b1), 0xFFFF 33 } 34 35 func hue(v1, v2, h float64) float64 { 36 if h < 0 { 37 h += 1 38 } 39 if h > 1 { 40 h -= 1 41 } 42 if 6*h < 1 { 43 return v1 + (v2-v1)*6*h 44 } else if 2*h < 1 { 45 return v2 46 } else if 3*h < 2 { 47 return v1 + (v2-v1)*(2.0/3.0-h)*6 48 } 49 50 return v1 51 } 52 53 func hsla(h, s, l, a float64) (r, g, b, ra float64) { 54 if s == 0 { 55 return l, l, l, a 56 } 57 58 h = math.Mod(h, TAU) / TAU 59 60 var v2 float64 61 if l < 0.5 { 62 v2 = l * (1 + s) 63 } else { 64 v2 = (l + s) - s*l 65 } 66 67 v1 := 2*l - v2 68 r = hue(v1, v2, h+1.0/3.0) 69 g = hue(v1, v2, h) 70 b = hue(v1, v2, h-1.0/3.0) 71 ra = a 72 73 return 74 } 75 76 // sat16 converts 0..1 float to 0..0xFFFF uint32 77 func sat16(v float64) uint32 { 78 v = v * 0xFFFF 79 if v >= 0xFFFF { 80 return 0xFFFF 81 } else if v <= 0 { 82 return 0 83 } 84 return uint32(v) & 0xFFFF 85 }