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

package models
import (
"fmt"
"math"
"strconv"
"strings"
)
type ColorValue struct {
Hue float64 `json:"h,omitempty"` // 0..360
Saturation float64 `json:"s,omitempty"` // 0..=1
Kelvin int `json:"kelvin,omitempty"`
}
func (c *ColorValue) IsHueSat() bool {
return !c.IsKelvin()
}
func (c *ColorValue) IsKelvin() bool {
return c.Kelvin > 0
}
func (c *ColorValue) String() string {
if c.Kelvin > 0 {
return fmt.Sprintf("k:%d", c.Kelvin)
}
return fmt.Sprintf("hs:%.4g,%.3g", c.Hue, c.Saturation)
}
func ParseColorValue(raw string) (ColorValue, error) {
tokens := strings.SplitN(raw, ":", 2)
if len(tokens) != 2 {
return ColorValue{}, ErrBadInput
}
if tokens[0] == "kelvin" || tokens[0] == "k" {
parsedPart, err := strconv.Atoi(tokens[1])
if err != nil {
return ColorValue{}, ErrBadInput
}
return ColorValue{Kelvin: parsedPart}, nil
}
if tokens[0] == "hs" {
parts := strings.Split(tokens[1], ",")
if len(parts) < 2 {
return ColorValue{}, ErrUnknownColorFormat
}
part1, err1 := strconv.ParseFloat(parts[0], 64)
part2, err2 := strconv.ParseFloat(parts[1], 64)
if err1 != nil || err2 != nil {
return ColorValue{}, ErrBadInput
}
return ColorValue{Hue: math.Mod(part1, 360), Saturation: math.Min(math.Max(part2, 0), 1)}, nil
}
if tokens[0] == "hsk" {
parts := strings.Split(tokens[1], ",")
if len(parts) < 3 {
return ColorValue{}, ErrUnknownColorFormat
}
part1, err1 := strconv.ParseFloat(parts[0], 64)
part2, err2 := strconv.ParseFloat(parts[1], 64)
part3, err3 := strconv.Atoi(parts[2])
if err1 != nil || err2 != nil || err3 != nil {
return ColorValue{}, ErrBadInput
}
return ColorValue{
Hue: math.Mod(part1, 360),
Saturation: math.Min(math.Max(part2, 0), 1),
Kelvin: part3,
}, nil
}
return ColorValue{}, ErrUnknownColorFormat
}