Kodachroma
Kodachroma is a color manipulation and palette generation library. It aims to be a maintained fork of the excellent Chroma. Many thanks to Jeremy Fairbank for developing Chroma.
From Chroma’s own README:
It is heavily inspired by and a very close Ruby port of the tinycolor.js library. Many thanks to Brian Grinstead for his hard work on that library.
Installation
Add this line to your application’s Gemfile:
gem 'kodachroma'
And then execute:
bundle
Or install it yourself as:
gem install kodachroma
Differences from Chroma
The string extension that defined String#paint
has been removed. If you would
like to replicate that behavior using Kodachroma, the following should do the
trick.
class String
# Creates {Kodachroma::Color} directly from a string representing a color.
#
# @example
# 'red'.paint
# '#f00'.paint
# '#ff0000'.paint
# 'rgb(255, 0, 0)'.paint
# 'hsl(0, 100%, 50%)'.paint
# 'hsv(0, 100%, 100%)'.paint
#
# @return [Kodachroma::Color]
def paint
Kodachroma.paint(self)
end
end
Creating Colors
Colors are created via the Kodachroma.paint
method. It expects any one of
many possible color formats as a string, including names, hexadecimal,
rgb, hsl, and hsv.
Kodachroma.paint 'red' # named colors
Kodachroma.paint '#00ff00' # 6 character hexadecimal
Kodachroma.paint '#00f' # 3 character hexadecimal
Kodachroma.paint 'rgb(255, 255, 0)' # rgb
Kodachroma.paint 'rgba(255, 255, 0, 0.5)' # rgba
Kodachroma.paint 'hsl(60, 100%, 50%)' # hsl with percentages
Kodachroma.paint 'hsl(60, 1, 0.5)' # hsl with decimals
Kodachroma.paint 'hsla(60, 100%, 50%, 0.5)' # hsla
Kodachroma.paint 'hsv(60, 100%, 50%)' # hsv with percentages
Kodachroma.paint 'hsv(60, 1, 0.5)' # hsv with decimals
Kodachroma.paint 'hsva(60, 100%, 50%, 0.75)' # hsva
Motivation
Kodachroma’s major strength is manipulating colors and generating color palettes, which allows you to easily generate dynamic colors, dynamic themes for a web application, and more.
Color manipulation
Lighten
Lighten the color by a given amount. Defaults to 10.
Kodachroma.paint('red').lighten #=> #ff3333
Kodachroma.paint('red').lighten(20) #=> #ff6666
Brighten
Brighten the color by a given amount. Defaults to 10.
Kodachroma.paint('red').brighten #=> #ff1a1a
Kodachroma.paint('red').brighten(20) #=> #ff3333
Darken
Darken the color by a given amount. Defaults to 10.
Kodachroma.paint('red').darken #=> #cc0000
Kodachroma.paint('red').darken(20) #=> #990000
Desaturate
Desaturate the color by a given amount. Defaults to 10.
Kodachroma.paint('red').desaturate #=> #f20d0d
Kodachroma.paint('red').desaturate(20) #=> #e61919
Saturate
Saturate the color by a given amount. Defaults to 10.
Kodachroma.paint('#123').saturate #=> #0e2236
Kodachroma.paint('#123').saturate(20) #=> #0a223a
Grayscale
Convert the color to grayscale.
Kodachroma.paint('green').grayscale #=> #404040
# greyscale is an alias
Kodachroma.paint('red').greyscale #=> #808080
Opacity
Set the opacity of the color to a given amount.
Kodachroma.paint('red').opacity(0.3) #=> #ff0000
Kodachroma.paint('red').opacity(0.3).to_rgb #=> 'rgba(255, 0, 0, 0.3)'
Spin
Spin a given amount in degrees around the hue wheel.
Kodachroma.paint('red').spin(30) #=> #ff8000
Kodachroma.paint('red').spin(60) #=> yellow
Kodachroma.paint('red').spin(90) #=> #80ff00
Generating palettes
Kodachroma’s most powerful feature is palette generation. You can use the default palettes available or even create your own custom palettes.
Palette methods are available via Color#palette
and by default output
an array of colors. If you want the underlying color strings, you can
pass in the desired format via the :as
option.
Available Formats
- name
- rgb
- hex
- hex6 (alias for hex)
- hex3
- hex8 (includes the alpha value in the highest order byte)
- hsl
- hsv
Complement
Generate a complement palette.
Kodachroma.paint('red').palette.complement #=> [red, cyan]
Kodachroma.paint('red').palette.complement(as: :name) #=> ['red', 'cyan']
Kodachroma.paint('red').palette.complement(as: :hex) #=> ['#ff0000', '#00ffff']
Triad
Generate a triad palette.
Kodachroma.paint('red').palette.triad #=> [red, lime, blue]
Kodachroma.paint('red').palette.triad(as: :name) #=> ['red', 'lime', 'blue']
Kodachroma.paint('red').palette.triad(as: :hex) #=> ['#ff0000', '#00ff00', '#0000ff']
Tetrad
Generate a tetrad palette.
Kodachroma.paint('red').palette.tetrad
#=> [red, #80ff00, cyan, #7f00ff]
Kodachroma.paint('red').palette.tetrad(as: :name)
#=> ['red', '#80ff00', 'cyan', '#7f00ff']
Kodachroma.paint('red').palette.tetrad(as: :hex)
#=> ['#ff0000', '#80ff00', '#00ffff', '#7f00ff']
Split complement
Generate a split complement palette.
Kodachroma.paint('red').palette.split_complement
#=> [red, #ccff00, #0066ff]
Kodachroma.paint('red').palette.split_complement(as: :name)
#=> ['red', '#ccff00', '#0066ff']
Kodachroma.paint('red').palette.split_complement(as: :hex)
#=> ['#ff0000', '#ccff00', '#0066ff']
Analogous
Generate an analogous palette. Pass in a :size
option to specify the
size of the palette (defaults to 6). Pass in a :slice_by
option to
specify the angle size to slice into the hue wheel (defaults to 30
degrees).
Kodachroma.paint('red').palette.analogous
#=> [red, #ff0066, #ff0033, red, #ff3300, #ff6600]
Kodachroma.paint('red').palette.analogous(as: :hex)
#=> ['#f00', '#f06', '#f03', '#f00', '#f30', '#f60']
Kodachroma.paint('red').palette.analogous(size: 3)
#=> [red, #ff001a, #ff1a00]
Kodachroma.paint('red').palette.analogous(size: 3, slice_by: 60)
#=> [red, #ff000d, #ff0d00]
Monochromatic
Generate a monochromatic palette. Pass in a :size
option to specify
the size of the palette (defaults to 6).
Kodachroma.paint('red').palette.monochromatic
#=> [red, #2a0000, #550000, maroon, #aa0000, #d40000]
Kodachroma.paint('red').palette.monochromatic(as: :hex)
#=> ['#ff0000', '#2a0000', '#550000', '#800000', '#aa0000', '#d40000']
Kodachroma.paint('red').palette.monochromatic(size: 3)
#=> [red, #550000, #aa0000]
Defining custom palettes
Kodachroma allows you to define your own custom palettes if the default ones
aren’t all you’re looking for. You can define a custom palette by
calling Kodachroma.define_palette
, passing in a palette name and
definition block. The definition block uses the color manipulation
methods (i.e. =lighten=, spin
, etc.) as its DSL. Every DSL call
defines a new color that will be included in the palette. Your seed
color (i.e. the color from which you call the palette method) will be
included as the first color in your palette too.
red = Kodachroma.paint('red')
red.palette.respond_to? :my_palette #=> false
# Define a palette with 5 colors including the seed color
Kodachroma.define_palette :my_palette do
spin 60
spin 180
spin(60).brighten(20) # chain calls as well
greyscale
end
red.palette.respond_to? :my_palette #=> true
red.palette.my_palette #=> [#ff0000 #ffff00 #00ffff #ffff33 #808080]
Dynamic custom palettes
You can generate custom palettes on the fly too with
Kodachroma::Color#custom_palette
.
Kodachroma.paint('red').custom_palette do
spin 60
spin 180
end
#=> [red, yellow, cyan]
Serializing colors
Colors offer several methods to output to different string color formats.
Method | Description |
---|---|
to_hsv |
output to hsv string, outputs hsva if alpha < 1 |
to_hsl |
output to hsl string, outputs hsla if alpha < 1 |
to_hex |
output to hex string, optional argument allows 3-character hex output if possible |
to_hex8 |
output to 8-character hex string with alpha value in the highest order byte |
to_rgb |
output to rgb string, outputs rgba if alpha < 1 |
to_name |
output to color name string if available, otherwise '<unknown>' or to_hex output based on optional arg value |
to_s |
output to the appropriate string format based on how the color was created, optional arg forces the format |
# to_hsv
Kodachroma.paint('red').to_hsv #=> 'hsv(0, 100%, 100%)'
Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_hsv #=> 'hsva(0, 100%, 100%, 0.5)'
# to_hsl
Kodachroma.paint('red').to_hsl #=> 'hsl(0, 100%, 50%)'
Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_hsl #=> 'hsla(0, 100%, 50%, 0.5)'
# to_hex
Kodachroma.paint('red').to_hex #=> '#ff0000'
Kodachroma.paint('red').to_hex(true) #=> '#f00'
Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_hex #=> '#ff0000'
Kodachroma.paint('red').to_hex #=> '#ffff0000'
Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_hex #=> '#80ff0000'
# to_rgb
Kodachroma.paint('red').to_rgb #=> 'rgb(255, 0, 0)'
Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_rgb #=> 'rgb(255, 0, 0, 0.5)'
# to_name
Kodachroma.paint('red').to_name #=> 'red'
Kodachroma.paint('#00f').to_name #=> 'blue'
Kodachroma.paint('rgba(255, 0, 0, 0.5)').to_name #=> '<unknown>'
Kodachroma.paint('#123').to_name(true) #=> '#112233'
# to_s
Kodachroma.paint('red').to_s #=> 'red'
Kodachroma.paint('rgb(255, 0, 0)').to_s #=> 'rgb(255, 0, 0)'
Kodachroma.paint('#f00').to_s #=> '#f00'
Kodachroma.paint('#80ff0000').to_s(:rgb) #=> 'rgba(255, 0, 0, 0.5)'
Other methods
Colors also have a few other helper methods:
Method | Description |
---|---|
dark? |
is the color dark? |
light? |
is the color light? |
alpha |
retrieve the alpha value |
brightness |
calculate the brightness as a number between 0 and 255 |
complement |
return the complementary color |
# dark?
Kodachroma.paint('red').dark? #=> true
Kodachroma.paint('yellow').dark? #=> false
# light?
Kodachroma.paint('red').light? #=> false
Kodachroma.paint('yellow').light? #=> true
# alpha
Kodachroma.paint('red').alpha #=> 1.0
Kodachroma.paint('rgba(0, 0, 0, 0.5)').alpha #=> 0.5
# brightness
Kodachroma.paint('red').brightness #=> 76.245
Kodachroma.paint('yellow').brightness #=> 225.93
Kodachroma.paint('white').brightness #=> 255.0
Kodachroma.paint('black').brightness #=> 0.0
# complement
Kodachroma.paint('red').complement #=> cyan
Trivia
The name “Kodachroma” is inspired by Paul Simon’s lovely song “Kodachrome” and my desire to keep “chroma” in the name of the gem so people searching for the original gem might find this fork.