commit 824b07eaeb28f25761495d7800bb18ba87a25317
parent 1ef2be684dd04560c492710f2f1c6557254d1b52
Author: Thomas Frössman <thomasf@jossystem.se>
Date: Wed, 20 Nov 2019 10:33:05 +0100
colorlab: refactor
Diffstat:
9 files changed, 342 insertions(+), 259 deletions(-)
diff --git a/colorlab/main.go b/colorlab/main.go
@@ -36,7 +36,6 @@ func main() {
for _, pal := range palettes {
fmt.Println(pal.Name)
nc := pal.Generate()
-
nc.PrintAlist(os.Stdout, 0)
// nc.FilterPrefix("base").PrintAlist(os.Stdout, 0)
// Merge(nc.FilterSuffix("-d"), oldDarkAccents.NamedColors().WithSuffix("-do")).PrintAlist(os.Stdout, 0)
@@ -140,6 +139,9 @@ type AccentPairGenerator struct {
BlendBackgroundAmout float64
BlendForegroundAmout float64
Gamma float64
+
+ // BackgroundBlendColor ColorFinder
+ // ForegroundBlendColor ColorFinder
}
func (g *AccentPairGenerator) Generate(sol colorlab.Solarized) (backgrounds, foregrounds colorlab.Accents) {
@@ -157,29 +159,8 @@ func (g *AccentPairGenerator) Generate(sol colorlab.Solarized) (backgrounds, for
fmt.Println(" ")
}
- blendBgColor := sol.Base03.Color()
- blendFgColor := sol.Base0.Color()
- brightOnDark := true
- if light(blendFgColor) < light(blendBgColor) {
- brightOnDark = false
- }
- for _, v := range sol.Base.Colors() {
- if brightOnDark {
- if light(v) > light(blendFgColor) {
- blendFgColor = v
- }
- if light(v) < light(blendBgColor) {
- blendBgColor = v
- }
- } else {
- if light(v) < light(blendFgColor) {
- blendFgColor = v
- }
- if light(v) > light(blendBgColor) {
- blendBgColor = v
- }
- }
- }
+ blendBgColor := colorlab.DefaultBlendColorBgFinder(sol)
+ blendFgColor := colorlab.DefaultBlendColorFgFinder(sol)
bg := v.BlendLab(blendBgColor, g.BlendBackgroundAmout)
fg := v.BlendLab(blendFgColor, g.BlendForegroundAmout)
diff --git a/colorlab/pkg/colorlab/accents.go b/colorlab/pkg/colorlab/accents.go
@@ -0,0 +1,124 @@
+package colorlab
+
+import "github.com/lucasb-eyer/go-colorful"
+
+func NewAccents(cc [8]colorful.Color) Accents {
+ return Accents{
+ Yellow: HexColor(cc[0].Clamped().Hex()),
+ Orange: HexColor(cc[1].Clamped().Hex()),
+ Red: HexColor(cc[2].Clamped().Hex()),
+ Magenta: HexColor(cc[3].Clamped().Hex()),
+ Violet: HexColor(cc[4].Clamped().Hex()),
+ Blue: HexColor(cc[5].Clamped().Hex()),
+ Cyan: HexColor(cc[6].Clamped().Hex()),
+ Green: HexColor(cc[7].Clamped().Hex()),
+ }
+}
+func (s Accents) Clone() Accents {
+ return Accents{
+ Yellow: s.Yellow,
+ Orange: s.Orange,
+ Red: s.Red,
+ Magenta: s.Magenta,
+ Violet: s.Violet,
+ Blue: s.Blue,
+ Cyan: s.Cyan,
+ Green: s.Green,
+ }
+}
+
+func (s Accents) Colors() AccentColors {
+ a := s.colorArray()
+ return [8]colorful.Color{
+ a[0].Color(),
+ a[1].Color(),
+ a[2].Color(),
+ a[3].Color(),
+ a[4].Color(),
+ a[5].Color(),
+ a[6].Color(),
+ a[7].Color(),
+ }
+}
+func (a Accents) ChangeLightness(amount float64) Accents {
+ cc := a.Colors()
+ lightness := func(c colorful.Color, v float64) colorful.Color {
+ l, a, b := c.Lab()
+ l = l + v
+ return colorful.Lab(l, a, b)
+ }
+ cc[0] = lightness(cc[0], amount)
+ cc[1] = lightness(cc[1], amount)
+ cc[2] = lightness(cc[2], amount)
+ cc[3] = lightness(cc[3], amount)
+ cc[4] = lightness(cc[4], amount)
+ cc[5] = lightness(cc[5], amount)
+ cc[6] = lightness(cc[6], amount)
+ cc[7] = lightness(cc[7], amount)
+ return NewAccents(cc)
+}
+func (a Accents) ChangeSaturation(amount float64) Accents {
+ cc := a.Colors()
+ saturation := func(c colorful.Color, v float64) colorful.Color {
+ h, s, l := c.Hsl()
+ // s = math.Min(math.Max(s+v, 0), 1)
+ s = s + v
+ return colorful.Hsl(h, s, l)
+ }
+ cc[0] = saturation(cc[0], amount)
+ cc[1] = saturation(cc[1], amount)
+ cc[2] = saturation(cc[2], amount)
+ cc[3] = saturation(cc[3], amount)
+ cc[4] = saturation(cc[4], amount)
+ cc[5] = saturation(cc[5], amount)
+ cc[6] = saturation(cc[6], amount)
+ cc[7] = saturation(cc[7], amount)
+ return NewAccents(cc)
+}
+
+func (a Accents) Blend(hc HexColor, amount float64) Accents {
+ c := hc.Color()
+ cc := a.Colors()
+ cc[0] = cc[0].BlendLab(c, amount)
+ cc[1] = cc[1].BlendLab(c, amount)
+ cc[2] = cc[2].BlendLab(c, amount)
+ cc[3] = cc[3].BlendLab(c, amount)
+ cc[4] = cc[4].BlendLab(c, amount)
+ cc[5] = cc[5].BlendLab(c, amount)
+ cc[6] = cc[6].BlendLab(c, amount)
+ cc[7] = cc[7].BlendLab(c, amount)
+ return NewAccents(cc)
+}
+
+func (ac Accents) NamedColors() NamedColors {
+ nc := make(NamedColors, 8)
+ arr := ac.colorArray()
+ for idx, hex := range arr {
+ nc[accentNames[idx]] = hex
+ }
+ return nc
+}
+
+func (s Accents) colorArray() [8]HexColor {
+ return [8]HexColor{
+ s.Yellow,
+ s.Orange,
+ s.Red,
+ s.Magenta,
+ s.Violet,
+ s.Blue,
+ s.Cyan,
+ s.Green,
+ }
+}
+
+var accentNames = [8]string{
+ 0: "yellow",
+ 1: "orange",
+ 2: "red",
+ 3: "magenta",
+ 4: "violet",
+ 5: "blue",
+ 6: "cyan",
+ 7: "green",
+}
diff --git a/colorlab/pkg/colorlab/base.go b/colorlab/pkg/colorlab/base.go
@@ -0,0 +1,137 @@
+package colorlab
+
+import (
+ "log"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+type Base struct {
+ Base03 HexColor
+ Base02 HexColor
+ Base01 HexColor
+ Base00 HexColor
+ Base0 HexColor
+ Base1 HexColor
+ Base2 HexColor
+ Base3 HexColor
+}
+
+type BaseColors [8]colorful.Color
+
+func NewBase(bc [8]colorful.Color) Base {
+ return Base{
+ Base03: HexColor(bc[0].Clamped().Hex()),
+ Base02: HexColor(bc[1].Clamped().Hex()),
+ Base01: HexColor(bc[2].Clamped().Hex()),
+ Base00: HexColor(bc[3].Clamped().Hex()),
+ Base0: HexColor(bc[4].Clamped().Hex()),
+ Base1: HexColor(bc[5].Clamped().Hex()),
+ Base2: HexColor(bc[6].Clamped().Hex()),
+ Base3: HexColor(bc[7].Clamped().Hex()),
+ }
+}
+func (s Base) Clone() Base {
+ return Base{
+ Base03: s.Base03,
+ Base02: s.Base02,
+ Base01: s.Base01,
+ Base00: s.Base00,
+ Base0: s.Base0,
+ Base1: s.Base1,
+ Base2: s.Base2,
+ Base3: s.Base3,
+ }
+}
+func (s Base) NamedColors() NamedColors {
+ nc := make(NamedColors, 8)
+ arr := s.colorArray()
+ for idx, hex := range arr {
+ nc[baseNames[idx]] = hex
+ }
+ return nc
+}
+
+func (s Base) Colors() BaseColors {
+ a := s.colorArray()
+ return [8]colorful.Color{
+ a[0].Color(),
+ a[1].Color(),
+ a[2].Color(),
+ a[3].Color(),
+ a[4].Color(),
+ a[5].Color(),
+ a[6].Color(),
+ a[7].Color(),
+ }
+}
+
+func (s Base) colorArray() [8]HexColor {
+ return [8]HexColor{
+ s.Base03,
+ s.Base02,
+ s.Base01,
+ s.Base00,
+ s.Base0,
+ s.Base1,
+ s.Base2,
+ s.Base3,
+ }
+}
+
+// Returns true if the LAB lightness of base0 is larger than base03.
+func (b Base) IsDarkOnBright() bool {
+ lightness := func(c colorful.Color) float64 {
+ l, _, _ := c.Lab()
+ return l
+ }
+ bg := b.Base03
+ fg := b.Base0
+ bgl := lightness(bg.Color())
+ fgl := lightness(fg.Color())
+ if fgl == bgl {
+ log.Fatalf("bg (%v) and fg (%v) are not supposed to have equal lightness: %v %v", bg, fg, bgl, fgl)
+ }
+ return fgl > bgl
+}
+
+var baseNames = [8]string{
+ 0: "base03",
+ 1: "base02",
+ 2: "base01",
+ 3: "base00",
+ 4: "base0",
+ 5: "base1",
+ 6: "base2",
+ 7: "base3",
+}
+
+func (s Base) Inverse() Base {
+ return Base{
+ Base03: s.Base3,
+ Base02: s.Base2,
+ Base01: s.Base1,
+ Base00: s.Base0,
+ Base0: s.Base00,
+ Base1: s.Base01,
+ Base2: s.Base02,
+ Base3: s.Base03,
+ }
+}
+func (b Base) ChangeLightness(amountFgs, amountBgs float64) Base {
+ cc := b.Colors()
+ lightness := func(c colorful.Color, v float64) colorful.Color {
+ l, a, b := c.Lab()
+ l = l + v
+ return colorful.Lab(l, a, b)
+ }
+ cc[0] = lightness(cc[0], amountBgs)
+ cc[1] = lightness(cc[1], amountBgs)
+ cc[2] = lightness(cc[2], amountFgs)
+ cc[3] = lightness(cc[3], amountBgs)
+ cc[4] = lightness(cc[4], amountFgs)
+ cc[5] = lightness(cc[5], amountFgs)
+ cc[6] = lightness(cc[6], amountFgs)
+ cc[7] = lightness(cc[7], amountFgs)
+ return NewBase(cc)
+}
diff --git a/colorlab/pkg/colorlab/colorlist.go b/colorlab/pkg/colorlab/colorlist.go
@@ -0,0 +1,36 @@
+package colorlab
+
+import (
+ "sort"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+type ColorList []colorful.Color
+
+// returns the ColorList ordered by Lightness, darkest first
+func (c ColorList) ByLightness() ColorList {
+ res := c
+ sort.Sort(ByLightness(res))
+ return res
+}
+
+// returns the ColorList ordered by Lightness, lightest first
+func (c ColorList) ByLightnessDesc() ColorList {
+ res := c
+ sort.Sort(sort.Reverse(ByLightness(res)))
+ return res
+}
+
+// ByLightness sorts a list of colors by LAB L(ightness) value
+type ByLightness ColorList
+
+func (a ByLightness) Len() int { return len(a) }
+func (a ByLightness) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a ByLightness) Less(i, j int) bool {
+ lightness := func(c colorful.Color) float64 {
+ l, _, _ := c.Lab()
+ return l
+ }
+ return lightness(a[i]) < lightness(a[j])
+}
diff --git a/colorlab/pkg/colorlab/colortransformer.go b/colorlab/pkg/colorlab/colortransformer.go
@@ -0,0 +1,5 @@
+package colorlab
+
+import "github.com/lucasb-eyer/go-colorful"
+
+type ColorTransformer func(colorful.Color) colorful.Color
diff --git a/colorlab/pkg/colorlab/colrofinder.go b/colorlab/pkg/colorlab/colrofinder.go
@@ -0,0 +1,22 @@
+package colorlab
+
+import "github.com/lucasb-eyer/go-colorful"
+
+// Find a specific color in a Solarized based on some preconditon
+type ColorFinder func(Solarized) colorful.Color
+
+// DefaultBlendColorFgFinder finds the darkest base tone for light on dark or the lightest color for dark on light.
+func DefaultBlendColorFgFinder(sol Solarized) colorful.Color {
+ if sol.IsDarkOnBright() {
+ return sol.Base.NamedColors().ColorList().ByLightnessDesc()[0]
+ }
+ return sol.Base.NamedColors().ColorList().ByLightness()[0]
+}
+
+// DefaultBlendColorFgFinder finds the lightest base tone for light on dark or the darkest color for dark on light.
+func DefaultBlendColorBgFinder(sol Solarized) colorful.Color {
+ if sol.IsDarkOnBright() {
+ return sol.Base.NamedColors().ColorList().ByLightness()[0]
+ }
+ return sol.Base.NamedColors().ColorList().ByLightnessDesc()[0]
+}
diff --git a/colorlab/pkg/colorlab/hexcolor.go b/colorlab/pkg/colorlab/hexcolor.go
@@ -17,3 +17,7 @@ func (h HexColor) Blend(hc HexColor, t float64) HexColor {
c2 := hc.Color()
return HexColor(c1.BlendLab(c2, t).Clamped().Hex())
}
+
+func NewHexColor(c colorful.Color) HexColor {
+ return HexColor(c.Clamped().Hex())
+}
diff --git a/colorlab/pkg/colorlab/namedcolors.go b/colorlab/pkg/colorlab/namedcolors.go
@@ -85,6 +85,15 @@ func (n NamedColors) PrintAlist(w io.Writer, indent int) (int, error) {
return nt, nil
}
+func (n NamedColors) ColorList() ColorList {
+ var res ColorList
+ for _, v := range n {
+ res = append(res, v.Color())
+
+ }
+ return res
+}
+
// Orderedkeys returns the keys in a order that is like how solarized names should be ordered.
//
// primary orer is:
diff --git a/colorlab/pkg/colorlab/solarized.go b/colorlab/pkg/colorlab/solarized.go
@@ -9,19 +9,6 @@ type Solarized struct {
Accents
}
-type Base struct {
- Base03 HexColor
- Base02 HexColor
- Base01 HexColor
- Base00 HexColor
- Base0 HexColor
- Base1 HexColor
- Base2 HexColor
- Base3 HexColor
-}
-
-type BaseColors [8]colorful.Color
-
// Accents .
type Accents struct {
Yellow HexColor
@@ -52,226 +39,4 @@ func (s Solarized) Inverse() Solarized {
func (s Solarized) NamedColors() NamedColors {
return Merge(s.Base.NamedColors(), s.Accents.NamedColors())
-
-}
-
-func NewBase(bc [8]colorful.Color) Base {
- return Base{
- Base03: HexColor(bc[0].Clamped().Hex()),
- Base02: HexColor(bc[1].Clamped().Hex()),
- Base01: HexColor(bc[2].Clamped().Hex()),
- Base00: HexColor(bc[3].Clamped().Hex()),
- Base0: HexColor(bc[4].Clamped().Hex()),
- Base1: HexColor(bc[5].Clamped().Hex()),
- Base2: HexColor(bc[6].Clamped().Hex()),
- Base3: HexColor(bc[7].Clamped().Hex()),
- }
-}
-func (s Base) Clone() Base {
- return Base{
- Base03: s.Base03,
- Base02: s.Base02,
- Base01: s.Base01,
- Base00: s.Base00,
- Base0: s.Base0,
- Base1: s.Base1,
- Base2: s.Base2,
- Base3: s.Base3,
- }
-}
-func (s Base) NamedColors() NamedColors {
- nc := make(NamedColors, 8)
- arr := s.colorArray()
- for idx, hex := range arr {
- nc[baseNames[idx]] = hex
- }
- return nc
-}
-
-func (s Base) Colors() BaseColors {
- a := s.colorArray()
- return [8]colorful.Color{
- a[0].Color(),
- a[1].Color(),
- a[2].Color(),
- a[3].Color(),
- a[4].Color(),
- a[5].Color(),
- a[6].Color(),
- a[7].Color(),
- }
-}
-func (s Base) colorArray() [8]HexColor {
- return [8]HexColor{
- s.Base03,
- s.Base02,
- s.Base01,
- s.Base00,
- s.Base0,
- s.Base1,
- s.Base2,
- s.Base3,
- }
-}
-
-var baseNames = [8]string{
- 0: "base03",
- 1: "base02",
- 2: "base01",
- 3: "base00",
- 4: "base0",
- 5: "base1",
- 6: "base2",
- 7: "base3",
-}
-
-func (s Base) Inverse() Base {
- return Base{
- Base03: s.Base3,
- Base02: s.Base2,
- Base01: s.Base1,
- Base00: s.Base0,
- Base0: s.Base00,
- Base1: s.Base01,
- Base2: s.Base02,
- Base3: s.Base03,
- }
-}
-func (b Base) ChangeLightness(amountFgs, amountBgs float64) Base {
- cc := b.Colors()
- lightness := func(c colorful.Color, v float64) colorful.Color {
- l, a, b := c.Lab()
- l = l + v
- return colorful.Lab(l, a, b)
- }
- cc[0] = lightness(cc[0], amountBgs)
- cc[1] = lightness(cc[1], amountBgs)
- cc[2] = lightness(cc[2], amountFgs)
- cc[3] = lightness(cc[3], amountBgs)
- cc[4] = lightness(cc[4], amountFgs)
- cc[5] = lightness(cc[5], amountFgs)
- cc[6] = lightness(cc[6], amountFgs)
- cc[7] = lightness(cc[7], amountFgs)
- return NewBase(cc)
-}
-
-func NewAccents(cc [8]colorful.Color) Accents {
- return Accents{
- Yellow: HexColor(cc[0].Clamped().Hex()),
- Orange: HexColor(cc[1].Clamped().Hex()),
- Red: HexColor(cc[2].Clamped().Hex()),
- Magenta: HexColor(cc[3].Clamped().Hex()),
- Violet: HexColor(cc[4].Clamped().Hex()),
- Blue: HexColor(cc[5].Clamped().Hex()),
- Cyan: HexColor(cc[6].Clamped().Hex()),
- Green: HexColor(cc[7].Clamped().Hex()),
- }
-}
-func (s Accents) Clone() Accents {
- return Accents{
- Yellow: s.Yellow,
- Orange: s.Orange,
- Red: s.Red,
- Magenta: s.Magenta,
- Violet: s.Violet,
- Blue: s.Blue,
- Cyan: s.Cyan,
- Green: s.Green,
- }
-}
-
-func (s Accents) Colors() AccentColors {
- a := s.colorArray()
- return [8]colorful.Color{
- a[0].Color(),
- a[1].Color(),
- a[2].Color(),
- a[3].Color(),
- a[4].Color(),
- a[5].Color(),
- a[6].Color(),
- a[7].Color(),
- }
-}
-func (a Accents) ChangeLightness(amount float64) Accents {
- cc := a.Colors()
- lightness := func(c colorful.Color, v float64) colorful.Color {
- l, a, b := c.Lab()
- l = l + v
- return colorful.Lab(l, a, b)
- }
- cc[0] = lightness(cc[0], amount)
- cc[1] = lightness(cc[1], amount)
- cc[2] = lightness(cc[2], amount)
- cc[3] = lightness(cc[3], amount)
- cc[4] = lightness(cc[4], amount)
- cc[5] = lightness(cc[5], amount)
- cc[6] = lightness(cc[6], amount)
- cc[7] = lightness(cc[7], amount)
- return NewAccents(cc)
-}
-func (a Accents) ChangeSaturation(amount float64) Accents {
- cc := a.Colors()
- saturation := func(c colorful.Color, v float64) colorful.Color {
- h, s, l := c.Hsl()
- // s = math.Min(math.Max(s+v, 0), 1)
- s = s + v
- return colorful.Hsl(h, s, l)
- }
- cc[0] = saturation(cc[0], amount)
- cc[1] = saturation(cc[1], amount)
- cc[2] = saturation(cc[2], amount)
- cc[3] = saturation(cc[3], amount)
- cc[4] = saturation(cc[4], amount)
- cc[5] = saturation(cc[5], amount)
- cc[6] = saturation(cc[6], amount)
- cc[7] = saturation(cc[7], amount)
- return NewAccents(cc)
-}
-
-func (a Accents) Blend(hc HexColor, amount float64) Accents {
- c := hc.Color()
- cc := a.Colors()
- cc[0] = cc[0].BlendLab(c, amount)
- cc[1] = cc[1].BlendLab(c, amount)
- cc[2] = cc[2].BlendLab(c, amount)
- cc[3] = cc[3].BlendLab(c, amount)
- cc[4] = cc[4].BlendLab(c, amount)
- cc[5] = cc[5].BlendLab(c, amount)
- cc[6] = cc[6].BlendLab(c, amount)
- cc[7] = cc[7].BlendLab(c, amount)
- return NewAccents(cc)
-}
-
-func (ac Accents) NamedColors() NamedColors {
- nc := make(NamedColors, 8)
- arr := ac.colorArray()
- for idx, hex := range arr {
- nc[accentNames[idx]] = hex
- }
- return nc
-}
-
-func (s Accents) colorArray() [8]HexColor {
- return [8]HexColor{
- s.Yellow,
- s.Orange,
- s.Red,
- s.Magenta,
- s.Violet,
- s.Blue,
- s.Cyan,
- s.Green,
- }
-}
-
-var accentNames = [8]string{
- 0: "yellow",
- 1: "orange",
- 2: "red",
- 3: "magenta",
- 4: "violet",
- 5: "blue",
- 6: "cyan",
- 7: "green",
}