I'm creating an app that visualises stars using a NASA API. The colour of a star comes back as a 0 to 1 value, with 0 being pure blue, and 1 being pure red. Essentially I need to set up a way to convert 0-1 values in javascript to a sliding HEX (or rgb) scale, progressing like this:
0: blue (9aafff)
.165: blue white (cad8ff)
.33: white (f7f7ff)
.495: yellow white (fcffd4)
.66: yellow (fff3a1)
.825: orange (ffa350)
1: red (fb6252)
Is this possible? I don't have any idea how to even begin to approach this. Cheers!
The best would be to work in another color space than the RGB one. For example HSL.
Example:
var stones = [ // Your Data
{v:0, hex:'#9aafff'},
{v:.165, hex:'#cad8ff'},
{v:.33, hex:'#f7f7ff'},
{v:.495, hex:'#fcffd4'},
{v:.66, hex:'#fff3a1'},
{v:.825, hex:'#ffa350'},
{v:1, hex:'#fb6252'},
]
stones.forEach(function(s){
s.rgb = hexToRgb(s.hex);
s.hsl = rgbToHsl.apply(0, s.rgb);
});
function valueToRgbColor(val){
for (var i=1; i<stones.length; i++) {
if (val<=stones[i].v) {
var k = (val-stones[i-1].v)/(stones[i].v-stones[i-1].v),
hsl = interpolArrays(stones[i-1].hsl, stones[i].hsl, k);
return 'rgb('+hslToRgb.apply(0,hsl).map(function(v){ return v|0})+')';
}
}
throw "bad value";
}
/**
* Converts an RGB color value to HSL. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
*
* #param Number r The red color value
* #param Number g The green color value
* #param Number b The blue color value
* #return Array The HSL representation
*/
function rgbToHsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* #param Number h The hue
* #param Number s The saturation
* #param Number l The lightness
* #return Array The RGB representation
*/
function hslToRgb(h, s, l){
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];
}
function hexToRgb(hex) {
return /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
.slice(1).map(function(v){ return parseInt(v,16) });
}
function interpolArrays(a,b,k){
var c = a.slice();
for (var i=0;i<a.length;i++) c[i]+=(b[i]-a[i])*k;
return c;
}
var stones = [ // Your Data
{v:0, hex:'#9aafff'},
{v:.165, hex:'#cad8ff'},
{v:.33, hex:'#f7f7ff'},
{v:.495, hex:'#fcffd4'},
{v:.66, hex:'#fff3a1'},
{v:.825, hex:'#ffa350'},
{v:1, hex:'#fb6252'},
]
stones.forEach(function(s){
s.rgb = hexToRgb(s.hex);
s.hsl = rgbToHsl.apply(0, s.rgb);
});
function valueToRgbColor(val){
for (var i=1; i<stones.length; i++) {
if (val<=stones[i].v) {
var k = (val-stones[i-1].v)/(stones[i].v-stones[i-1].v),
hsl = interpolArrays(stones[i-1].hsl, stones[i].hsl, k);
return 'rgb('+hslToRgb.apply(0,hsl).map(function(v){ return v|0})+')';
}
}
throw "bad value";
}
for (var i=0; i<=1; i+=.03) {
var color = valueToRgbColor(i);
$('<div>').css({background:color}).text(i.toFixed(2)+" -> "+color).appendTo('body');
}
body {
background: #222;
}
div {
width:200px;
margin:auto;
color: #333;
padding: 2px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
For this example, I took the color space conversion functions here but there are easy to find once you know what to look for.
Note that modern browsers understand HSL colors (exemple: background: hsl(120,100%, 50%);) so, if you're just building HTML, you don't have to embed all this code in your page, just precompute the color stops and interpolate on the HSL values directly.
Here is one the solution in pure Javascript I just did. It process a linear interpolation between two colors.
/*
NASA color to RGB function
by Alexis Paques
It process a linear interpolation between two colors, here is the scheme:
0: blue
.165: blue white
.33: white
.495: yellow white
.66: yellow
.825: orange
1: red
*/
var blue = [0,0,255];
var bluewhite = [127,127,255];
var white = [255,255,255];
var yellowwhite = [255,255,127];
var yellow = [255,255,0];
var orange = [255,127,0];
var red = [255,0,0];
function color01toRGB(color01){
var RGB = [0,0,0];
var fromRGB = [0,0,0];
var toRGB = [0,0,0];
if(!color01)
return '#000000';
if(color01 > 1 || color01 < 0)
return '#000000';
if(color01 >= 0 && color01 <= 0.165 ){
fromRGB = blue;
toRGB = bluewhite;
}
else if(color01 > 0.165 && color01 <= 0.33 ){
fromRGB = bluewhite;
toRGB = white;
}
else if(color01 > 0.33 && color01 <= 0.495 ){
fromRGB = white;
toRGB = yellowwhite;
}
else if(color01 > 0.495 && color01 <= 0.66 ){
fromRGB = yellowwhite;
toRGB = yellow;
}
else if(color01 > 0.66 && color01 <= 0.825 ){
fromRGB = yellow;
toRGB = orange;
}
else if(color01 > 0.825 && color01 <= 1 ){
fromRGB = orange;
toRGB = red;
}
// 0.165
for (var i = RGB.length - 1; i >= 0; i--) {
RGB[i] = Math.round(fromRGB[i]*color01/0.165 + toRGB[i]*(1-color01/0.165)).toString(16);
};
return '#' + RGB.join('');
}
Since you have a list of values, all pretty well-saturated and bright, you can probably interpolate in the current (RGB) space for this. It won't be quite as pretty as if you convert to HSL, but will work fine for the colors you have.
Since you don't have any weighting or curves in the data, going with a simple linear interpolation should work just fine. Something like:
var stops = [
[0, 154, 175, 255],
[0.165, 202, 216, 255],
[0.33, 247, 247, 255],
[0.495, 252, 255, 212],
[0.66, 255, 243, 161],
[0.825, 255, 163, 80],
[1, 251, 98, 82]
];
function convertColor(color) {
var c = Math.min(Math.max(color, 0), 1); // Clamp between 0 and 1
// Find the first stop below c
var startIndex = 0;
for (; stops[startIndex][0] < c && startIndex < stops.length; ++startIndex) {
// nop
}
var start = stops[startIndex];
console.log('using stop', startIndex, 'as start');
// Find the next stop (above c)
var stopIndex = startIndex + 1;
if (stopIndex >= stops.length) {
stopIndex = stops.length - 1;
}
var stop = stops[stopIndex];
console.log('using stop', stopIndex, 'as stop');
// Find the distance from start to c and start to stop
var range = stop[0] - start[0];
var diff = c - start[0];
// Convert diff into a ratio from start to stop
if (range > 0) {
diff /= range;
}
console.log('interpolating', c, 'between', stop[0], 'and', start[0], 'by', diff);
// Convert from RGB to HSL
var a = rgbToHsl(start[1], start[2], start[3]);
var b = rgbToHsl(stop[1], stop[2], stop[3]);
console.log('hsl stops', a, b);
// Interpolate between the two colors (start * diff + (stop * (1 - diff)))
var out = [0, 0, 0];
out[0] = a[0] * diff + (b[0] * (1 - diff));
out[1] = a[1] * diff + (b[1] * (1 - diff));
out[2] = a[2] * diff + (b[2] * (1 - diff));
console.log('interpolated', out);
// Convert back from HSL to RGB
var r = hslToRgb(out[0], out[1], out[2]);
r = r.map(function(rv) {
// Round each component of the output
return Math.round(rv);
});
return r;
}
// Set the divs
var divs = document.querySelectorAll('.star');
Array.prototype.forEach.call(divs, function(star) {
var color = convertColor(star.dataset.color);
var colorStr = 'rgb(' + color[0] + ',' + color[1] + ',' + color[2] + ')';
console.log('setting', star, 'to', colorStr);
star.style.backgroundColor = colorStr;
});
// HSL to RGB conversion from http://stackoverflow.com/a/30758827/129032
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b),
min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return [h, s, l];
}
function hslToRgb(h, s, l) {
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];
}
.star {
width: 24px;
height: 24px;
display: inline-block;
box-shadow: 0px 0px 16px -2px rgba(0, 0, 0, 0.66);
}
<div class="star" data-color="0.0"></div>
<div class="star" data-color="0.05"></div>
<div class="star" data-color="0.1"></div>
<div class="star" data-color="0.15"></div>
<div class="star" data-color="0.2"></div>
<div class="star" data-color="0.25"></div>
<div class="star" data-color="0.3"></div>
<div class="star" data-color="0.35"></div>
<div class="star" data-color="0.4"></div>
<div class="star" data-color="0.45"></div>
<div class="star" data-color="0.5"></div>
<div class="star" data-color="0.55"></div>
<div class="star" data-color="0.6"></div>
<div class="star" data-color="0.65"></div>
<div class="star" data-color="0.7"></div>
<div class="star" data-color="0.75"></div>
<div class="star" data-color="0.8"></div>
<div class="star" data-color="0.85"></div>
<div class="star" data-color="0.9"></div>
<div class="star" data-color="0.95"></div>
<div class="star" data-color="1.0"></div>
Related
I'm trying to make buttons for converting between color models (hex, rgb, hsl).
I've created a button that generates a random color when clicked on.
And I've created a class that generates the random color in rgb and has methods to convert it to hex or hsl.
I tried creating a "click" event listener on each of the color model buttons but I'm not able to access the newly generated color object that I made through the class (block scope).
Should I have just used normal functions to convert instead of a class constructor?
const colorName = document.querySelector(".colorName");
const genColorBtn = document.querySelector("#genColorBtn");
const hexBtn = document.querySelector("#hexBtn");
const rgbBtn = document.querySelector("#rgbBtn");
const hslBtn = document.querySelector("#hslBtn");
// Generate Random Color
const genRandomColor = () => {
const r = Math.floor(Math.random() * 255 + 1);
const g = Math.floor(Math.random() * 255 + 1);
const b = Math.floor(Math.random() * 255 + 1);
return new Color(r, g, b);
};
genColorBtn.addEventListener("click", function () {
const newColor = genRandomColor();
document.body.style.backgroundColor = newColor.rgb();
colorName.innerText = newColor.rgb();
});
// Color Model Conversions
class Color {
constructor(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
this.calcHSL();
}
// Add methods to the prototype.
hex() {
const { r, g, b } = this;
return (
"#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)
);
}
rgb() {
const { r, g, b } = this;
return `rgb(${r}, ${g}, ${b})`;
}
hsl() {
const { h, s, l } = this;
return `hsl(${h}, ${s}%, ${l}%)`;
}
// For hsl
calcHSL() {
let { r, g, b } = this;
// Make r, g, and b fractions of 1
r /= 255;
g /= 255;
b /= 255;
// Find greatest and smallest channel values
let cmin = Math.min(r, g, b),
cmax = Math.max(r, g, b),
delta = cmax - cmin,
h = 0,
s = 0,
l = 0;
if (delta == 0) h = 0;
else if (cmax == r)
// Red is max
h = ((g - b) / delta) % 6;
else if (cmax == g)
// Green is max
h = (b - r) / delta + 2;
// Blue is max
else h = (r - g) / delta + 4;
h = Math.round(h * 60);
// Make negative hues positive behind 360°
if (h < 0) h += 360;
// Calculate lightness
l = (cmax + cmin) / 2;
// Calculate saturation
s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
// Multiply l and s by 100
s = +(s * 100).toFixed(1);
l = +(l * 100).toFixed(1);
// Assign h, s, l to the object instance so that we can reuse it.
this.h = h;
this.s = s;
this.l = l;
}
}
<body>
<main>
<h1>Random Color Flipper</h1>
<h2>Color: <span class="colorName">rgb(255, 255, 255)</span></h2>
<div class="colorModes">
<button id="hexBtn">hex</button>
<button id="rgbBtn">rgb</button>
<button id="hslBtn">hsl</button>
</div>
<button id="genColorBtn">Generate Color</button>
</main>
<script src="app.js"></script>
</body>
Your code seems fine, but your hex, rgb and hsl buttons were not wired up. I added a variable curRGB to store the current RGB values (though there is probably a more elegant getter/setter for your Class that could be written). I did take a stab at the hexBtn listener:
hexBtn.addEventListener("click", function () {
colorName.innerText = new Color(...curRGB).hex();
});
const colorName = document.querySelector(".colorName");
const genColorBtn = document.querySelector("#genColorBtn");
const hexBtn = document.querySelector("#hexBtn");
const rgbBtn = document.querySelector("#rgbBtn");
const hslBtn = document.querySelector("#hslBtn");
let curRGB
// Generate Random Color
const genRandomColor = () => {
const r = Math.floor(Math.random() * 255 + 1);
const g = Math.floor(Math.random() * 255 + 1);
const b = Math.floor(Math.random() * 255 + 1);
curRGB = [r, g, b]
return new Color(r, g, b);
};
genColorBtn.addEventListener("click", function () {
const newColor = genRandomColor();
document.body.style.backgroundColor = newColor.rgb();
colorName.innerText = newColor.rgb();
});
hexBtn.addEventListener("click", function () {
colorName.innerText = new Color(...curRGB).hex();
});
// Color Model Conversions
class Color {
constructor(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
this.calcHSL();
}
// Add methods to the prototype.
hex() {
const { r, g, b } = this;
return (
"#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)
);
}
rgb() {
const { r, g, b } = this;
return `rgb(${r}, ${g}, ${b})`;
}
hsl() {
const { h, s, l } = this;
return `hsl(${h}, ${s}%, ${l}%)`;
}
// For hsl
calcHSL() {
let { r, g, b } = this;
// Make r, g, and b fractions of 1
r /= 255;
g /= 255;
b /= 255;
// Find greatest and smallest channel values
let cmin = Math.min(r, g, b),
cmax = Math.max(r, g, b),
delta = cmax - cmin,
h = 0,
s = 0,
l = 0;
if (delta == 0) h = 0;
else if (cmax == r)
// Red is max
h = ((g - b) / delta) % 6;
else if (cmax == g)
// Green is max
h = (b - r) / delta + 2;
// Blue is max
else h = (r - g) / delta + 4;
h = Math.round(h * 60);
// Make negative hues positive behind 360°
if (h < 0) h += 360;
// Calculate lightness
l = (cmax + cmin) / 2;
// Calculate saturation
s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
// Multiply l and s by 100
s = +(s * 100).toFixed(1);
l = +(l * 100).toFixed(1);
// Assign h, s, l to the object instance so that we can reuse it.
this.h = h;
this.s = s;
this.l = l;
}
}
<main>
<h1>Random Color Flipper</h1>
<h2>Color: <span class="colorName">rgb(255, 255, 255)</span></h2>
<div class="colorModes">
<button id="hexBtn">hex</button>
<button id="rgbBtn">rgb</button>
<button id="hslBtn">hsl</button>
</div>
<button id="genColorBtn">Generate Color</button>
</main>
I need a color converter to convert from hsl to rgb and hex value. I am going to do similar like this. I am using jquery and jquery ui range slider for this. Here is my code:
$(function() {
$( "#hsl_hue_range" ).slider({
min: 0,
max: 100,
value: 0,
range: false,
animate:"slow",
orientation: "horizontal",
slide: function( event, ui ) {
var hsl_hue = ui.value;
}
});
});
$(function() {
$( "#hsl_saturation_range" ).slider({
min: 0,
max: 100,
value: 0,
range: false,
animate:"slow",
orientation: "horizontal",
slide: function( event, ui ) {
var hsl_saturation = ui.value;
}
});
});
$(function() {
$( "#hsl_light_range" ).slider({
min: 0,
max: 100,
value: 0,
range: false,
animate:"slow",
orientation: "horizontal",
slide: function( event, ui ) {
var hsl_light = ui.value;
}
});
});
I want the solution like this:
the input to converter can be given by the variables. like hsl_hue hsl_saturation hsl_light.
Is there any way to do this?
if no way, what can I do?
New approach (inspired by #Kamil-Kiełczewski solution)
Takes degree, percentage, percentage and returns css hex color:
function hslToHex(h, s, l) {
l /= 100;
const a = s * Math.min(l, 1 - l) / 100;
const f = n => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color).toString(16).padStart(2, '0'); // convert to Hex and prefix "0" if needed
};
return `#${f(0)}${f(8)}${f(4)}`;
}
Example:
hslToHex(360, 100, 50) // "#ff0000" -> red
Original version: (still OK, just longer)
Takes degree, percentage, percentage and returns css hex color:
function hslToHex(h, s, l) {
h /= 360;
s /= 100;
l /= 100;
let r, g, b;
if (s === 0) {
r = g = b = l; // achromatic
} else {
const 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;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
const toHex = x => {
const hex = Math.round(x * 255).toString(16);
return hex.length === 1 ? '0' + hex : hex;
};
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
Example:
hslToHex(360, 100, 50) // "#ff0000" -> red
Shortest
Try this (wiki, error analysis, more: rgb2hsl, hsv2rgb rgb2hsv and hsl2hsv)
// input: h in [0,360] and s,v in [0,1] - output: r,g,b in [0,1]
function hsl2rgb(h,s,l)
{
let a= s*Math.min(l,1-l);
let f= (n,k=(n+h/30)%12) => l - a*Math.max(Math.min(k-3,9-k,1),-1);
return [f(0),f(8),f(4)];
}
To calc hsl2hex use rgb2hex(...hsl2rgb(30,1,0.5)). To convert string from format e.g. rgb(255, 255, 255) to hex use rgbStrToHex (which handle empty string case) as follows
// oneliner version
let hsl2rgb = (h,s,l, a=s*Math.min(l,1-l), f= (n,k=(n+h/30)%12) => l - a*Math.max(Math.min(k-3,9-k,1),-1)) => [f(0),f(8),f(4)];
// r,g,b are in [0-1], result e.g. #0812fa.
let rgb2hex = (r,g,b) => "#" + [r,g,b].map(x=>Math.round(x*255).toString(16).padStart(2,0) ).join('');
// hexStr e.g #abcdef, result "rgb(171,205,239)"
let hexStr2rgb = (hexStr) => `rgb(${hexStr.substr(1).match(/../g).map(x=>+`0x${x}`)})`;
// rgb - color str e.g."rgb(12,233,43)", result color hex e.g. "#0ce92b"
let rgbStrToHex= rgb=> '#'+rgb.match(/\d+/g).map(x=>(+x).toString(16).padStart(2,0)).join``
console.log(`hsl: (30,0.2,0.3) --> rgb: (${hsl2rgb(30,0.2,0.3)}) --> hex: ${rgb2hex(...hsl2rgb(30,0.2,0.3))}`);
console.log(`rgb: ${hexStr2rgb("#ff647b")} --> hex: ${rgbStrToHex("rgb(255,100, 123)")}`)
// ---------------
// UX
// ---------------
rgb= [0,0,0];
hs= [0,0,0];
let $ = x => document.querySelector(x);
function changeRGB(i,e) {
rgb[i]=e.target.value/255;
hs = rgb2hsl(...rgb);
refresh();
}
function changeHS(i,e) {
hs[i]=e.target.value/(i?255:1);
rgb= hsl2rgb(...hs);
refresh();
}
function refresh() {
rr = rgb.map(x=>x*255|0).join(', ')
hh = rgb2hex(...rgb);
tr = `RGB: ${rr}`
th = `HSL: ${hs.map((x,i)=>i? (x*100).toFixed(2)+'%':x|0).join(', ')}`
thh= `HEX: ${hh}`
$('.box').style.backgroundColor=`rgb(${rr})`;
$('.infoRGB').innerHTML=`${tr}`;
$('.infoHS').innerHTML =`${th}\n${thh}`;
$('#r').value=rgb[0]*255;
$('#g').value=rgb[1]*255;
$('#b').value=rgb[2]*255;
$('#h').value=hs[0];
$('#s').value=hs[1]*255;
$('#l').value=hs[2]*255;
}
function rgb2hsl(r,g,b) {
let a=Math.max(r,g,b), n=a-Math.min(r,g,b), f=(1-Math.abs(a+a-n-1));
let h= n && ((a==r) ? (g-b)/n : ((a==g) ? 2+(b-r)/n : 4+(r-g)/n));
return [60*(h<0?h+6:h), f ? n/f : 0, (a+a-n)/2];
}
refresh();
.box {
width: 50px;
height: 50px;
margin: 20px;
}
body {
display: flex;
}
<div>
<input id="r" type="range" min="0" max="255" oninput="changeRGB(0,event)">R<br>
<input id="g" type="range" min="0" max="255" oninput="changeRGB(1,event)">G<br>
<input id="b" type="range" min="0" max="255" oninput="changeRGB(2,event)">B<br>
<pre class="infoRGB"></pre>
</div>
<div>
<div class="box hsl"></div>
</div>
<div>
<input id="h" type="range" min="0" max="360" oninput="changeHS(0,event)">H<br>
<input id="s" type="range" min="0" max="255" oninput="changeHS(1,event)">S<br>
<input id="l" type="range" min="0" max="255" oninput="changeHS(2,event)">L<br>
<pre class="infoHS"></pre><br>
</div>
HSL to RGB:
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* #param {number} h The hue
* #param {number} s The saturation
* #param {number} l The lightness
* #return {Array} The RGB representation
*/
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
var hue2rgb = 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 [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
You can find more information here - HSL to RGB color conversion
Another way to solve this problem is to leverage the window.getComputedStyle capability of modern browsers:
Create an element on the page (it can be hidden, e.g. with display:none, but that appears to suppress output of the opacity / "A" value)
Set a color-valued property of that element using the representation of your choice, e.g. e.style.color = 'hsla(100, 50%, 75%, 0.8)'; (or even named colors like 'rebeccapurple')
Read the value back using window.getComputedStyle(e).color. It will be a string of the form rgb(r,g,b) or rgba(r,g,b,a).
Live demo on CodePen
I've made a small library that can easily convert colors.
This is my HSL to RGB method, which uses a few other utility methods from the library:
Color.hslToRgb = function(hsl, formatted) {
var a, b, g, h, l, p, q, r, ref, s;
if (isString(hsl)) {
if (!hsl.match(Color.HSL_REGEX)) {
return;
}
ref = hsl.match(/hsla?\((.+?)\)/)[1].split(',').map(function(value) {
value.trim();
return parseFloat(value);
}), h = ref[0], s = ref[1], l = ref[2], a = ref[3];
} else if ((isObject(hsl)) && (hasKeys(hsl, ['h', 's', 'l']))) {
h = hsl.h, s = hsl.s, l = hsl.l, a = hsl.a;
} else {
return;
}
h /= 360;
s /= 100;
l /= 100;
if (s === 0) {
r = g = b = l;
} else {
q = l < 0.5 ? l * (1 + s) : l + s - l * s;
p = 2 * l - q;
r = Color.hueToRgb(p, q, h + 1 / 3);
g = Color.hueToRgb(p, q, h);
b = Color.hueToRgb(p, q, h - 1 / 3);
}
return getRgb(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a, formatted);
};
If you don't want to use npm, the lib can also be found on GitHub.
I recently had cause to solve this problem and came up with a canvas-based solution. I'm logging it here for posterity only.
In my case I also needed to account for the cumulative effects on the conversion given a range of background colors and a semi-transparent alpha channel...
var HSL2COLOR = function () {
return function (hsl, bg) {
function checkHex(v) {
return 1 === v.length ? '0'+v : v;
}
var data, r, g, b, a,
cnv = document.createElement('canvas'),
ctx = cnv.getContext('2d'),
alpha = /a\(/.test(hsl),
output = {};
return cnv.width = cnv.height = 1,
bg && (ctx.fillStyle = bg, ctx.fillRect(0, 0, 1, 1)),
ctx.fillStyle = hsl,
ctx.fillRect(0, 0, 1, 1),
data = ctx.getImageData(0, 0, 1, 1).data,
r = data[0],
g = data[1],
b = data[2],
a = (data[3] / 255).toFixed(2),
alpha ? (output.hsla = hsl, bg ? output.rgb = 'rgb('+r+','+g+','+b+')' : output.rgba = 'rgb('+r+','+g+','+b+','+a+')') : (output.hsl = hsl, output.rgb = 'rgb('+r+','+g+','+b+')'),
output.hex = '#'+checkHex(r.toString(16))+checkHex(g.toString(16))+checkHex(b.toString(16)),
output;
};
}();
// hsl: no alpha-channel + no background color
console.log(HSL2COLOR('hsl(170, 60%, 45%)'));
/*=> {
hsl: "hsl(170, 60%, 45%)",
rgb: "rgb(45,183,160)",
hex: "#2db7a0"
}
*/
// hsla: alpha-channel + no background color
console.log(HSL2COLOR('hsla(170, 60%, 45%, 0.35)'));
/*=> {
hsla: "hsla(170, 60%, 45%, 0.35)",
rgba: "rgb(42,183,160,0.35)",
hex: "#2ab7a0"
}
*/
// hsla: alpha-channel + background color
console.log(HSL2COLOR('hsla(170, 60%, 45%, 0.35)','#f00'));
/*=> {
hsla: "hsla(170, 60%, 45%, 0.35)",
rgb: "rgb(181,64,56)",
hex: "#b54038"
}
*/
As you can see from the results above, HEX values are not particularly representative when there is an alpha-channel in the input but no background color specified - as the canvas basically sees a transparent background as black. Nonetheless, the rgba value remained coherent.
Anyway, I achieved what I needed to, and perhaps this will be of some use to someone, sometime.
BP
Or you could npm install color-convert and not re-invent the wheel.
const convert = require('color-convert')
const hex = '#' + convert.hsl.hex(96, 48, 59) // convert hsl to hex
const rgb = convert.hsl.rgb(96, 48, 59) // convert hsl to rgb
Life can be simple at times.
from #icl7126 's answer,
you can add another function param to include alpha
function hsl2hex(h,s,l,alpha) {
l /= 100;
const a = s * Math.min(l, 1 - l) / 100;
const f = n => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color).toString(16).padStart(2, '0');
// convert to Hex and prefix "0" if needed
};
//alpha conversion
alpha = Math.round(alpha * 255).toString(16).padStart(2, '0');
return `#${f(0)}${f(8)}${f(4)}${alpha}`;
}
I have a textured image with color. What i want is to change the color of the image but retaining its texture. i already know how to get the data of an image,pixel by pixel(the rgb values).
here's the sample image:
i want it to be colored into these:
Here's an interactive solution. Run it from localhost and specify a valid image.
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
window.addEventListener('load', mInit, false);
function mInit()
{
var srcImg = byId('srcImg');
byId('hueSlider').style.width = srcImg.width + "px";
var destImg = byId('dstImg');
destImg.width = srcImg.width;
destImg.height = srcImg.height;
}
function colorize()
{
var curHue = byId('hueSlider').value;
var curSat = byId('satSlider').value;// / 100.0;
var curLum = byId('lumSlider').value / 100.0;
byId('hueVal').innerHTML = curHue;
byId('satVal').innerHTML = curSat;
byId('lumVal').innerHTML = curLum;
var dst = byId('dstImg');
var dstCtx = dst.getContext('2d');
var img = byId('srcImg');
dstCtx.drawImage(img, 0, 0);
var dstImgData = dstCtx.getImageData(0,0,dst.width,dst.height);
var i, j, r,g,b,hsl,rgb, index;
if (byId('colCheckBox').checked)
{
console.log('colourizing');
for (j=0; j<dst.height; j++)
{
for (i=0; i<dst.width; i++)
{
index = (i + j*dst.width) * 4; // 4 bytes/pixel, set index to point to r component of x,y in dst image
r = dstImgData.data[index+0];
g = dstImgData.data[index+1];
b = dstImgData.data[index+2];
hsl = rgb2hsl (r, g, b);
hsl.h = curHue;
//if (hsl.h > 359)
// hsl.h -= 360;
hsl.s = curSat;
hsl.l *= curLum;
rgb = hsl2rgb(hsl.h, hsl.s, hsl.l);
dstImgData.data[index+0] = rgb.r;
dstImgData.data[index+1] = rgb.g;
dstImgData.data[index+2] = rgb.b;
}
}
dstCtx.putImageData(dstImgData,0,0);
}
}
// code taken from nichabi.com
function hsl2rgb (h, s, l) {
var r, g, b, m, c, x
if (!isFinite(h)) h = 0
if (!isFinite(s)) s = 0
if (!isFinite(l)) l = 0
h /= 60
if (h < 0) h = 6 - (-h % 6)
h %= 6
s = Math.max(0, Math.min(1, s / 100))
l = Math.max(0, Math.min(1, l / 100))
c = (1 - Math.abs((2 * l) - 1)) * s
x = c * (1 - Math.abs((h % 2) - 1))
if (h < 1) {
r = c
g = x
b = 0
} else if (h < 2) {
r = x
g = c
b = 0
} else if (h < 3) {
r = 0
g = c
b = x
} else if (h < 4) {
r = 0
g = x
b = c
} else if (h < 5) {
r = x
g = 0
b = c
} else {
r = c
g = 0
b = x
}
m = l - c / 2
r = Math.round((r + m) * 255)
g = Math.round((g + m) * 255)
b = Math.round((b + m) * 255)
return { r: r, g: g, b: b }
}
// code taken from nichabi.com
function rgb2hsl (r, g, b)
{
var max, min, h, s, l, d
r /= 255
g /= 255
b /= 255
max = Math.max(r, g, b)
min = Math.min(r, g, b)
l = (max + min) / 2
if (max == min) {
h = s = 0
} else {
d = max - min
s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0)
break
case g:
h = (b - r) / d + 2
break
case b:
h = (r - g) / d + 4
break
}
h /= 6
}
h = Math.floor(h * 360)
s = Math.floor(s * 100)
l = Math.floor(l * 100)
return { h: h, s: s, l: l }
}
</script>
<style>
body
{
background: #888;
}
#hueVal, #satVal, #lumVal
{
font-size: 0.8em;
font-weight: bold;
display: inline;
}
</style>
</head>
<body>
<img id='srcImg' src='handlebars.png'/><canvas id='dstImg'></canvas>
<br>
<label><input type='checkbox' id='colCheckBox' onchange='colorize()' />Colourize</label>
<br>
Hue<input id='hueSlider' onchange='colorize()' type='range' min='0' max='359'/><div id='hueVal'></div><br>
Saturation<input id='satSlider' onchange='colorize()' type='range' value='50' min='0' max='100'/><div id='satVal'></div><br>
Luminance<input id='lumSlider' onchange='colorize()' type='range' min='0' max='200'/><div id='lumVal'></div>
</body>
</html>
Similar to this (how to increase brightness) I want to change the Hue of a RGB (Hex) Color.
Say changeHue("#FF0000", 40) returns "#FFAA00"
Here is the solution I found. I hope its usable and might help in the future. Any improvements or further solutions are very welcome.
Change Hue
// Changes the RGB/HEX temporarily to a HSL-Value, modifies that value
// and changes it back to RGB/HEX.
function changeHue(rgb, degree) {
var hsl = rgbToHSL(rgb);
hsl.h += degree;
if (hsl.h > 360) {
hsl.h -= 360;
}
else if (hsl.h < 0) {
hsl.h += 360;
}
return hslToRGB(hsl);
}
// exepcts a string and returns an object
function rgbToHSL(rgb) {
// strip the leading # if it's there
rgb = rgb.replace(/^\s*#|\s*$/g, '');
// convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
if(rgb.length == 3){
rgb = rgb.replace(/(.)/g, '$1$1');
}
var r = parseInt(rgb.substr(0, 2), 16) / 255,
g = parseInt(rgb.substr(2, 2), 16) / 255,
b = parseInt(rgb.substr(4, 2), 16) / 255,
cMax = Math.max(r, g, b),
cMin = Math.min(r, g, b),
delta = cMax - cMin,
l = (cMax + cMin) / 2,
h = 0,
s = 0;
if (delta == 0) {
h = 0;
}
else if (cMax == r) {
h = 60 * (((g - b) / delta) % 6);
}
else if (cMax == g) {
h = 60 * (((b - r) / delta) + 2);
}
else {
h = 60 * (((r - g) / delta) + 4);
}
if (delta == 0) {
s = 0;
}
else {
s = (delta/(1-Math.abs(2*l - 1)))
}
return {
h: h,
s: s,
l: l
}
}
// expects an object and returns a string
function hslToRGB(hsl) {
var h = hsl.h,
s = hsl.s,
l = hsl.l,
c = (1 - Math.abs(2*l - 1)) * s,
x = c * ( 1 - Math.abs((h / 60 ) % 2 - 1 )),
m = l - c/ 2,
r, g, b;
if (h < 60) {
r = c;
g = x;
b = 0;
}
else if (h < 120) {
r = x;
g = c;
b = 0;
}
else if (h < 180) {
r = 0;
g = c;
b = x;
}
else if (h < 240) {
r = 0;
g = x;
b = c;
}
else if (h < 300) {
r = x;
g = 0;
b = c;
}
else {
r = c;
g = 0;
b = x;
}
r = normalize_rgb_value(r, m);
g = normalize_rgb_value(g, m);
b = normalize_rgb_value(b, m);
return rgbToHex(r,g,b);
}
function normalize_rgb_value(color, m) {
color = Math.floor((color + m) * 255);
if (color < 0) {
color = 0;
}
return color;
}
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
Usage
changeHue("#FF0000", 40) --> returns #ffaa00
changeHue("#D61E1E", 180) --> returns #1ed6d6
changeHue("#2244BB", -80) --> returns #21bb66
References
RGB to HSL
HSL to RGB
Inital Hex to RGB Conversion
If you're not afraid of libraries and a few kb won't ruin your project, you could try sc-color rather than reimplementing the wheel...
Here's a jsfiddle using sc-color. The crux of the code is here:
var c = sc_color("#FF0000").hue(40).hex6();
$("#test").css("background-color", c);
Disclosure: I'm the author of sc-color
I want to take a color and generate random deviations from that color with JavaScript. For example, say I have a color #33CCFF, I want to feed that number into the script and get numbers like #8AE2FF, #00AAE2, and #7BDEFF. Basically, the hue should stay the same, but the saturation/brightness should fluctuate a bit.
What's the fastest and simplest way to generate these numbers?
Convert your RGB color to HSL, keep the Hue, derive Saturation and Lightness(Brightness) with a small random number, for instance, then convert back to RGB.
For converting: http://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL
Bonus, the code for conversion: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
Honestly I don't know how Hex codes work out saturation/brightness, so I would convert to HSL:
http://serennu.com/colour/rgbtohsl.php
change up the ones you want, and change it back. The only major drawback I see is the possibility that the HSL doesn't exist in the Hex field after you've changed it.
As in,
HSL colour space has only 360 x 100 x 100 = 3,600,000
colours in it whilst the RGB colour space has 256 x 256 x 256 =
16,77,216 colours in it, That's four half times as many.
I know this question is one year old, but I was looking around for a solution and couldn't find it.
But basing on suggestions here and there (mainly on SO) I created ready to use script.
NOTICE 1: colorToRGB function is unreliable. I found it in SO (source attached). I changed hex values for some colors but I didn't want to check it for all of them. For best results always use hex value.
NOTICE 2: deviation in generateSimilarColor function is set just for my purposes. You can change it for better results.
NOTICE 3: Many functions are found on SO. I've just gathered them together and I'm providing links to corresponding questions.
JavaScript code below (testing environment on the bottom of the post):
/**
* Generates similar color based on passed one
*
* #param color accepts few formats, e.g. white, #ffffff or [255, 255, 255]
* #return hex value, e.g. #ffffff
*
* #author Carlos (StackOverflow)
*/
function generateSimilarColor(color) {
var rand = generateRandomInt(-5, 5);
if(rand < 0) rand -= 5;
else rand += 5;
var deviation = rand / 100;
if(!isArray(color) || color.length != 3) { // this is not [r, g, b] array
var hexNotation = colorToRGB(color);
if(!hexNotation) { // we couldn't find HEX value of this string based on color name
if(!isString(color) || color.length != 7 || color[0] != '#') { // this is not string in this format: #ffffff
return false;
}
else {
hexNotation = color;
}
}
color = hexToRgb(hexNotation);
if(!color) {
return false;
}
}
var hsl = rgbToHsl(color[0], color[1], color[2]);
// saturation
hsl[1] += deviation;
if(hsl[1] > 1) hsl[1] = 1 - Math.abs(deviation);
else if(hsl[1] < 0) hsl[1] = Math.abs(deviation);
// lightness
hsl[2] += deviation;
if(hsl[2] > 1) hsl[2] = 1 - Math.abs(deviation);
else if(hsl[2] < 0) hsl[2] = Math.abs(deviation);
color = hslToRgb(hsl[0], hsl[1], hsl[2]);
var hex = rgbToHex(color[0], color[1], color[2]);
return hex;
}
/**
* Returns a random integer between min and max
* Using Math.round() will give you a non-uniform distribution!
*
* #source http://stackoverflow.com/questions/1527803/generating-random-numbers-in-javascript-in-a-specific-range
*/
function generateRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
/**
* #source: [slightly changed] http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
*/
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
/**
* #source: [slightly changed] http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
*/
function rgbToHex(r, g, b) {
r = parseInt(r);
g = parseInt(g);
b = parseInt(b);
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
/**
* #source http://stackoverflow.com/questions/1058427/how-to-detect-if-a-variable-is-an-array
*/
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
/**
* #source http://stackoverflow.com/questions/4059147/check-if-a-variable-is-a-string
*/
function isString(str) {
return (typeof str == 'string' || str instanceof String);
}
/**
* #source: http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb slightly change
*/
function hexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? [
parseInt(result[1], 16),
parseInt(result[2], 16),
parseInt(result[3], 16)
] : false;
}
/**
* Converts an RGB color value to HSL. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
*
* #param Number r The red color value
* #param Number g The green color value
* #param Number b The blue color value
* #return Array The HSL representation
*
* #source http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
*/
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* #param Number h The hue
* #param Number s The saturation
* #param Number l The lightness
* #return Array The RGB representation
*/
function hslToRgb(h, s, l) {
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];
}
/**
* #source [slightly changed] http://stackoverflow.com/questions/1573053/javascript-function-to-convert-color-names-to-hex-codes
*/
function colorToRGB(color) {
var colors = {"aliceblue":"#f0f8ff","antiquewhite":"#faebd7","aqua":"#00ffff","aquamarine":"#7fffd4","azure":"#f0ffff",
"beige":"#f5f5dc","bisque":"#ffe4c4","black":"#000000","blanchedalmond":"#ffebcd","blue":"#0000ff","blueviolet":"#8a2be2","brown":"#603311","burlywood":"#deb887",
"cadetblue":"#5f9ea0","chartreuse":"#7fff00","chocolate":"#d2691e","coral":"#ff7f50","cornflowerblue":"#6495ed","cornsilk":"#fff8dc","crimson":"#dc143c","cyan":"#00ffff",
"darkblue":"#00008b","darkcyan":"#008b8b","darkgoldenrod":"#b8860b","darkgray":"#a9a9a9","darkgreen":"#006400","darkkhaki":"#bdb76b","darkmagenta":"#8b008b","darkolivegreen":"#556b2f",
"darkorange":"#ff8c00","darkorchid":"#9932cc","darkred":"#8b0000","darksalmon":"#e9967a","darkseagreen":"#8fbc8f","darkslateblue":"#483d8b","darkslategray":"#2f4f4f","darkturquoise":"#00ced1",
"darkviolet":"#9400d3","deeppink":"#ff1493","deepskyblue":"#00bfff","dimgray":"#696969","dodgerblue":"#1e90ff",
"firebrick":"#b22222","floralwhite":"#fffaf0","forestgreen":"#228b22","fuchsia":"#ff00ff",
"gainsboro":"#dcdcdc","ghostwhite":"#f8f8ff","gold":"#ffd700","goldenrod":"#daa520","gray":"#808080","green":"#008000","greenyellow":"#adff2f",
"honeydew":"#f0fff0","hotpink":"#ff69b4",
"indianred ":"#cd5c5c","indigo ":"#4b0082","ivory":"#fffff0","khaki":"#f0e68c",
"lavender":"#e6e6fa","lavenderblush":"#fff0f5","lawngreen":"#7cfc00","lemonchiffon":"#fffacd","lightblue":"#add8e6","lightcoral":"#f08080","lightcyan":"#e0ffff","lightgoldenrodyellow":"#fafad2",
"lightgrey":"#d3d3d3","lightgreen":"#90ee90","lightpink":"#ffb6c1","lightsalmon":"#ffa07a","lightseagreen":"#20b2aa","lightskyblue":"#87cefa","lightslategray":"#778899","lightsteelblue":"#b0c4de",
"lightyellow":"#ffffe0","lime":"#00ff00","limegreen":"#32cd32","linen":"#faf0e6",
"magenta":"#ff00ff","maroon":"#800000","mediumaquamarine":"#66cdaa","mediumblue":"#0000cd","mediumorchid":"#ba55d3","mediumpurple":"#9370d8","mediumseagreen":"#3cb371","mediumslateblue":"#7b68ee",
"mediumspringgreen":"#00fa9a","mediumturquoise":"#48d1cc","mediumvioletred":"#c71585","midnightblue":"#191970","mintcream":"#f5fffa","mistyrose":"#ffe4e1","moccasin":"#ffe4b5",
"navajowhite":"#ffdead","navy":"#000080",
"oldlace":"#fdf5e6","olive":"#808000","olivedrab":"#6b8e23","orange":"#ffa500","orangered":"#ff4500","orchid":"#da70d6",
"palegoldenrod":"#eee8aa","palegreen":"#98fb98","paleturquoise":"#afeeee","palevioletred":"#d87093","papayawhip":"#ffefd5","peachpuff":"#ffdab9","peru":"#cd853f","pink":"#ffc0cb","plum":"#dda0dd","powderblue":"#b0e0e6","purple":"#800080",
"red":"#ff0000","rosybrown":"#bc8f8f","royalblue":"#4169e1",
"saddlebrown":"#8b4513","salmon":"#fa8072","sandybrown":"#f4a460","seagreen":"#2e8b57","seashell":"#fff5ee","sienna":"#a0522d","silver":"#c0c0c0","skyblue":"#87ceeb","slateblue":"#6a5acd","slategray":"#708090","snow":"#fffafa","springgreen":"#00ff7f","steelblue":"#4682b4",
"tan":"#d2b48c","teal":"#008080","thistle":"#d8bfd8","tomato":"#ff6347","turquoise":"#40e0d0",
"violet":"#8F00FF",
"wheat":"#f5deb3","white":"#ffffff","whitesmoke":"#f5f5f5",
"yellow":"#ffff00","yellowgreen":"#9acd32"};
if (typeof colors[color.toLowerCase()] != 'undefined')
return colors[color.toLowerCase()];
return false;
}
Testing environment (with jQuery required):
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Color Test</title>
<script type="text/javascript" src="js/libs/jquery.js"></script>
<script type="text/javascript" src="js/color.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var i, j, colors = ['blue', 'orange', 'green', 'red', 'yellow', 'brown', 'violet'];
for(i = 0; i < colors.length; i++) {
for(j = 0; j < 3; j++) {
$("body").append('<div style="height: 20px; background-color: ' + generateSimilarColor(colors[i]) + ';"></div>');
}
$("body").append('<div style="height: 20px;"></div>');
}
});
</script>
</head>
<body></body>
</html>
Any bugs or suggestions - please write.