Skip to content

Instantly share code, notes, and snippets.

@ctbarna
Created August 2, 2012 02:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctbarna/3232445 to your computer and use it in GitHub Desktop.
Save ctbarna/3232445 to your computer and use it in GitHub Desktop.
Coffeescript Color Interpolator
root = exports ? window
Number::toPaddedString = (radix, digits=2) ->
str = this.toString(radix)
while str.length < digits
str = "0" + str
str
# Interpolate between html RGB hex colors.
class Interpolator
constructor: (startColor, endColor, steps=10) ->
testRegExp = /^#[0-9A-F]{6}$/i
if testRegExp.test(startColor) is false
throw Error("Start color is incorrect.")
if testRegExp.test(endColor) is false
throw Error("End color is incorrect.")
# Parse the start color
@start = {
r: parseInt(startColor.substr(1, 2), 16)
g: parseInt(startColor.substr(3, 2), 16)
b: parseInt(startColor.substr(5, 2), 16)
}
# Parse the end color
@end = {
r: parseInt(endColor.substr(1, 2), 16)
g: parseInt(endColor.substr(3, 2), 16)
b: parseInt(endColor.substr(5, 2), 16)
}
# How many steps do we want to interpolate between?
@steps = steps
# Just interpolate one RGB channel.
interpolateSub: (step_num, color) ->
if step_num > @steps then return false
eachStep = (@start[color] - @end[color]) / @steps
Math.ceil(@start[color] - (eachStep * step_num))
# Get the color for a given interpolation step.
interpolate: (step_num) ->
colstr = '#'
for color in ['r', 'g', 'b']
val = new Number(@interpolateSub(step_num, color))
colstr += val.toPaddedString(16)
colstr
# Return all the possible colors.
getRange: ->
colList = []
for step in [1..@steps]
colList.push(@interpolate(step))
colList
root.Interpolator = Interpolator
chai = require 'chai'
chai.should()
Interpolator = require('./interpolator').Interpolator
describe "Interpolator", ->
color1 = "#FFFFFF"
color2 = "#000000"
steps = 10
colorRegExp = /^#[0-9A-F]{6}$/i
it 'should be creatable', ->
(-> new Interpolator(color1, color2, steps)).should.not.throw(Error)
it 'should not accept bad start color', ->
badColor1 = "abscdion"
(-> new Interpolator(badColor1, color2, steps)).should.throw(Error)
it 'should not accept bad end color', ->
badColor2 = "avoinsv"
(-> new Interpolator(color1, badColor2, steps)).should.throw(Error)
describe "#interpolate()", ->
it 'should return a color when asked to interpolate', ->
interpolator = new Interpolator(color1, color2, steps)
randomNumber = Math.ceil(Math.random() * steps)
colorRegExp.test(interpolator.interpolate(randomNumber)).should.equal(true)
describe "#getRange()", ->
it 'should list correct number of colors', ->
interpolator = new Interpolator(color1, color2, steps)
interpolator.getRange().length.should.equal(steps)
it 'should have correct color codes', ->
interpolator = new Interpolator(color1, color2, steps)
for color in interpolator.getRange()
colorRegExp.test(color).should.equal(true)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment