3

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?

Francesco
  • 24,839
  • 29
  • 105
  • 152
  • 3
    use HSL colors. 85+ saturation will do the trick ;) then just rotate the hue wheel. [similar question](http://stackoverflow.com/questions/1586147/how-to-generate-random-greenish-colors) – c69 Dec 12 '11 at 18:24
  • but that's in python... what about JS? – Francesco Dec 12 '11 at 18:34
  • 1
    `document.body.style.backgroundColor = 'hsl(' + Math.floor( 360 * Math.random() ) + ', 85%, 55%)';` – c69 Dec 12 '11 at 19:48

2 Answers2

5

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!)

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • If I had to google the question, what's the point to use stackoverflow.com? – Francesco Dec 12 '11 at 18:41
  • 1
    @FrancescoBertelli I didn't say to Google the question, I (effectively) said to Google "hsl to rgb javascript". Asking here got you the HSL hint, asking Google will get you the required code. – Alnitak Dec 12 '11 at 18:42
0

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%)');

kennebec
  • 102,654
  • 32
  • 106
  • 127