1

I have the following code:

function get_random_color() {
    return '#' + Math.floor((Math.random() * 0xF00000) + 0x0FFFFF).toString(16);
}

for (var i=0; i<5; i++)
  {
      $(".colors").append("<div style='background:"+get_random_color()+"'></div>");
  }

HTML

<div class="colors"></div>

CSS

.colors > div{width:30px; height:30px;}

However the "random" generation seems to create an assortment of almost complementary colours:

enter image description here enter image description here enter image description here enter image description here enter image description here

Why isn't my code fully random and colours always seem to match?

Example:

http://jsfiddle.net/SaRT6/

Community
  • 1
  • 1
rickyduck
  • 4,030
  • 14
  • 58
  • 93
  • 1
    It seems that you need a random seed. See for example [here](http://stackoverflow.com/questions/424292/how-to-create-my-own-javascript-random-number-generator-that-i-can-also-set-the) and [here](http://stackoverflow.com/questions/521295/javascript-random-seeds) – Paolo Gibellini Sep 10 '13 at 15:01

2 Answers2

1

I wouldn't say that they matched exactly, but I get your drift!

I think this boils down to maths and probability, not that I'm an expert in that area, but if you think about it you have three ranges, and to end up with black for example you need all three of those random numbers to match at the extreme end of the range. That is less likely to happen than three non-matching numbers as you can imagine. You're much more likely to get numbers that sit within that range somewhere than numbers that that are at the very extremes. If you now look at a few common colours many of them will rely on one of those numbers being zero or near zero, or possibly the other end at 255. To get black you've got 1 in 16.5 million chance of getting it. Same for any of the greys.

So the solution? If you don't need too many colours, simply make an array of different 'nice' colours and pick them from that using a random index.

Darren Crabb
  • 570
  • 2
  • 10
  • Alternatively, use a different color model: HSB. Pick S and B at random and use this for all colors. Next, pick random H (hue) -- the colors will vary but their brightness will be the same. To get a spread of *similar* colors, pick a random starting H and then get your color values 'around' that (plus or minus a small value). – Jongware Sep 10 '13 at 15:30
1

Here is my suggestion using CSS3's HSL model. This uses a fixed Saturation and Lightness and varies Hue a bit -- you could also vary S and L the same way.

function get_random_color(H,S,L) {
  return 'hsl(' + ((H+Math.floor(Math.random() * 60))%360) + ','+S+'%,'+L+'%)' ;
}

randomS = Math.round(Math.random()*25)+75; // not too gray!
randomL = Math.round(Math.random()*20)+50-10; // not too light!
randomH = Math.floor(Math.random()*360);
for (var i=0; i<5; i++)
{
  $(".colors").append("<div style='background:"+get_random_color(randomH,randomS,randomL)+";'></div>");
}
Jongware
  • 22,200
  • 8
  • 54
  • 100
  • Unfortunately using that it generates even closer complementary colors. Trying it with the same random generator on S & L is the same issue. Can you explain a bit better please? – rickyduck Sep 10 '13 at 15:56
  • http://jsfiddle.net/SaRT6/4/ & http://jsfiddle.net/SaRT6/5/ & http://jsfiddle.net/SaRT6/6/ – rickyduck Sep 10 '13 at 15:57
  • Can you explain what you need: *similar* colors or *complimentary* colors? My routine creates *similar* colors; to make *complimentary* colors, you need an even spread around the 360 degrees of hue. Since you have 5 colors, try `(H+i*(360/5))%360`. – Jongware Sep 10 '13 at 16:17
  • Apologies, thought I made it clear in the question: `Why isn't my code fully random and colors always seem to match?` I need a suitably random set of colors. I appreciate that's near impossible but at the moment it's almost always close to complimentary for at least three. – rickyduck Sep 10 '13 at 16:23
  • Can you add a few palettes to your question that *are* close to what you have in mind? – Jongware Sep 10 '13 at 18:10