diff --git a/README.md b/README.md index e640501..55ba39c 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,17 @@ Fun & easy way to create _color gradient_ / _color scales_ in __Go__ (__Golang__ * [Usages](#usages) - [Basic](#basic) - [Custom Colors](#custom-colors) + - [Hex Colors](#using-hex-colors) + - [Custom Domain](#custom-domain) + - [Blending Mode](#blending-mode) + - [Invalid RGB](#beware-of-invalid-rgb-color) + - [Hard-Edged Gradient](#hard-edged-gradient) * [Preset Gradients](#preset-gradients) * [Color Scheme](#color-scheme) -* [Random Colors](#random-colors) -* [Playground](#go-playground) +* [Gallery](#gallery) +* [Playground](#playground) * [Dependencies](#dependencies) +* [Inspirations](#inspirations) ### Usages @@ -119,6 +125,20 @@ Without `Clamped()` With `Clamped()` ![valid rgb](img/clamped.png) +#### Hard-Edged Gradient + +```go +grad1, err := colorgrad.NewGradient(). + HexColors("#18dbf4", "#f6ff56"). + Build() +``` +![img](img/normal-gradient.png) + +```go +grad2 := colorgrad.SharpGradient(grad1, 7) +``` +![img](img/classes-gradient.png) + ### Preset Gradients ```go @@ -218,11 +238,15 @@ grad, err := colorgrad.NewGradient(). `colorgrad.Scheme.Set3` ![img](img/scheme-set3.png) -### Random Colors +### Gallery + +Colored noise using hard-edged gradient. +![noise](img/noise-2.png) +Random colors using `colorgrad.Cool()`. ![random-color](img/random-cool.png) -### Go Playground +### Playground * [Basic](https://play.golang.org/p/rE8OI50PsQA) * [Random colors](https://play.golang.org/p/d67x9di4sAF) diff --git a/gradset.go b/gradset.go index f0938ea..907b84e 100644 --- a/gradset.go +++ b/gradset.go @@ -1,39 +1,73 @@ package colorgrad -func Viridis() Gradient { - colors := []string{"#440154", "#482777", "#3f4a8a", "#31678e", "#26838f", "#1f9d8a", "#6cce5a", "#b6de2b", "#fee825"} +// Diverging + +func BrBG() Gradient { + colors := []string{"#543005", "#8c510a", "#bf812d", "#dfc27d", "#f6e8c3", "#f5f5f5", "#c7eae5", "#80cdc1", "#35978f", "#01665e", "#003c30"} grad, _ := NewGradient(). HexColors(colors...). Build() return grad } -func Spectral() Gradient { - colors := []string{"#9e0142", "#d53e4f", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#e6f598", "#abdda4", "#66c2a5", "#3288bd", "#5e4fa2"} +func PRGn() Gradient { + colors := []string{"#40004b", "#762a83", "#9970ab", "#c2a5cf", "#e7d4e8", "#f7f7f7", "#d9f0d3", "#a6dba0", "#5aae61", "#1b7837", "#00441b"} grad, _ := NewGradient(). HexColors(colors...). Build() return grad } -func Plasma() Gradient { - colors := []string{"#0d0887", "#42039d", "#6a00a8", "#900da3", "#b12a90", "#cb4678", "#e16462", "#f1834b", "#fca636", "#fccd25", "#f0f921"} +func PiYG() Gradient { + colors := []string{"#8e0152", "#c51b7d", "#de77ae", "#f1b6da", "#fde0ef", "#f7f7f7", "#e6f5d0", "#b8e186", "#7fbc41", "#4d9221", "#276419"} grad, _ := NewGradient(). HexColors(colors...). Build() return grad } -func Magma() Gradient { - colors := []string{"#000004", "#140e37", "#3b0f70", "#641a80", "#8c2981", "#b63679", "#de4968", "#f66f5c", "#fe9f6d", "#fece91", "#fcfdbf"} +func PuOr() Gradient { + colors := []string{"#7f3b08", "#b35806", "#e08214", "#fdb863", "#fee0b6", "#f7f7f7", "#d8daeb", "#b2abd2", "#8073ac", "#542788", "#2d004b"} grad, _ := NewGradient(). HexColors(colors...). Build() return grad } -func Inferno() Gradient { - colors := []string{"#000004", "#170b3a", "#420a68", "#6b176e", "#932667", "#bb3654", "#dd513a", "#f3771a", "#fca50a", "#f6d644", "#fcffa4"} +func RdBu() Gradient { + colors := []string{"#67001f", "#b2182b", "#d6604d", "#f4a582", "#fddbc7", "#f7f7f7", "#d1e5f0", "#92c5de", "#4393c3", "#2166ac", "#053061"} + grad, _ := NewGradient(). + HexColors(colors...). + Build() + return grad +} + +func RdGy() Gradient { + colors := []string{"#67001f", "#b2182b", "#d6604d", "#f4a582", "#fddbc7", "#ffffff", "#e0e0e0", "#bababa", "#878787", "#4d4d4d", "#1a1a1a"} + grad, _ := NewGradient(). + HexColors(colors...). + Build() + return grad +} + +func RdYlBu() Gradient { + colors := []string{"#a50026", "#d73027", "#f46d43", "#fdae61", "#fee090", "#ffffbf", "#e0f3f8", "#abd9e9", "#74add1", "#4575b4", "#313695"} + grad, _ := NewGradient(). + HexColors(colors...). + Build() + return grad +} + +func RdYlGn() Gradient { + colors := []string{"#a50026", "#d73027", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#d9ef8b", "#a6d96a", "#66bd63", "#1a9850", "#006837"} + grad, _ := NewGradient(). + HexColors(colors...). + Build() + return grad +} + +func Spectral() Gradient { + colors := []string{"#9e0142", "#d53e4f", "#f46d43", "#fdae61", "#fee08b", "#ffffbf", "#e6f598", "#abdda4", "#66c2a5", "#3288bd", "#5e4fa2"} grad, _ := NewGradient(). HexColors(colors...). Build() @@ -88,3 +122,37 @@ func Reds() Gradient { Build() return grad } + +// Sequential (Multi-Hue) + +func Viridis() Gradient { + colors := []string{"#440154", "#482777", "#3f4a8a", "#31678e", "#26838f", "#1f9d8a", "#6cce5a", "#b6de2b", "#fee825"} + grad, _ := NewGradient(). + HexColors(colors...). + Build() + return grad +} + +func Inferno() Gradient { + colors := []string{"#000004", "#170b3a", "#420a68", "#6b176e", "#932667", "#bb3654", "#dd513a", "#f3771a", "#fca50a", "#f6d644", "#fcffa4"} + grad, _ := NewGradient(). + HexColors(colors...). + Build() + return grad +} + +func Magma() Gradient { + colors := []string{"#000004", "#140e37", "#3b0f70", "#641a80", "#8c2981", "#b63679", "#de4968", "#f66f5c", "#fe9f6d", "#fece91", "#fcfdbf"} + grad, _ := NewGradient(). + HexColors(colors...). + Build() + return grad +} + +func Plasma() Gradient { + colors := []string{"#0d0887", "#42039d", "#6a00a8", "#900da3", "#b12a90", "#cb4678", "#e16462", "#f1834b", "#fca636", "#fccd25", "#f0f921"} + grad, _ := NewGradient(). + HexColors(colors...). + Build() + return grad +} diff --git a/gradset_test.go b/gradset_test.go index d0779ef..9589c49 100644 --- a/gradset_test.go +++ b/gradset_test.go @@ -5,11 +5,15 @@ import ( ) func TestPreset(t *testing.T) { - testGrad(t, Inferno(), "#000004", "#fcffa4") - testGrad(t, Magma(), "#000004", "#fcfdbf") - testGrad(t, Plasma(), "#0d0887", "#f0f921") + testGrad(t, BrBG(), "#543005", "#003c30") + testGrad(t, PRGn(), "#40004b", "#00441b") + testGrad(t, PiYG(), "#8e0152", "#276419") + testGrad(t, PuOr(), "#7f3b08", "#2d004b") + testGrad(t, RdBu(), "#67001f", "#053061") + testGrad(t, RdGy(), "#67001f", "#1a1a1a") + testGrad(t, RdYlBu(), "#a50026", "#313695") + testGrad(t, RdYlGn(), "#a50026", "#006837") testGrad(t, Spectral(), "#9e0142", "#5e4fa2") - testGrad(t, Viridis(), "#440154", "#fee825") testGrad(t, Blues(), "#f7fbff", "#08306b") testGrad(t, Greens(), "#f7fcf5", "#00441b") @@ -17,6 +21,11 @@ func TestPreset(t *testing.T) { testGrad(t, Oranges(), "#fff5eb", "#7f2704") testGrad(t, Purples(), "#fcfbfd", "#3f007d") testGrad(t, Reds(), "#fff5f0", "#67000d") + + testGrad(t, Viridis(), "#440154", "#fee825") + testGrad(t, Inferno(), "#000004", "#fcffa4") + testGrad(t, Magma(), "#000004", "#fcfdbf") + testGrad(t, Plasma(), "#0d0887", "#f0f921") } func testGrad(t *testing.T, grad Gradient, start, end string) { diff --git a/gradx.go b/gradx.go index bbb9fce..68b428a 100644 --- a/gradx.go +++ b/gradx.go @@ -7,42 +7,42 @@ import ( "github.com/lucasb-eyer/go-colorful" ) -type classesGrad struct { +type sharpGradient struct { colors []colorful.Color pos []float64 n int } -func Classes(grad Gradient, count uint) Gradient { - return classesGrad{ +func SharpGradient(grad Gradient, count uint) Gradient { + return sharpGradient{ colors: grad.Colors(count), pos: linspace(0, 1, count+1), n: int(count), } } -func (cg classesGrad) At(t float64) colorful.Color { +func (sg sharpGradient) At(t float64) colorful.Color { if math.IsNaN(t) || t < 0 { - return cg.colors[0] + return sg.colors[0] } if t > 1 { - return cg.colors[cg.n-1] + return sg.colors[sg.n-1] } - for i := 0; i < cg.n; i++ { - if (cg.pos[i] <= t) && (t <= cg.pos[i+1]) { - return cg.colors[i] + for i := 0; i < sg.n; i++ { + if (sg.pos[i] <= t) && (t <= sg.pos[i+1]) { + return sg.colors[i] } } - return cg.colors[cg.n-1] + return sg.colors[sg.n-1] } -func (cg classesGrad) Colors(count uint) []colorful.Color { +func (sg sharpGradient) Colors(count uint) []colorful.Color { l := float64(count - 1) colors := make([]colorful.Color, count) for i := range colors { - colors[i] = cg.At(float64(i) / l) + colors[i] = sg.At(float64(i) / l) } return colors } diff --git a/gradx_test.go b/gradx_test.go index ffe22ca..5fe0d5a 100644 --- a/gradx_test.go +++ b/gradx_test.go @@ -8,7 +8,7 @@ import ( func TestX(t *testing.T) { grad, _ := NewGradient().Build() - grad2 := Classes(grad, 7) + grad2 := SharpGradient(grad, 7) testStr(t, grad2.At(0).Hex(), "#000000") testStr(t, grad2.At(1).Hex(), "#ffffff") diff --git a/img/classes-gradient.png b/img/classes-gradient.png new file mode 100644 index 0000000..0e4f664 Binary files /dev/null and b/img/classes-gradient.png differ diff --git a/img/noise-2.png b/img/noise-2.png new file mode 100644 index 0000000..8776fd2 Binary files /dev/null and b/img/noise-2.png differ diff --git a/img/normal-gradient.png b/img/normal-gradient.png new file mode 100644 index 0000000..fc45d1d Binary files /dev/null and b/img/normal-gradient.png differ