Skip to content

Instantly share code, notes, and snippets.

@miccolis
Created March 29, 2012 03:06
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 miccolis/2232837 to your computer and use it in GitHub Desktop.
Save miccolis/2232837 to your computer and use it in GitHub Desktop.
Test of various hsl2rgb conversions
var assert = require('assert');
var tests = [
{hsl: [0, 0, 0], rgb: [0, 0, 0]}, // black
{hsl: [0, 0, 1], rgb: [255, 255, 255]}, // white
{hsl: [0, 1, 0.5], rgb: [255, 0, 0]}, // red
{hsl: [120, 1, 0.5], rgb: [0, 255, 0]}, // green
{hsl: [240, 1, 0.5], rgb: [0, 0, 255]}, // blue
// http://www.december.com/html/spec/colorcodes.html
{hsl: [205, 0.55, 0.75], rgb: [155, 196, 226]}, // cerulean blue
{hsl: [131, 0.91, 0.86], rgb: [189, 252, 201]}, // mint green
{hsl: [9, 0.59, 0.34], rgb: [138, 51, 36]}, // burnt umber
// Brokers
// Calculations from http://serennu.com/colour/hsltorgb.php
{hsl: [350, 0.9, 0.1], rgb: [48, 3, 10]},
{hsl: [350, 0.9, 0.5], rgb: [242, 13, 51]},
{hsl: [350, 0.9, 0.8], rgb: [250, 158, 173]},
];
var converters = [
// From node-tint
function (h, s, l) {
if (!s) return [l * 255, l * 255, l * 255];
var v = l <= 0.5 ? l*(1+s) : l+s-l*s;
if (!v) return [0, 0, 0];
var min = 2*l-v;
var sv = (v-min)/l
h = (h % 360) / 60;
var sextant = h | 0;
var fract = h-sextant;
v *= 255;
min *= 255;
switch (sextant) {
case 0: return [Math.round(v), Math.round(min+v*sv*fract), Math.round(min)];
case 1: return [Math.round(v-v*sv*fract), Math.round(v), Math.round(min)];
case 2: return [Math.round(min), Math.round(v), Math.round(min+v*sv*fract)];
case 3: return [Math.round(min), Math.round(v-v*sv*fract), Math.round(v)];
case 4: return [Math.round(min+v*sv*fract), Math.round(min), Math.round(v)];
case 5: return [Math.round(v), Math.round(min), Math.round(v-v*sv*fract)];
}
},
// From farbtastic
function(h, s, l) {
// normalize input.
h = h / 360;
var m1, m2, r, g, b;
var hueToRGB = function (m1, m2, h) {
h = (h + 1) % 1;
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
if (h * 2 < 1) return m2;
if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
return m1;
};
m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s;
m1 = l * 2 - m2;
return [
hueToRGB(m1, m2, h + 0.33333) * 255,
hueToRGB(m1, m2, h) * 255,
hueToRGB(m1, m2, h - 0.33333) * 255
];
},
// @see http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
function (h, s, l) {
// normalize input.
h = h / 360;
var r, g, b;
if (s == 0) {
r = g = b = l; // achromatic
} else {
function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [r * 255, g * 255, b * 255];
}
];
var run = 0;
var fail = 0;
converters.forEach(function(hsl2rgb, idx) {
console.warn("Method " + (idx + 1));
tests.forEach(function(test) {
run++;
var rgb = hsl2rgb(test.hsl[0], test.hsl[1],test.hsl[2]);
rgb[0] = Math.round(rgb[0]);
rgb[1] = Math.round(rgb[1]);
rgb[2] = Math.round(rgb[2]);
try {
assert.deepEqual(test.rgb, rgb);
}
catch(e) {
fail++
console.warn(">> " + e.toString());
}
});
});
console.log(">> Passed " + (run - fail) + " of " + run);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment