effects.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package rgb
  2. import (
  3. "fmt"
  4. "math"
  5. "strconv"
  6. )
  7. // LEDParam defines QMK rgblight parameter indices.
  8. type LEDParam uint8
  9. const (
  10. Brightness LEDParam = 1
  11. EffectID LEDParam = 2
  12. Speed LEDParam = 3
  13. ColorValue LEDParam = 4
  14. Mode LEDParam = EffectID
  15. Enable LEDParam = EffectID
  16. )
  17. // Color represents an RGB color.
  18. type Color struct {
  19. R uint8
  20. G uint8
  21. B uint8
  22. }
  23. // ParseHexColor parses a 6-digit hex color string (e.g. "ff0000").
  24. func ParseHexColor(s string) (Color, error) {
  25. if len(s) != 6 {
  26. return Color{}, fmt.Errorf("invalid hex color: %s", s)
  27. }
  28. r, err := strconv.ParseUint(s[0:2], 16, 8)
  29. if err != nil {
  30. return Color{}, fmt.Errorf("invalid hex color: %s", s)
  31. }
  32. g, err := strconv.ParseUint(s[2:4], 16, 8)
  33. if err != nil {
  34. return Color{}, fmt.Errorf("invalid hex color: %s", s)
  35. }
  36. b, err := strconv.ParseUint(s[4:6], 16, 8)
  37. if err != nil {
  38. return Color{}, fmt.Errorf("invalid hex color: %s", s)
  39. }
  40. return Color{R: uint8(r), G: uint8(g), B: uint8(b)}, nil
  41. }
  42. // HSV converts the color to HSV (QMK rgblight uses 0-255 ranges for H, S, V).
  43. func (c Color) HSV() (h, s, v uint8) {
  44. r, g, b := float64(c.R), float64(c.G), float64(c.B)
  45. max := math.Max(r, math.Max(g, b))
  46. min := math.Min(r, math.Min(g, b))
  47. v = uint8(max)
  48. d := max - min
  49. if d == 0 {
  50. return 0, 0, v
  51. }
  52. if max > 0 {
  53. s = uint8((d / max) * 255)
  54. } else {
  55. return 0, 0, 0
  56. }
  57. var hFloat float64
  58. switch {
  59. case max == r:
  60. hFloat = ((g - b) / d) * 60.0
  61. case max == g:
  62. hFloat = ((b-r)/d)*60.0 + 120.0
  63. case max == b:
  64. hFloat = ((r-g)/d)*60.0 + 240.0
  65. }
  66. if hFloat < 0 {
  67. hFloat += 360.0
  68. }
  69. h = uint8((hFloat / 360.0) * 255.0)
  70. if h >= 255 {
  71. h = 254
  72. }
  73. return h, s, v
  74. }