Project

kodachroma

0.01
Low commit activity in last 3 years
No release in over a year
A library for color manipulation and palette generation.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies
 Project Readme

Kodachroma

https://badge.fury.io/rb/kodachroma.svg

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.