You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
1.8 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package models
  2. import (
  3. "fmt"
  4. "math"
  5. "strconv"
  6. "strings"
  7. )
  8. type ColorValue struct {
  9. Hue float64 `json:"h,omitempty"` // 0..360
  10. Saturation float64 `json:"s,omitempty"` // 0..=1
  11. Kelvin int `json:"kelvin,omitempty"`
  12. }
  13. func (c *ColorValue) IsHueSat() bool {
  14. return !c.IsKelvin()
  15. }
  16. func (c *ColorValue) IsKelvin() bool {
  17. return c.Kelvin > 0
  18. }
  19. func (c *ColorValue) String() string {
  20. if c.Kelvin > 0 {
  21. return fmt.Sprintf("k:%d", c.Kelvin)
  22. }
  23. return fmt.Sprintf("hs:%.4g,%.3g", c.Hue, c.Saturation)
  24. }
  25. func ParseColorValue(raw string) (ColorValue, error) {
  26. tokens := strings.SplitN(raw, ":", 2)
  27. if len(tokens) != 2 {
  28. return ColorValue{}, ErrBadInput
  29. }
  30. if tokens[0] == "kelvin" || tokens[0] == "k" {
  31. parsedPart, err := strconv.Atoi(tokens[1])
  32. if err != nil {
  33. return ColorValue{}, ErrBadInput
  34. }
  35. return ColorValue{Kelvin: parsedPart}, nil
  36. }
  37. if tokens[0] == "hs" {
  38. parts := strings.Split(tokens[1], ",")
  39. if len(parts) < 2 {
  40. return ColorValue{}, ErrUnknownColorFormat
  41. }
  42. part1, err1 := strconv.ParseFloat(parts[0], 64)
  43. part2, err2 := strconv.ParseFloat(parts[1], 64)
  44. if err1 != nil || err2 != nil {
  45. return ColorValue{}, ErrBadInput
  46. }
  47. return ColorValue{Hue: math.Mod(part1, 360), Saturation: math.Min(math.Max(part2, 0), 1)}, nil
  48. }
  49. if tokens[0] == "hsk" {
  50. parts := strings.Split(tokens[1], ",")
  51. if len(parts) < 3 {
  52. return ColorValue{}, ErrUnknownColorFormat
  53. }
  54. part1, err1 := strconv.ParseFloat(parts[0], 64)
  55. part2, err2 := strconv.ParseFloat(parts[1], 64)
  56. part3, err3 := strconv.Atoi(parts[2])
  57. if err1 != nil || err2 != nil || err3 != nil {
  58. return ColorValue{}, ErrBadInput
  59. }
  60. return ColorValue{
  61. Hue: math.Mod(part1, 360),
  62. Saturation: math.Min(math.Max(part2, 0), 1),
  63. Kelvin: part3,
  64. }, nil
  65. }
  66. return ColorValue{}, ErrUnknownColorFormat
  67. }