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.

63 lines
1.3 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
  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("kelvin:%d", c.Kelvin)
  22. }
  23. return fmt.Sprintf("hsv:%f,%f", 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" {
  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. return ColorValue{}, ErrUnknownColorFormat
  50. }