Skip to content

Commit 23cf7dd

Browse files
committed
color gradient function and tests
1 parent c647f87 commit 23cf7dd

File tree

4 files changed

+106
-23
lines changed

4 files changed

+106
-23
lines changed

colors.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"github.com/lucasb-eyer/go-colorful"
55
"golang.org/x/image/colornames"
66
"image/color"
7+
"math"
78
"regexp"
89
"strings"
910
)
@@ -22,6 +23,7 @@ type ColorConfig struct {
2223
Outline color.Color
2324
Text color.Color
2425
Fill color.Color
26+
Gradient SimpleGradient
2527
}
2628

2729
func (cc *ColorConfig) Set(hexString string, colorType ColorType, defaultString string) {
@@ -85,3 +87,43 @@ func (sg *SimpleGradient) Color(percentage float64) color.Color {
8587
c2, _ := colorful.MakeColor(sg.endColor)
8688
return c1.BlendHcl(c2, val)
8789
}
90+
91+
type Gradient struct {
92+
stops []color.Color
93+
}
94+
95+
func (g *Gradient) AddStop(colorString string) {
96+
g.stops = append(g.stops, StringToColor(colorString))
97+
}
98+
99+
func (g *Gradient) NumStops() int {
100+
return len(g.stops)
101+
}
102+
103+
func NewGradientFromNamed(names []string) Gradient {
104+
var grad Gradient
105+
for _, i := range names {
106+
grad.AddStop(i)
107+
}
108+
return grad
109+
}
110+
111+
func (g *Gradient) Color(percentage float64) color.Color {
112+
val := Clamp(0, 1, percentage)
113+
n := g.NumStops()
114+
if n == 1 {
115+
return g.stops[0]
116+
}
117+
if val == 0 {
118+
return g.stops[0]
119+
}
120+
if val == 1 {
121+
return g.stops[n-1]
122+
}
123+
i := Map(0, 1, 0, float64(n)-1, percentage)
124+
lerp := i - math.Floor(i)
125+
index := int(math.Floor(i))
126+
c1, _ := colorful.MakeColor(g.stops[index])
127+
c2, _ := colorful.MakeColor(g.stops[index+1])
128+
return c1.BlendHcl(c2, lerp)
129+
}

controls.go

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const (
1818
SliderOutlineColor = "#ffdb00"
1919
SliderFillColor = "#ffdb00"
2020
SliderTextColor = "#ffffff"
21+
SliderGradientStart = "cyan"
22+
SliderGradientEnd = "magenta"
2123
ToggleHeight = 15.0
2224
ToggleHPadding = 12.0
2325
ToggleVPadding = 7.0
@@ -29,20 +31,23 @@ const (
2931
)
3032

3133
type Slider struct {
32-
Name string `json:"Name"`
33-
Pos Point `json:"-"`
34-
Width float64 `json:"Width"`
35-
Height float64 `json:"Height"`
36-
MinVal float64 `json:"MinVal"`
37-
MaxVal float64 `json:"MaxVal"`
38-
Val float64 `json:"Val"`
39-
Incr float64 `json:"Incr"`
40-
OutlineColor string `json:"OutlineColor"`
41-
BackgroundColor string `json:"BackgroundColor"`
42-
FillColor string `json:"FillColor"`
43-
TextColor string `json:"TextColor"`
44-
colors ColorConfig
45-
DidJustChange bool `json:"-"`
34+
Name string `json:"Name"`
35+
Pos Point `json:"-"`
36+
Width float64 `json:"Width"`
37+
Height float64 `json:"Height"`
38+
MinVal float64 `json:"MinVal"`
39+
MaxVal float64 `json:"MaxVal"`
40+
Val float64 `json:"Val"`
41+
Incr float64 `json:"Incr"`
42+
OutlineColor string `json:"OutlineColor"`
43+
BackgroundColor string `json:"BackgroundColor"`
44+
FillColor string `json:"FillColor"`
45+
UseGradientFill bool `json:"UseGradientFill"`
46+
GradientStartColor string `json:"GradientStartColor"`
47+
GradientEndColor string `json:"GradientEndColor"`
48+
TextColor string `json:"TextColor"`
49+
colors ColorConfig
50+
DidJustChange bool `json:"-"`
4651
}
4752

4853
type Toggle struct {
@@ -126,7 +131,11 @@ func (s *Slider) Draw(ctx *gg.Context) {
126131
ctx.SetColor(s.colors.Background)
127132
ctx.DrawRectangle(s.Pos.X, s.Pos.Y, s.Width, SliderHeight)
128133
ctx.Fill()
129-
ctx.SetColor(s.colors.Fill)
134+
fillColor := s.colors.Fill
135+
if s.UseGradientFill {
136+
fillColor = s.colors.Gradient.Color(s.GetPercentage())
137+
}
138+
ctx.SetColor(fillColor)
130139
ctx.DrawRectangle(s.Pos.X, s.Pos.Y, s.Width*s.GetPercentage(), SliderHeight)
131140
ctx.Fill()
132141
ctx.SetColor(s.colors.Outline)
@@ -253,6 +262,17 @@ func (s *Slider) parseColors() {
253262
s.colors.Set(s.OutlineColor, OutlineColorType, SliderOutlineColor)
254263
s.colors.Set(s.TextColor, TextColorType, SliderTextColor)
255264
s.colors.Set(s.FillColor, FillColorType, SliderFillColor)
265+
if s.UseGradientFill {
266+
c1 := SliderGradientStart
267+
c2 := SliderGradientEnd
268+
if s.GradientStartColor != "" {
269+
c1 = s.GradientStartColor
270+
}
271+
if s.GradientEndColor != "" {
272+
c2 = s.GradientEndColor
273+
}
274+
s.colors.Gradient = NewSimpleGradientFromNamed(c1, c2)
275+
}
256276
}
257277

258278
func (c *Toggle) parseColors() {

visual_tests/color_gradient/color_gradient.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ package main
22

33
import (
44
"flag"
5+
"image/color"
56
"log"
67

78
"github.com/aldernero/sketchy"
89
"github.com/fogleman/gg"
910
"github.com/hajimehoshi/ebiten/v2"
1011
)
1112

12-
var cg sketchy.SimpleGradient
13+
var cg1 sketchy.SimpleGradient
14+
var cg2 sketchy.Gradient
1315

1416
func update(s *sketchy.Sketch) {
1517
// Update logic goes here
@@ -24,15 +26,29 @@ func draw(s *sketchy.Sketch, c *gg.Context) {
2426
dx := 1.10 * (right - left) / float64(N)
2527
dy := 20.0
2628
c.SetLineCapButt()
27-
c.SetLineWidth(0)
29+
c.SetLineWidth(1)
2830
for _, i := range x {
2931
p := sketchy.Map(0.05*s.SketchWidth, 0.95*s.SketchWidth, 0, 1, i)
30-
c.SetColor(cg.Color(p))
32+
c.SetColor(cg1.Color(p))
3133
c.DrawRectangle(i, 20, dx, dy)
3234
c.Fill()
35+
c.SetColor(cg2.Color(p))
36+
c.DrawRectangle(i, 120, dx, dy)
37+
c.Fill()
3338
}
34-
c.SetColor(cg.Color(s.Slider("percentage")))
35-
c.DrawCircle(s.SketchWidth/2, s.SketchHeight/2, 100)
39+
p := s.Slider("percentage")
40+
xPos := sketchy.Map(0, 1, 0.05*s.SketchWidth, 0.95*s.SketchWidth, p)
41+
c.SetColor(color.White)
42+
c.DrawLine(xPos, 42, xPos, 58)
43+
c.Stroke()
44+
c.DrawRectangle(xPos-10, 60, 20, 20)
45+
c.SetColor(cg1.Color(p))
46+
c.Fill()
47+
c.SetColor(color.White)
48+
c.DrawLine(xPos, 142, xPos, 158)
49+
c.Stroke()
50+
c.DrawRectangle(xPos-10, 160, 20, 20)
51+
c.SetColor(cg2.Color(p))
3652
c.Fill()
3753
}
3854

@@ -52,7 +68,8 @@ func main() {
5268
s.Updater = update
5369
s.Drawer = draw
5470
s.Init()
55-
cg = sketchy.NewSimpleGradientFromNamed("cyan", "magenta")
71+
cg1 = sketchy.NewSimpleGradientFromNamed("cyan", "magenta")
72+
cg2 = sketchy.NewGradientFromNamed([]string{"blue", "green", "yellow", "red"})
5673
ebiten.SetWindowSize(int(s.ControlWidth+s.SketchWidth), int(s.SketchHeight))
5774
ebiten.SetWindowTitle("Sketchy - " + s.Title)
5875
ebiten.SetWindowResizable(false)

visual_tests/color_gradient/sketch.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
"MinVal": 0,
99
"MaxVal": 1,
1010
"Val": 0.5,
11-
"Incr": 0.01
11+
"Incr": 0.01,
12+
"UseGradientFill": true,
13+
"OutlineColor": "yellow"
1214
}
13-
]
15+
],
16+
"ControlOutlineColor": "darkcyan",
17+
"SketchOutlineColor": "darkmagenta"
1418
}

0 commit comments

Comments
 (0)