Sign up ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

As the title says the function is for creating random hex colors. Is there any better way to generate random hex colors?

function getRandomColor() {
    var chars = '0123456789ABCDEF'.split('');
    var hex = '#';
    for (var i = 0; i < 6; i++) {
        hex += chars[Math.floor(Math.random() * 16)];
    }
    return hex;
 }
share|improve this question

3 Answers 3

up vote 5 down vote accepted

Hex colors can be in 3 digits or 6 digits. In the case where you want 3 digits, you can't do it because 6 is hardcoded. You may want to move it into a variable with a default value of 6.

Strings characters in JS are accessible via indices the same way as an array. So splitting the characters into an array is unnecessary, not to mention the additional memory consumed by creating an array.

Adding | 0 after a number truncates the decimal places from the number. Internally, it converts the internal representation of the number from a float into an integer, dropping the decimal information. So basically, it does the same thing as Math.floor, albeit in a more vague but shorter way.

You could also use reverse looping, and using the length as the condition. When length is zero, it's essentially falsy, thus stopping the loop.

function getRandomColor() {
  var length = 6;
  var chars = '0123456789ABCDEF';
  var hex = '#';
  while(length--) hex += chars[(Math.random() * 16) | 0];
  return hex;
}

document.write(getRandomColor());

share|improve this answer
    
Works like a charm thx! – Patiphan Mahamat 22 hours ago
    
it's worth noting that any 3-digit hex color is also representable as a 6-digit hex-code, so unless you have a particular reason for wanting 3-digit colors, it's unimportant. (#ABC => #AABBCC.) – j6m8 12 hours ago
    
@j6m8 It's also worth noting that while it's unimportant, it's an option. Just because you can peel an apple doesn't mean you can't eat the skin. – Joseph the Dreamer 12 hours ago
    
For sure! Although, to be really nitpicky, if you have a random distribution of 6-digit codes and 3-digit codes, you'll double the probability of those three-digit-representable colors ;D – j6m8 8 hours ago

Edited: The first version was a little naive, and would sometimes return less than 6 digits. To ensure 6 digits, with leading zeroes, and allowing for pure white to be returned, we need to do some extra magic:

function getRandomColor() {
   max = 1 << 24;
   return '#' + (max + Math.floor(Math.random()*max)).toString(16).slice(-6);
}

// Lets generate some colors
document.write("<pre>");
for (i=0; i < 50; i++) {
   document.write(getRandomColor()+ "  ");
   if (i % 5 == 4) {
      document.write("<br />");
   }
}
document.write("</pre>");

First of all it adds the max, i.e. 0x1000000, to ensure leading zeroes, with the random number multiplied by max. This number is then converted into hexadecimal notation and we take the last six characters of this result. If you want only three digits, change the slice value. If extending for 24 bits, you'll also need to extend the max value approriately.

Edit hat tip to MarcDefiant: The code does now allow for pure white, 0xFFFFFF, and pads the returned number with leading zeroes.

share|improve this answer

You are discarding most of the random bits from the random numbers that you generated. All you need is a random integer between 0x000000 and 0xffffff, inclusive.

I would use a very similar solution to @holroy's. Also, I suggest dropping "get" from the function name, since it's generating rather than retrieving something.

function randomColor() {
    var color = Math.floor(0x1000000 * Math.random()).toString(16);
    return '#' + ('000000' + color).slice(-6);
}

Note that picking a color uniformly from the RGB color space might not be the best approach, depending on what you are using the color for. If you want to pick colors that are uniformly distributed according to human color perception, use the L-a-b color space instead, then convert the result to RGB.

share|improve this answer
    
nice solution. what's the reason you aren't just returning '#' + color? – Jonah 16 hours ago
1  
@Jonah Zero padding. – 200_success 16 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.