Reputation: 25259
i saw a lot of Js example but none fit my needs:
I'd like to have a script to generate colros, but if I use the common solution
color = '#'+Math.floor(Math.random()*16777215).toString(16);
it generates pastel colors, where I'd like better more saturated colors...or more ambitious, how can i select the palette form which i pick the colors?
how can I "restrict" the randomness?
Upvotes: 3
Views: 2974
Reputation: 104830
You can convert a color string value to hsl.
hsl is the easiest value to manipulate mathematically.
The first item in an hsl color triplet is the 'hue' of a circle, in degrees (0-360),
the second is the 'saturation' of the hue (0-100%), the last is 'lightness', (0-100%).
Any color with a lightness of 0 is black. If the lightness is 100 it is white.
You can rotate a color by changing the hue.
Changing the saturation or lightness makes a color richer, paler, lighter or darker.
(function(){
String.prototype.padZero= function(len, c){
var s= this, c= c || '0', len= len || 2;
while(s.length< len) s= c+ s;
return s;
}
window.Color= function(c){
if(!(this instanceof Color)) return new Color(c);
var h= Color.getHex(c);
if(h){
this.hex= h;
this.rgb= Color.hexToRgb(h);
this.hsl= Color.rgbToHsl(this.rgb);
this.isgray= this.hsl[1]=== 0;
}
}
var CC={
colornames:{
aqua:'#00ffff', black:'#000000', blue:'#0000ff', fuchsia:'#ff00ff',
gray:'#808080', green:'#008000', lime:'#00ff00', maroon:'#800000',
navy:'#000080', olive:'#808000', orange:'#ffa500', purple:'#800080',
red:'#ff0000', silver:'#c0c0c0', teal:'#008080', white:'#ffffff',
yellow:'#ffff00'
},
getHex: function(c){
if(c instanceof Color) return c.hex;
if(typeof c== 'string'){
c= c.toLowerCase();
if(/^#([a-f0-9]{3}){1,2}$/.test(c)){
if(c.length== 4){
return '#'+[c[1], c[1], c[2], c[2], c[3], c[3]].join('');
}
return c;
}
if (/^[a-z]+$/.test(c)) return Color.colornames[c];
if(c.indexOf('hsl')== 0) c= Color.hslToRgb(c);
else{
c= c.match(/\d+(\.\d+)?%?/g);
if(c){
c= c.map(function(itm){
if(itm.indexOf('%')!= -1){
return Math.round(parseFloat(itm)*2.55);
}
return parseInt(itm);
}).slice(0, 3);
}
}
}
if(c && c.length=== 3) return Color.rgbToHex(c);
},
hexToRgb: function(hex){
var c= '0x'+hex.substring(1);
return [(c>> 16)&255, (c>> 8)&255, c&255];
},
hslToRgb: function(hsl){
if(typeof hsl== 'string'){
hsl= hsl.match(/(\d+(\.\d+)?)/g);
}
var h= hsl[0]/360,
s= hsl[1]/100,
l= hsl[2]/100,
t1, t2, t3, rgb, val;
if(s== 0){
val= l*255;
return [val, val, val];
}
if(l < 0.5) t2= l*(1 + s);
else t2= l + s - l*s;
t1= 2*l - t2;
rgb= [0, 0, 0];
for(var i= 0; i < 3; i++){
t3= h + 1/3*-(i - 1);
t3 < 0 && t3++;
t3> 1 && t3--;
if(6*t3 < 1) val= t1 +(t2 - t1)*6*t3;
else if(2*t3 < 1) val= t2;
else if(3*t3 < 2) val= t1 +(t2 - t1)*(2/3 - t3)*6;
else val= t1;
rgb[i]= Math.round(val*255);
}
return rgb;
},
rgbToHex: function(rgb){
rgb= rgb.map(function(c){
c= (Math.round(+c).minmax(0, 255));
return c.toString(16).padZero(2);
});
return '#'+rgb.join('').toLowerCase();
},
rgbToHsl: function(c){
var r= c[0]/255, g= c[1]/255, b= c[2]/255,
min= Math.min(r, g, b), max= Math.max(r, g, b),
d= max - min, h, s, l;
if(max== min) h= 0;
else if(r== max) h= (g - b)/d;
else if(g== max) h= 2 +(b - r)/d;
else if(b== max) h= 4 +(r - g)/d;
h= Math.min(h*60, 360);
if(h < 0) h += 360;
l= (min + max)/2;
if(max== min) s= 0;
else if(l <= 0.5) s= d/(max + min);
else s= d/(2 - max - min);
return [Math.round(h), Math.round(s*100), Math.floor(l*100)];
}
}
var CP={
getName: function(){
var C= Color.colornames, hex= this.hex;
for(var p in C) if(C[p]=== hex) return p;
return '';
},
rotate: function(d){
if(typeof d!= 'number') d= 180;
var C= this.hsl.slice(0);
d+= C[0];
C[0]= Math.abs(d%360);
return Color(Color.hslToRgb(C));
},
shade: function(s, v){
var C= this.hsl.slice(0);
if(typeof s== 'number') C[1]= s.minmax(0, 100);
if(typeof v== 'number') C[2]= v.minmax(0, 100);
return Color(Color.hslToRgb(C));
},
toHsl: function(c){
c= c || this.hsl;
return 'hsl('+c[0]+','+c[1]+'%,'+c[2]+'%)';
},
toRgb: function(){
return 'rgb('+this.rgb.join(',')+')';
}
}
for(var p in CC) Color[p]= CC[p];
for(var p in CP) Color.prototype[p]= CP[p];
Color.prototype.toString= function(){
return this.hex;
}
})();
sample code-
var C= [], hue= Color('red');
while(C.length<6){
C.push((hue.getName() || hue.hex)+'='+hue.hsl);
hue= hue.rotate(60);
}
C.join('\n')
returns:
red=0,100,50
yellow=60,100,50
lime=120,100,50
aqua=180,100,50
blue=240,100,50
fuchsia=300,100,50
you can use other color string values- Color('rgb(255,0,0)'), or Color('#ff0000') or Color('hsl(0,100%,50%)');
Upvotes: 0
Reputation: 339975
For fully saturated colours use the HSL colour space with H from 0-360, S at (or slightly below) 100% and L at 50%.
If you know the browser has CSS3 support you may be able to use that directly. Failing that, use an HSL to RGB algorithm (20ish lines of code) readily available via Google to convert into hex format.
The formulae for conversion from HSL to RGB are also on the Wikipedia page on HSL and are easily translated into Javascript (and most other languages too!)
Upvotes: 5