Gamut, a Go Package to Manage Color Palettes
I have talked about using an algorithm to generate color palettes in my previous blog post and as promised I set aside some of my time to work on gamut, a Go package to manage and generate color palettes & themes. The original scope of the package was to provide a more Go-idiomatic and convenient interface to the color generator I presented in the post. Working on it, it became painfully obvious that Go’s standard color package is fairly minimalistic by design. There’s the fabulous go-colorful which handles all the color space conversions and computations for you, but I still thought there’s a need for a bit more syntactic sugar when facing the every-day problems working with colors and palettes.
So here it is, a quick introduction to managing colors with gamut
.
Colors
gamut
operates on various color spaces internally, but all color values you
pass in as parameters and all return values will match Go’s color.Color
interface.
Let’s start with the basics. Just for convenience there’s a hex-value parser:
color = gamut.Hex("#333")
color = gamut.Hex("#ABCDEF")
Use the Lighter
and Darker
methods to lighten and respectively darken any
given color. The HCL color
space is used internally for computations here:
color = gamut.Lighter(color, 0.3)
color = gamut.Darker(color, 0.1)
Often you will need the complementary value of a color (the color on the opposite side of the color wheel):
color = gamut.Complementary(color)
You can also calculate the best contrast value for a given color. The following code returns the color with the highest contrast (and hence always either black or white):
color = gamut.Contrast(color)
Around the Color Wheel
To retrieve a color with the same lightness and saturation, but a different
angle on the color wheel, you can use the HueOffset
function:
color = gamut.HueOffset(color, 90)
gamut
helps you creating color schemes by providing convenient functions for a
color’s Triadic
, Quadratic
, Tetradic
, Analogous
and SplitComplementary
values. I can recommend w3schools' article on color schemes.
It’s a nice intro with live examples if you aren’t familiar with the color wheel yet.
The following examples use #2F1B82
as the base value for color
.
Triadic
schemes are made up of three hues equally spaced around the color wheel:
colors := gamut.Triadic(color)
Quadratic
schemes are made up of four hues equally spaced around the color wheel:
colors := gamut.Quadratic(color)
Tetradic
schemes are made up by two colors and their complementary values:
colors := gamut.Tetradic(color1, color2)
Analogous
schemes are created by using colors that are next to each other
on the color wheel:
colors := gamut.Analogous(color)
SplitComplementary
schemes are created by using colors next to the
complementary value of a given color:
colors := gamut.SplitComplementary(color)
Shades, Tints & Tones
Monochromatic
returns colors of the same hue, but with a different
saturation/lightness:
colors := gamut.Monochromatic(color, 8)
Shades
returns colors blended from the given color to black:
colors := gamut.Shades(color, 8)
Tints
returns colors blended from the given color to white:
colors := gamut.Tints(color, 8)
Tones
returns colors blended from the given color to gray:
colors := gamut.Tones(color, 8)
Blends
returns interpolated colors by blending two colors in the CIELab
color space:
colors := gamut.Blends(color1, color2, 8)
Palettes
Gamut comes with four curated color palettes: Wikipedia
, Crayola
, Resene
and Monokai
. The Wikipedia palette is an import of common colors from
Wikipedia’s List of Colors.
Similarly Crayola consists of colors resembling the palette of Crayola drawing
crayons, while Resene refers to the color palette of the paint manufacturer. New
curated palettes and importers are welcome. Send me a pull request on GitHub!
The function Colors
lets you retrieve all colors in a palette:
|
|
Your Own Palettes
|
|
Names
Each color in the curated palettes comes with an “official” name. You can filter palettes by colors with specific names. This code snippet will return a list of all “blue” colors in the Wikipedia palette:
colors := palette.Wikipedia.Filter("blue")
Calling a palette’s Name
function with a given color returns the name &
distance of the closest (perceptually) matching color in it:
name, distance := palette.Wikipedia.Name(color)
Mixing
You can mix two palettes. Colors with the same name and color value will be de-duplicated and only appear once in the resulting palette:
palette := palette.Crayola.MixedWith(palette.Monokai)
Perception
Sometimes you got a slice of colors, but you have a limited color palette to
work with. The Clamped
function returns a slice of the closest perceptually
matching colors in a palette, maintaining the same order as the original slice
you provided. Finally you can remix your favorite wallpapers in Crayola-style!
colors = palette.Crayola.Clamped(colors)
Generators
Working with curated color palettes is nice, but if you need to visualize a larger data set or just want to experiment with colors, gamut’s Generators are a lot of fun to play with:
colors, err := gamut.Generate(8, gamut.PastelGenerator{})
colors, err := gamut.Generate(8, gamut.WarmGenerator{})
You can even write your own generators if you implement the ColorGenerator
interface:
|
|
You can read up on the inner workings of the color generation algorithm in my previous blog post.
What’s Next
I’d like to add functions to sort color slices by certain criteria. gamut
provides basic support for color roles and theming, but it’s still pretty
barebone. Contributions are always welcome!