563

Given this function, I want to replace the color with a random color generator.

document.overlay = GPolyline.fromEncoded({
    color: "#0000FF",
    weight: 10,
    points: encoded_points,
    zoomFactor: 32,
    levels: encoded_levels,
    numLevels: 4
});

How can I do it?

Milan
  • 1,743
  • 2
  • 13
  • 36
n00ki3
  • 14,529
  • 18
  • 56
  • 65

65 Answers65

1241

Use getRandomColor() in place of "#0000FF":

function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}



function setRandomColor() {
  $("#colorpad").css("background-color", getRandomColor());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="colorpad" style="width:300px;height:300px;background-color:#000">

</div>
<button onclick="setRandomColor()">Random Color</button>
Paolo Forgia
  • 6,572
  • 8
  • 46
  • 58
Anatoliy
  • 29,485
  • 5
  • 46
  • 45
  • 105
    Note that this has a bias towards quite dark and unsaturated colors because of the way RGB wraps the color space. Martin Ankerl has a nice article about generating colors from other spaces (like HSV) as well: http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/ – Thomas Ahle Jan 10 '12 at 10:53
  • For anyone who is looking to limit the spectrum to light colors, you can set the letters to '789ABCD' and reduce the multiplier to letters[Math.round(Math.random() * 6)];. Just to note that I removed the low and high range just to avoid the extreme colors i.e. white and black. – KevinIsNowOnline Sep 12 '13 at 08:24
  • 5
    You could also use a [Generator Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator) as [such](https://jsfiddle.net/zafbbvvj/) – Taku Aug 26 '16 at 11:01
  • what is your suggestion if we want to generate colors only near to blue or red that we pass to this function as parameter like #FFF000 and your method generate color near to this. – saber tabatabaee yazdi Jan 16 '17 at 11:27
  • Impressive @Azarus. Could you explain? – WebWanderer Feb 18 '19 at 20:36
  • 4
    @WebWanderer Yep, there are 16777216 possible RGB color variations. Doing toString(16) will provide you a hexadecimal value. This is way faster and is more accurate way of producing color variations. Note the difference 16777215 and 16777216 . That is because we start to count at 0. So you have 16777216 different colors. but the maximum value is 16777215 – Playdome.io Feb 22 '19 at 14:05
  • 1
    @Azarus `Math.floor(Math.random() * 16777215)` is going to return a number in the range `[0, 16777214]` since `Math.random()` returns `[0, 1)`. Shouldn't you still be using `16777216` there? – sheng Mar 02 '19 at 17:43
  • @Sheng Oh you're right, i don't have a chance to edit my comment. – Playdome.io Mar 04 '19 at 03:13
  • 1
    @Azarus Just making sure I still have a single brain cell left (and documentation for the future Googler!). Regardless, super useful code. Thanks! – sheng Mar 04 '19 at 03:46
348

I doubt anything will be faster or shorter than this one:

"#" + ((1 << 24) * Math.random() | 0).toString(16).padStart(6, "0")

Challenge!

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
ZPiDER
  • 4,264
  • 1
  • 17
  • 17
  • 176
    `'#'+(Math.random()*0xFFFFFF<<0).toString(16);` – Mohsen May 06 '11 at 07:49
  • 36
    `('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6)` will always return a length of 6. though this method will still (rarely) return small numbers that give results like `000cf4` or `0000a7` which is a bit hacky i think. in these cases the red component does not contribute to the random color. – bryc Nov 27 '12 at 20:52
  • 3
    I copy-paste this for every other new page I prototype. Dozens of times now since 2011, I owe you a very sincere thanks! – Dom Vinyard Feb 02 '14 at 16:42
  • 2
    @bryc There are equally many random results like `4fc000` or `7a0000` where the blue is zero ;) – Niet the Dark Absol Apr 27 '16 at 15:31
  • @NiettheDarkAbsol yes, but the weight of the zero padding means zeroes show up more when the random number doesnt use up all the bits – bryc Feb 14 '17 at 05:59
  • 11
    `Math.random().toString(16).slice(-6)` shortest yet :) – bryc Feb 14 '17 at 06:16
  • 1
    challenge accepted: https://codegolf.stackexchange.com/questions/12563/random-css-color-code – phil294 Sep 13 '17 at 23:57
  • 7
    **Code comprehensible code.** `\`#${Math.floor(Math.random() * 0x1000000).toString(16).padStart(6, 0)}\`` – Константин Ван Nov 10 '17 at 22:11
  • 1
    Although not shorter, I find the following a lot more readable: `"#" + Math.floor(Math.random() * (1 << 3 * 8)).toString(16).padStart(6, "0")` – 3limin4t0r Sep 17 '20 at 13:30
  • @bryc No, the number of hexadecimal numbers from 0 to FFFF is the same as the number of hex numbers between 0 and FFFFFF where the last two digits (or the last 16 bits) are zero. – Joooeey Sep 19 '21 at 13:40
  • @Joooeey So you replied to a 10 year old comment saying "0-FFFFFF is the same 0-FFFF if you force the last digits to zero"? That isn't contradicting anything I said. The leading zeroes of that oneliner I posted introduces non-randomness whenever zero padding is necessary. Is that what you're trying to disprove? The second oneliner I posted in 2017 avoids this issue entirely because there's enough entropy to always have 6 digits. – bryc Sep 20 '21 at 00:57
  • @bryc No, the zero-padding doesn't make it any less random. The chance of selecting every number remains the same. In fact by disallowing numbers with fewer than 6 digits, you exclude numbers like `0000cf4` entirely. Also check out Niet's comment. – Joooeey Sep 20 '21 at 09:04
  • @Joooeey Apologies, I ran some tests and found both versions are equally likely to produce zeroes in red/green. so my assumption for it being less random was wrong. I simply assumed that because `(1<<24)*Math.random()|0).toString(16)` strips off many random bits and sometimes only returns 3-5 hex digits, that it was less random. – bryc Sep 22 '21 at 00:10
192

Here is another take on this problem.

My goal was to create vibrant and distinct colors. To ensure the colors are distinct I avoid using a random generator and select "evenly spaced" colors from the rainbow.

This is perfect for creating pop-out markers in Google Maps that have optimal "uniqueness" (that is, no two markers will have similar colors).

/**
 * @param numOfSteps: Total number steps to get color, means total colors
 * @param step: The step number, means the order of the color
 */
function rainbow(numOfSteps, step) {
    // This function generates vibrant, "evenly spaced" colours (i.e. no clustering). This is ideal for creating easily distinguishable vibrant markers in Google Maps and other apps.
    // Adam Cole, 2011-Sept-14
    // HSV to RBG adapted from: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
    var r, g, b;
    var h = step / numOfSteps;
    var i = ~~(h * 6);
    var f = h * 6 - i;
    var q = 1 - f;
    switch(i % 6){
        case 0: r = 1; g = f; b = 0; break;
        case 1: r = q; g = 1; b = 0; break;
        case 2: r = 0; g = 1; b = f; break;
        case 3: r = 0; g = q; b = 1; break;
        case 4: r = f; g = 0; b = 1; break;
        case 5: r = 1; g = 0; b = q; break;
    }
    var c = "#" + ("00" + (~ ~(r * 255)).toString(16)).slice(-2) + ("00" + (~ ~(g * 255)).toString(16)).slice(-2) + ("00" + (~ ~(b * 255)).toString(16)).slice(-2);
    return (c);
}

If you wish to see what this looks like in action see Simple JavaScript Rainbow Color Generator for Google Map Markers.

Duc Filan
  • 6,769
  • 3
  • 21
  • 26
Adam Cole
  • 1,921
  • 1
  • 11
  • 2
  • I've made a simplified implementation of the same idea as the answer to similar question http://stackoverflow.com/a/14187677/421010 – Andrew Jan 06 '13 at 22:54
  • Updated link: http://blog.adamcole.ca/2011/11/simple-javascript-rainbow-color.html – neuquen Nov 10 '13 at 01:48
  • 23
    So what will be parameter's value ? – Ekramul Hoque Apr 27 '15 at 12:02
  • 2
    I also created something like this, but it is quite random and quite distinct. The pseudo-code is [here](https://github.com/ralphembree/ColorGenerator/wiki). It uses hsv rather than rgb, because hsv has much more predictable behavior. If you care to see the Python implementation, I used it [here](https://github.com/ralphembree/py2048) and [here](https://github.com/ralphembree/SquareUp). You'll have to search through the code for "color". – zondo Feb 09 '16 at 22:03
  • @zondo your links are broken. – rmolinamir Feb 18 '19 at 00:01
  • 2
    @RobertMolina: Sorry, I moved my stuff to Gitlab. The pseudo-code is now [here](https://gitlab.com/snippets/1827384), with the projects [here](https://gitlab.com/ralphembree/py2048) and [here](https://gitlab.com/ralphembree/SquareUp). – zondo Feb 20 '19 at 16:40
  • @zondo don't worry! Was just letting you know, thanks for sharing once again. – rmolinamir Feb 20 '19 at 17:01
  • This is GOLD, wish I could upvote this more than once – Ayrton Aug 04 '19 at 13:29
  • 1
    How do I avoid bright colours ? – Thadeus Ajayi Mar 10 '22 at 03:23
69

Who can beat it?

'#' + Math.random().toString(16).substr(-6);

It is guaranteed to work all the time: http://jsbin.com/OjELIfo/2/edit

Based on eterps's comment, the code above can still generate shorter strings if the hexadecimal representation of the random color is very short (0.730224609375 => 0.baf).

This code should work in all cases:

function makeRandomColor(){
  var c = '';
  while (c.length < 7) {
    c += (Math.random()).toString(16).substr(-6).substr(-1)
  }
  return '#' + c;
}
bluenote10
  • 23,414
  • 14
  • 122
  • 178
Mohsen
  • 64,437
  • 34
  • 159
  • 186
  • 15
    When Math.random() returns 0.022092682472568126 this code produces invalid '#5a7dd' string. crazy! – Piotr Rochala Nov 05 '11 at 18:10
  • 1
    Like this one since #ffffff don't appear too often. – Warface Dec 01 '14 at 16:06
  • There are quite a few occurrences where this will not work. Check the following output for Math.random()... 0.730224609375, 0.43603515625, 0.957763671875, and the list goes on... – eterps Mar 27 '15 at 01:48
  • 1
    The short version: when Math.random returns `0.125` the result is `"#0.2"` (invalid) – Kamil Kiełczewski Mar 19 '19 at 11:09
  • 2
    Or even more basic: `0` is a valid return value of `Math.random` and `'#' + (0).toString(16).substr(-6)` is `"#0"`. If you don't mind I'd strike-though the _it is guaranteed to work all the time_ to avoid confusing others? – bluenote10 Jun 17 '21 at 08:18
60

You can also use HSL available on every good browser (http://caniuse.com/#feat=css3-colors)

function randomHsl() {
    return 'hsla(' + (Math.random() * 360) + ', 100%, 50%, 1)';
}

This will give you only bright colors, you can play around with the brightness, saturation and alpha.

// es6
const randomHsl = () => `hsla(${Math.random() * 360}, 100%, 50%, 1)`
devsaw
  • 1,007
  • 2
  • 14
  • 28
kigiri
  • 2,952
  • 21
  • 23
  • Thanks! I managed to get perfect colors for backgrounds with: ```'hsla(' + (Math.floor(Math.random()*360) + ', 100%, 70%, 1)'``` – Redoman Oct 28 '14 at 18:23
  • 1
    No prob, I was surprised to see no one using the power of hsl :) – kigiri Oct 29 '14 at 12:47
  • 1
    http://stackoverflow.com/a/23861752/1693593, hsla is not needed it alpha=1, just use hsl –  Jun 17 '15 at 07:10
  • in this way we can "generate" maximum 360 colors - it is not full RGB color space (16M colors) – Kamil Kiełczewski Mar 19 '19 at 11:25
  • I believe the degre is a float number and so can represent more than 360 colors event tough I can't really tell less than 1 degree differences. you can also randomize saturation and lightness if you want, even better, you can select the range of each parts for more coherents colors. – kigiri Mar 19 '19 at 12:30
  • 1
    You cannot generate 16M kolor this way (e.g. you will never get white-black grayscale) - however yes - if we use random to each component then we get all hsl corols – Kamil Kiełczewski Mar 21 '19 at 15:48
  • 4
    +1 This makes it easier to use lightness and saturation to set random background colors while ensuring that the text is always readable – Osvaldo Maria Aug 24 '19 at 11:46
35

There is no need for a hash of hexadecimal letters. JavaScript can do this by itself:

function get_random_color() {
  function c() {
    var hex = Math.floor(Math.random()*256).toString(16);
    return ("0"+String(hex)).substr(-2); // pad with zero
  }
  return "#"+c()+c()+c();
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alsciende
  • 26,583
  • 9
  • 51
  • 67
32

I like this one: '#' + (Math.random().toString(16) + "000000").substring(2,8)

Nicolas Buduroi
  • 3,565
  • 1
  • 28
  • 29
  • Or `'#' + Math.floor(Math.random()*16777215).toString(16);` – Mohammad Anini Jun 09 '15 at 07:55
  • @MohammadAnin that has a 1 in 16 chance of producing less than 6 digits – James Mar 24 '16 at 20:47
  • 1
    This might generate invalid colours. For example`'#' + (0.125).toString(16).substring(2, 8) === '#2'`. It is dangerous because the probability is low (1 in 4096 I think) so a bug is likely to get through testing. You should (`'#' + Math.random().toString(16) + "000000").substring(2, 8)` – James Mar 24 '16 at 20:55
  • 2
    Correction: should be `'#' + (Math.random().toString(16) + "000000").substring(2,8)` – James Mar 24 '16 at 21:06
31

The article written by Paul Irish, Random Hex Color Code Generator in JavaScript, is absolutely amazing. Use:

'#' + Math.floor(Math.random()*16777215).toString(16).padStart(6, '0');

Thanks to Haytam for sharing the padStart to solve the hexadecimal code length issue.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
way2vin
  • 2,411
  • 1
  • 20
  • 15
30

Random color generation with brightness control:

function getRandColor(brightness){

    // Six levels of brightness from 0 to 5, 0 being the darkest
    var rgb = [Math.random() * 256, Math.random() * 256, Math.random() * 256];
    var mix = [brightness*51, brightness*51, brightness*51]; //51 => 255/5
    var mixedrgb = [rgb[0] + mix[0], rgb[1] + mix[1], rgb[2] + mix[2]].map(function(x){ return Math.round(x/2.0)})
    return "rgb(" + mixedrgb.join(",") + ")";
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
letronje
  • 9,002
  • 9
  • 45
  • 53
  • 1
    Very cool, though mostly generates 'pastels' rather than more vibrant colors that I was hoping when I saw brightness. Still going into my bag of tricks! – JayCrossler Jun 25 '12 at 03:49
  • I really like this one because you can customize it to be in harmony with your website color palette – Emanuel Gianico May 15 '15 at 18:30
23

If you’re a noob like me, clueless about hexadecimals and such, this might be more intuitive.

function r() {
  return Math.floor(Math.random() * 256);
}

const color = "rgb(" + r() + "," + r() + "," + r() + ")";

You just need to end up with a string such as "rgb(255, 123, 220)".

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
ICoffeeConsumer
  • 882
  • 1
  • 8
  • 22
20
'#'+Math.random().toString(16).slice(-3) // three-numbers format aka #f3c
'#'+Math.random().toString(16).slice(-6) // six-number format aka #abc123
jt3k
  • 642
  • 6
  • 17
19

There are so many ways you can accomplish this. Here's some I did:

Short one-liner, guaranteed valid colors

'#'+(Math.random().toString(16)+'00000').slice(2,8)

Generates six random hex digits (0-F)

function randColor() {
    for (var i=0, col=''; i<6; i++) {
        col += (Math.random()*16|0).toString(16);
    }
    return '#'+col;
}

// ES6 one-liner version
[..."000000"].map(()=>Math.random().toString(16)[2]).join("")

Generates individual HEX components (00-FF)

function randColor2() {
    var r = ('0'+(Math.random()*256|0).toString(16)).slice(-2),
        g = ('0'+(Math.random()*256|0).toString(16)).slice(-2),
        b = ('0'+(Math.random()*256|0).toString(16)).slice(-2);
    return '#' +r+g+b;
}

Over-engineered hex string (XORs 3 outputs together to form color)

function randColor3() {
    var str = Math.random().toString(16) + Math.random().toString(16),
    sg = str.replace(/0./g,'').match(/.{1,6}/g),
    col = parseInt(sg[0], 16) ^ 
          parseInt(sg[1], 16) ^ 
          parseInt(sg[2], 16);
    return '#' + ("000000" + col.toString(16)).slice(-6);
}
bryc
  • 12,710
  • 6
  • 41
  • 61
  • 1
    extremley shor one-liner: when random returns `0.125` then result is `#0.2` (invalid color) – Kamil Kiełczewski Mar 19 '19 at 11:23
  • @KamilKiełczewski `0.125` = `3FC0000000000000` in IEEE hex. 3 hex digits are exponent, 13 are mantissa. There's a **1 in 4.5 quadrillion** chance that mantissa is completely empty like that. I tested 100m times in both Firefox/Chrome. You are just _trying_ to break it ;). `Math.random` should _never_ give you 0.125. And if it does, there is a problem with the PRNG, which is not my problem. Fractions like 0.5, 0.25, 0.0625 etc. are useless, they contain no randomness. Perhaps you have a solution to this extreme edge case, hm? ;) – bryc Mar 19 '19 at 16:02
  • yes `'#'+Math.random().toString(16).split('.')[1].slice(-6).padStart(6,0)` but I prefer [this](https://stackoverflow.com/a/55235032/860099) – Kamil Kiełczewski Mar 19 '19 at 21:48
  • 1
    Can you prove that `Math.random()` never gives such numbers (which in hex representation have less digits than 6 after dot) ? Can you explain what do you mean that 0.5 is less random that any other number? You say It is not your problem - yes, you are right - the problem have programmes which use your code unless you can provide proof (however in that case this will mean that there is something wrong with Math.random() because it exclude some 'special' numbers...) – Kamil Kiełczewski Jun 18 '20 at 10:07
  • @KamilKiełczewski can you prove it _does_? feel free to run some tests. You manually cherry pick 0.125; I can cherry pick numbers too. 0.4999961853027344 will produce `#.7fffc`. You can easily manipulate mantissa and exponent to find these. My previous estimate "1 in 4.5 quadrillion" likely is wrong. However I am confident the probability of encountering these invalid outputs are **extremely unlikely and not a concern**. For these issues to happen, all 34 lower mantissa bits must be 0, thus the raw random u64 int must resemble `0x3FEFFFFC00000000`. If any bit there is set, bug **wont** occur. – bryc Jun 18 '20 at 13:00
  • @KamilKiełczewski I already tested this a year ago, but here is an improved test code: https://paste2.org/51Ftg7Lt. 100m iterations each run. I have generated maybe a billion colors by now, and this issue has not occurred even once. – bryc Jun 18 '20 at 13:34
  • When I test it manually it occur and generate invalid color - this is reason why I report it (and made more deep investigation) – Kamil Kiełczewski Jun 18 '20 at 13:37
  • @KamilKiełczewski testing `0.5, 0.25, 0.125` manually isn't very useful - those are very rare if possible. Only real statistical testing matters. Anyway: After testing 20 billion times, there are TEN invalids found. So it is closer to **roughly** ≈ 1 in 2 billion chance of failure. Much worse than previous estimate. Here are the values: 0.1769733428955078, 0.4149589538574219, 0.49722862243652344, 0.7051858901977539, 0.3124990463256836, 0.09694671630859375, 0.8300838470458984, 0.9915647506713867, 0.7658090591430664, 0.12326622009277344. Both Firefox and Chrome affected. – bryc Jun 18 '20 at 15:29
  • no no - I run Math.random() and get such "bad" value - "I run this code manualy" means: not in loop – Kamil Kiełczewski Jun 18 '20 at 15:46
  • You forgot about this 0.17698287963867188 and this 0.17698383331298828 and that 0.1769847869873047 .... (and much more) ? – Kamil Kiełczewski Jun 18 '20 at 16:03
  • 1
    I see you fix it - even shorter than I in [this comment](https://stackoverflow.com/questions/1484506/random-color-generator?page=1&tab=votes#comment97233506_13594375) +1 – Kamil Kiełczewski Jun 20 '20 at 21:52
19

Use:

function random_color(format)
{
    var rint = Math.round(0xffffff * Math.random());
    switch(format)
    {
        case 'hex':
            return ('#0' + rint.toString(16)).replace(/^#0([0-9a-f]{6})$/i, '#$1');
            break;

        case 'rgb':
            return 'rgb(' + (rint >> 16) + ',' + (rint >> 8 & 255) + ',' + (rint & 255) + ')';
            break;

        default:
            return rint;
            break;
    }
}

Updated version:

function random_color( format ){
  var rint = Math.floor( 0x100000000 * Math.random());
  switch( format ){
    case 'hex':
      return '#' + ('00000'   + rint.toString(16)).slice(-6).toUpperCase();
    case 'hexa':
      return '#' + ('0000000' + rint.toString(16)).slice(-8).toUpperCase();
    case 'rgb':
      return 'rgb('  + (rint & 255) + ',' + (rint >> 8 & 255) + ',' + (rint >> 16 & 255) + ')';
    case 'rgba':
      return 'rgba(' + (rint & 255) + ',' + (rint >> 8 & 255) + ',' + (rint >> 16 & 255) + ',' + (rint >> 24 & 255)/255 + ')';
    default:
      return rint;
  }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Funky Dude
  • 3,867
  • 2
  • 23
  • 33
18

Here's a twist on the solution provided by @Anatoliy.

I needed to generate only light colours (for backgrounds), so I went with three letter (#AAA) format:

function get_random_color() {
    var letters = 'ABCDE'.split('');
    var color = '#';
    for (var i=0; i<3; i++ ) {
        color += letters[Math.floor(Math.random() * letters.length)];
    }
    return color;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andrei R
  • 4,904
  • 5
  • 25
  • 26
  • I think this is likely to produce most often colors that are closely similar although light. For a more Sparse range of random colors, I think @Anatoli's response is better for the most part – Akah Aug 28 '19 at 20:40
18

map

always returns a valid RGB color:

`rgb(${[1,2,3].map(x=>Math.random()*256|0)})`

let c= `rgb(${[1,2,3].map(x=>Math.random()*256|0)})`

console.log(c);
document.body.style.background=c
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
12

The top voted comment of the top answer suggests that Martin Ankerl's approach is better than random hex numbers, and although I haven't improved on Ankerl's methodology, I have successfully translated it to JavaScript.

I figured I'd post an additional answer to this already mega-sized Stack Overflow question because the top answer has another comment linking to a Gist with the JavaScript implementation of Ankerl's logic and that link is broken (404). If I had the reputation, I would have simply commented the jsbin link I created.

// Adapted from
// http://jsfiddle.net/Mottie/xcqpF/1/light/
const rgb2hex = (rgb) => {
  return (rgb && rgb.length === 3) ? "#" +
    ("0" + parseInt(rgb[0],10).toString(16)).slice(-2) +
    ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
    ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) : '';
}

// The next two methods are converted from Ruby to JavaScript.
// It is sourced from http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/

// # HSV values in [0..1[
// # returns [r, g, b] values from 0 to 255
const hsv_to_rgb = (h, s, v) => {
  const h_i = Math.floor(h*6)
  const f = h*6 - h_i
  const p = v * (1 - s)
  const q = v * (1 - (f * s))
  const t = v * (1 - (1 - f) * s)
  let r, g, b
  switch(h_i) {
    case(0):
      [r, g, b] = [v, t, p]
      break
    case(1):
      [r, g, b] = [q, v, p]
      break
    case(2):
      [r, g, b] = [p, v, t]
      break
    case(3):
      [r, g, b] = [p, q, v]
      break
    case(4):
      [r, g, b] = [t, p, v]
      break
    case(5):
      [r, g, b] = [v, p, q]
      break
  }
  return [Math.floor(r * 256), Math.floor(g * 256), Math.floor(b * 256)]
}

// # Use the golden ratio
const golden_ratio_conjugate = 0.618033988749895
let h = Math.random() // # Use a random start value
const gen_hex = (numberOfColors) => {
  const colorArray = []
  while (numberOfColors > 0) {
    h += golden_ratio_conjugate
    h %= 1
    colorArray.push(rgb2hex(hsv_to_rgb(h, 0.99, 0.99)))
    numberOfColors -= 1
  }
  console.log(colorArray)
  return colorArray
}

gen_hex(100)

https://jsbin.com/qeyevoj/edit?js,console

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
spakmad
  • 880
  • 6
  • 15
  • 1
    Thanks. I needed it, and you took the trouble to convert Martin's article. (Of course, Martin's suggested parameters were (h, 0.5, 0.95), which produces a better color). I searched a lot and did not find any nodejs package for be like this. I think it's worth becoming an npm package. In this regard, if you need help, you can count on me. – Nabi K.A.Z. May 02 '22 at 22:20
12

regexp

always returns a valid hex 6-digit color

"#xxxxxx".replace(/x/g, y=>(Math.random()*16|0).toString(16))

let c= "#xxxxxx".replace(/x/g, y=>(Math.random()*16|0).toString(16));
       
console.log(c);
document.body.style.background=c
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
11
var color = "#";
for (k = 0; k < 3; k++) {
    color += ("0" + (Math.random()*256|0).toString(16)).substr(-2);
}

A breakdown of how this works:

Math.random()*256 gets a random (floating point) number from 0 to 256 (0 to 255 inclusive)
Example result: 116.15200161933899

Adding the |0 strips off everything after the decimal point.
Ex: 116.15200161933899 -> 116

Using .toString(16) converts this number to hexadecimal (base 16).
Ex: 116 -> 74
Another ex: 228 -> e4

Adding "0" pads it with a zero. This will be important when we get the substring, since our final result must have two characters for each color.
Ex: 74 -> 074
Another ex: 8 -> 08

.substr(-2) gets just the last two characters.
Ex: 074 -> 74
Another ex: 08 -> 08 (if we hadn't added the "0", this would have produced "8" instead of "08")

The for loop runs this loop three times, adding each result to the color string, producing something like this:
#7408e4

Erin Heyming
  • 1,521
  • 1
  • 13
  • 12
11

A short answer with padding to the exact size:

'#' + ((1<<24)*(Math.random()+1)|0).toString(16).substr(1)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Taha Jahangir
  • 4,774
  • 2
  • 42
  • 49
10

So whilst all the answers here are good I wanted a bit more control over the output. For instance I'd like to prevent any near white shades, whilst ensuring I get bright vibrant colours not washed out shades.

function generateColor(ranges) {
            if (!ranges) {
                ranges = [
                    [150,256],
                    [0, 190],
                    [0, 30]
                ];
            }
            var g = function() {
                //select random range and remove
                var range = ranges.splice(Math.floor(Math.random()*ranges.length), 1)[0];
                //pick a random number from within the range
                return Math.floor(Math.random() * (range[1] - range[0])) + range[0];
            }
            return "rgb(" + g() + "," + g() + "," + g() +")";
        };

So now I can specify 3 arbitrary ranges to pick rgb values from. You can call it with no arguments and get my default set which will usually generate a quite vibrant colour with once obvious dominant shade, or you can supply your own array of ranges.

Ollie Edwards
  • 14,042
  • 7
  • 28
  • 36
  • 1
    Google Map API supports only hexadecimal HTML color in the "#FFFFFF" format. – Valery Viktorovsky Jul 02 '10 at 14:34
  • Sure, pretty straightforward to convert a number to hex n.toString(16) only snag is you'll need to zero pad to make sure you get a two character return value from the inner g function. – Ollie Edwards Jul 09 '10 at 10:57
8

For decent randomness.

Random color

`#${crypto.getRandomValues(new Uint32Array(1))[0].toString(16).padStart(8, 0).slice(-6)}`

Random alpha, random color.

`#${crypto.getRandomValues(new Uint32Array(1))[0].toString(16).padStart(8, 0)}`
7

You could use this simple function

function getRandomColor(){
 var color =  "#" + (Math.random() * 0xFFFFFF << 0).toString(16);
 return color;
}
ChandrasekarG
  • 1,384
  • 13
  • 24
6

Array.prototype.reduce makes it very clean.

["r", "g", "b"].reduce(function(res) {
    return res + ("0" + ~~(Math.random()*256).toString(16)).slice(-2)
}, "#")

It needs a shim for old browsers.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
6

Use distinct-colors.

It generates a palette of visually distinct colors.

distinct-colors is highly configurable:

  • Choose how many colors are in the palette
  • Restrict the hue to a specific range
  • Restrict the chroma (saturation) to a specific range
  • Restrict the lightness to a specific range
  • Configure general quality of the palette
InternalFX
  • 1,475
  • 12
  • 14
  • 3541 lines of code..where other answers here are ~6-10 lines...i'm impressed how did somebody wrote so many lines of code just to pick distinct colors.. – vsync Feb 10 '16 at 17:25
  • Picking truly *visually* distinct colors requires a lot more math than just a random color generator. – InternalFX Feb 10 '16 at 17:38
  • I just did it in 2 lines.. modified this function: http://stackoverflow.com/a/20129594/104380 – vsync Feb 10 '16 at 17:39
  • It's not that simple. [suggested reading](http://tools.medialab.sciences-po.fr/iwanthue/theory.php) – InternalFX Feb 10 '16 at 17:42
  • Thanks, very interesting article. my method always provides the same colors, and results are consistent and distinctive. I guess in some situations you might need really random, well distributed colors which are pretty to the human eye. – vsync Feb 10 '16 at 18:03
  • That's actually what I was after personally...I wanted to provide *pretty* charts for my users. That's where this method really shines, most don't need/want so much. – InternalFX Feb 11 '16 at 18:24
6

I wanted to create very distinctive and vibrant colors (for graphing). For anything serious, hsl is a better method than rgb. If necessary, you can convert hsl to rgb as already mentioned by others.

Simple way:

  • Create a random Hue from 0 to 360
  • Create a random Saturation from 0.5 to 1 (or 50 to 100) for vividness
  • Fix Lightness to 50% for best visibility.
color_generator = () => hsl (360*Math.random(), 0.5 + Math.random()/2, 0.5)

modified way

It creates a very nice spectrum of bright and vivid colors but the problem is that in usual color spectrum red, green, blue shades are way more dominant than yellow, cyan, and purple. So, I transformed the hue through acos function. The technical reason is very boring, so I skip it but you can dig in wiki.

color_generator = () => {
    let color_section = Math.floor(Math.random()/0.33) // there are three section in full spectrum
    let transformed_hue = Math.acos(2*Math.random() - 1)/3.14 // transform so secondary colors would be as dominant as the primary colors
    let hue = 120*color_section + 120*transformed_hue
    return hsl(hue, 0.5 + Math.random()/2, 0.5)
}

The result is the best color spectrum I had after experimenting with many other methods.

References:

Ali Khosro
  • 1,580
  • 18
  • 25
6

Yet another random color generator:

var randomColor;
randomColor = Math.random() * 0x1000000; // 0 < randomColor < 0x1000000 (randomColor is a float)
randomColor = Math.floor(randomColor); // 0 < randomColor <= 0xFFFFFF (randomColor is an integer)
randomColor = randomColor.toString(16); // hex representation randomColor
randomColor = ("000000" + randomColor).slice(-6); // leading zeros added
randomColor = "#" + randomColor; // # added
Salman A
  • 262,204
  • 82
  • 430
  • 521
4
function get_random_color() {
    return "#" + (Math.round(Math.random() * 0XFFFFFF)).toString(16);
}

http://jsfiddle.net/XmqDz/1/

4

This function goes above and beyond other answers in two ways:

It attempts to generate colors as distinct as possible by finding which color out of 20 tries has the farthest Euclidean distance from the others in the HSV cone.

It allows you to restrict the hue, saturation, or value range, but it still attempts to pick colors as distinct as possible within that range.

It's not super efficient, but for reasonable values (who could even pick apart 100 colors easily?) It's fast enough.

See JSFiddle

  /**
   * Generates a random palette of HSV colors.  Attempts to pick colors
   * that are as distinct as possible within the desired HSV range.
   *
   * @param {number}    [options.numColors=10] - the number of colors to generate
   * @param {number[]}  [options.hRange=[0,1]] - the maximum range for generated hue
   * @param {number[]}  [options.sRange=[0,1]] - the maximum range for generated saturation
   * @param {number[]}  [options.vRange=[0,1]] - the maximum range for generated value
   * @param {number[][]}[options.exclude=[[0,0,0],[0,0,1]]] - colors to exclude
   *
   * @returns {number[][]} an array of HSV colors (each HSV color
   * is a [hue, saturation, value] array)
   */
  function randomHSVPalette(options) {
    function random(min, max) {
      return min + Math.random() * (max - min);
    }

    function HSVtoXYZ(hsv) {
      var h = hsv[0];
      var s = hsv[1];
      var v = hsv[2];
      var angle = h * Math.PI * 2;
      return [Math.sin(angle) * s * v,
              Math.cos(angle) * s * v,
              v];
    }

    function distSq(a, b) {
      var dx = a[0] - b[0];
      var dy = a[1] - b[1];
      var dz = a[2] - b[2];
      return dx * dx + dy * dy + dz * dz;
    }

    if (!options) {
      options = {};
    }

    var numColors = options.numColors || 10;
    var hRange = options.hRange || [0, 1];
    var sRange = options.sRange || [0, 1];
    var vRange = options.vRange || [0, 1];
    var exclude = options.exclude || [[0, 0, 0], [0, 0, 1]];

    var points = exclude.map(HSVtoXYZ);
    var result = [];

    while (result.length < numColors) {
      var bestHSV;
      var bestXYZ;
      var bestDist = 0;
      for (var i = 0; i < 20; i++) {
        var hsv = [random(hRange[0], hRange[1]), random(sRange[0], sRange[1]), random(vRange[0], vRange[1])];
        var xyz = HSVtoXYZ(hsv);
        var minDist = 10;
        points.forEach(function(point) {
          minDist = Math.min(minDist, distSq(xyz, point));
        });
        if (minDist > bestDist) {
          bestHSV = hsv;
          bestXYZ = xyz;
          bestDist = minDist;
        }
      }
      points.push(bestXYZ);
      result.push(bestHSV);
    }

    return result;
  }

  function HSVtoRGB(hsv) {
    var h = hsv[0];
    var s = hsv[1];
    var v = hsv[2];

    var i = ~~(h * 6);
    var f = h * 6 - i;
    var p = v * (1 - s);
    var q = v * (1 - f * s);
    var t = v * (1 - (1 - f) * s);
    v = ~~(255 * v);
    p = ~~(255 * p);
    q = ~~(255 * q);
    t = ~~(255 * t);
    switch (i % 6) {
      case 0: return [v, t, p];
      case 1: return [q, v, p];
      case 2: return [p, v, t];
      case 3: return [p, q, v];
      case 4: return [t, p, v];
      case 5: return [v, p, q];
    }
  }

  function RGBtoCSS(rgb) {
    var r = rgb[0];
    var g = rgb[1];
    var b = rgb[2];
    var rgb = (r << 16) + (g << 8) + b;
    return '#' + ('000000' + rgb.toString(16)).slice(-6);
  }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Andy
  • 7,885
  • 5
  • 55
  • 61
3

My version:

function RandomColor() {
  var hex = (Math.round(Math.random()*0xffffff)).toString(16);
  while (hex.length < 6) hex = "0" + hex;
  return hex;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Prostakov
  • 910
  • 1
  • 12
  • 22
  • I think the not-random `0` makes the color not `random` enough XD – shrekuu May 22 '15 at 04:00
  • 1
    We randonly generate a hexadecinal number from `0` to `ffffff`. Which is a perfect [uniform distribution](http://en.wikipedia.org/wiki/Uniform_distribution_(continuous)). That zero is only to complete string, because of browser usage considerations. I suggest you look more careful at this solution. – Prostakov May 22 '15 at 19:40
  • I did make a few adjustments though, not linked to your comment :) – Prostakov May 22 '15 at 19:42
3

A bit enhanced one-liner to make the approach more vivid

'#' + Math.round((0x1000000 + 0xffffff * Math.random())).toString(16).slice(1)
alexmagnus
  • 976
  • 5
  • 7
3

You should use '#'+Math.floor(Math.random()*16777215).toString(16); for a random color code.

Your thinking, but why 16777215? Check this article: Generate a random color with a single line of JavaScript code

function generateRandomColor()
{
    var randomColor = '#'+Math.floor(Math.random()*16777215).toString(16);
    if(randomColor.length != 7){ // In any case, the color code is invalid
        randomColor = generateRandomColor();
    }
    return randomColor;
    // The random color will be freshly served
}
document.body.style.backgroundColor = generateRandomColor() // -> #E1AC94
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ravi Makwana
  • 2,782
  • 1
  • 29
  • 41
3

To have the same "random" colors each run instead of using Math.random you can use, for example, Mulberry32 algorithm.

Here is the demo that prints lines with a random color with using mulberry32 which uses the seed value from the input element.

To get a random color value I use a HLS "generator". Which in additional to the random "H" (hue) value (360 colors total) uses the random "L" (lightness) value (from "40 %" to "60 %"). Also each next "H" value is differ at least by 10 to prevent too similar adjacent colors.

function hlsGen(seed) {
  if (isNaN(seed)) {
    seed = 0;
  }
  const random = mulberry32(seed);
  
  let preH = 0; 
  function getH() {
    while (true) {
      const newH = random() * 360;
      if (Math.abs(preH - newH) > 10) {
        preH = newH;
        return newH;
      }
    }
  }
  
  return function() {
    const H = getH();    
    const L = (40 + random() * 20) + "%";
    return `hsl(${H}, 100%, ${L})`;
  };
}

function mulberry32(seed = Date.now()) {
  return function() {
    let x = seed += 0x6D2B79F5;
    x = Math.imul(x ^ x >>> 15, x | 1);
    x ^= x + Math.imul(x ^ x >>> 7, x | 61);
    return ((x ^ x >>> 14) >>> 0) / 4294967296;
  }
}

// --- The example code ---
const input = document.createElement("input");
document.body.append(input);
input.addEventListener("input", () => {
  const seed = Number(input.value);  
  const nextHls = hlsGen(seed);
  document.querySelectorAll("div").forEach(div => div.remove());  
  for (let i = 0; i < 20; i++) {
    const style = `border-left: 10px solid ${nextHls()};`;
    document.body.insertAdjacentHTML("beforeend", `<div style="${style}">${i}</div>`);
  }
});
input.value = 100;
input.dispatchEvent(new Event("input"));
KeyKi
  • 2,693
  • 3
  • 12
  • 24
3

Almost all of the previous short hand methods are generating invalid hex codes (five digits). I came across a similar technique only without that issue here:

"#"+(((1+Math.random())*(1<<24)|0).toString(16)).substr(-6)

Test

Try this in the console:

for(i = 0; i < 200; i++) {
    console.log("#"+(((1+Math.random())*(1<<24)|0).toString(16)).substr(-6));
}
bryc
  • 12,710
  • 6
  • 41
  • 61
manikanta
  • 8,100
  • 5
  • 59
  • 66
  • 5
    I made a for-loop that ran this code 20000 times and only printed to the console if the length was less than 7, and I did find a case where the string was less than 6 characters. Also, one problem with this code is that it only pads the entire 6-digit string, not the individual 2-digit color codes, which means you're more likely to have zeroes in the red value than in the green or blue values. – Erin Heyming Mar 26 '13 at 03:46
  • when random returns `0.00001` the result is `"#000a7"` (invalid color - 5 digits) – Kamil Kiełczewski Mar 19 '19 at 11:33
2

Just because I can, I created an unreadable snippet that randomizes between min and max hex codes...:

function a(f, s){
    if(!s || !s.length > 1) return "";
    var c = Math.floor(Math.random()*(parseInt("0x" + s.substr(0,2))-parseInt("0x" +     f.substr(0,2))+1)+parseInt("0x" + f.substr(0,2))).toString(16);
    return  (Array(3 - c.length).join("0")) + c + a(f.substr(2,f.length),s.substr(2,s.length));
}

a("990099","ff00ff") → might randomize → b5009e

It does it in pairs, so a("12","f2") → might randomize → 8f. But it won't go above 'f2'.

var color = "#" + a("11","22") + a("33","44") + a("55","66");

It is the same as:

var color = "#" + a("113355","224466")

But slower.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
zenril
  • 300
  • 2
  • 8
2

You can use colorchain.js to generate a sequence of colors with varying hues.

alexishacks
  • 233
  • 3
  • 10
2

This code (Mohsen's) can't generate colors like #fcfc80.

'#' + Math.random().toString(16).substr(-6);

Nicolas Buduroi's one works unless Math.random() returns 0, reasonable.

'#' + (Math.random().toString(16) + "000000").substring(2,8)

This code generates lots of illegal colors (like #abcde).

'#' + Math.floor(Math.random()*16777215).toString(16);

And I keep using (+1 or anthing is also fine, but I'm used to +2 for no reason)

"#" + ((Math.random()+2)*16777216|0).toString(16).slice(1)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
l4m2
  • 1,157
  • 5
  • 17
  • Why is #008a80 not possible in that code? And why use +2 instead of +1 in your code? Thanks. – bryc Jun 19 '20 at 16:03
  • @bryc Seems 008a80 is possible `+2` is just I usually do, `+1` is also fine – l4m2 Jun 20 '20 at 09:38
  • Thanks. Also returning 0.0 is probably [extremely unlikely](https://en.wikipedia.org/wiki/IEEE_754-1985#Zero) if not practically impossible. The raw exponent bits in IEE754 must be 0, but are almost always hex `0x3FF` to `0x3E0`. – bryc Jun 20 '20 at 19:12
2

Here are my two versions for a random hex code generator.


/* Slowest but shortest. */
"#000000".replace(/0/g,function(){return (~~(Math.random()*16)).toString(16);});    

/* Good performance with small size. */
"#"+(function(a,b){while(a--){b+=""+(~~(Math.random()*16)).toString(16);} return b;})(6,"");

/* Remy Sharp provided one that's the fastest but a little bit too long */
(function(h){return '#000000'.substr(0,7-h.length)+h})((~~(Math.random()*(1<<24))).toString(16))

Larry Battle
  • 9,008
  • 4
  • 41
  • 55
2

Using ES6's Array.from() method, I created this solution:

function randomColor() {
  return "#"+ Array.from({length: 6},()=> Math.floor(Math.random()*16).toString(16)).join("");
}

The other implementations I've seen need to ensure that if the hexadecimal value has leading zeros, the number still contains six digits.

K._'s answer used ES6's padStart for this:

function randomColor() {
  return `#${Math.floor(Math.random() * 0x1000000).toString(16).padStart(6, 0)}`
}

The other good single-line solution I've seen is

function randomColor() {
  return '#'+ ('000000' + (Math.random()*0xFFFFFF<<0).toString(16)).slice(-6);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alexander Rice
  • 160
  • 1
  • 5
2

There is no need to use JavaScript to generate a random CSS color.

For example, in SCSS/Sass you can use something like this:

.rgb-color-selector {
    background-color: rgb(random(255), random(255), random(255));
}

or

.hsl-color-selector {
    color: hsl(random(360) * 1deg, floor(random() * 100%), floor(random() * 100%));;
}

CodePen sample.

Ferie
  • 1,358
  • 21
  • 36
  • 'no need' - unless you want to save the color. I'm trying to generate a random starter color for the user, they can keep that, or choose another. So the string is easier for me. But this is also cool! – nycynik Jul 16 '21 at 19:32
  • 1
    @nycynik the original post was not asking to "save" the colour just generate a random colour ;P In any case you can generate the colour and cache it in a SCSS variable and reuse that variable in multiple places. – Ferie Jul 19 '21 at 09:44
2

This one generates only saturated colors

let randomSaturatedColor = () => {
    let r = Math.random().toString(16).slice(2, 4)
    let value_012345 = Math.random().toString(6).slice(2, 3)
    let hex = {
        [0]: `${r}00FF`,
        [1]: `00${r}FF`,
        [2]: `00FF${r}`,
        [3]: `${r}FF00`,
        [4]: `FF${r}00`,
        [5]: `FF00${r}`,
    }[value_012345]
    return '#' + hex
}
Mathieu CAROFF
  • 1,230
  • 13
  • 19
2

There are a variety of methods for creating random hex color codes in the blog post Random hex color code generator in JavaScript. You need to pad with zeros when the random value is less than 0×100000, so here's the correct version:

var randomColor = "#000000".replace(/0/g,function(){return (~~(Math.random()*16)).toString(16);});

That replaces each of six 0s with a random hex digit, so it's sure to end up with a full six-digit valid color value.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
1

I think the first response is the most succinct/useful, but I just wrote one that would probably be easier for a beginner to understand.

function randomHexColor(){
    var hexColor=[]; //new Array()
    hexColor[0] = "#"; //first value of array needs to be hash tag for hex color val, could also prepend this later

    for (i = 1; i < 7; i++)
    {
        var x = Math.floor((Math.random()*16)); //Tricky: Hex has 16 numbers, but 0 is one of them

        if (x >=10 && x <= 15) //hex:0123456789ABCDEF, this takes care of last 6 
        {
            switch(x)
            {
                case 10: x="a" 
                break;
                case 11: x="b" 
                break;
                case 12: x="c" 
                break;
                case 13: x="d" 
                break;
                case 14: x="e" 
                break;
                case 15: x="f" 
                break;  
            }
        }
        hexColor[i] = x;
    }
    var cString = hexColor.join(""); //this argument for join method ensures there will be no separation with a comma
    return cString;
}
mv.danj
  • 11
  • 2
1

You can try this. It's an absolutely random and comfortable color generator ))

var Color = '#';
var myElement;
for (var i = 0; i < 6; i++) {
    function Random1(from, to) {
      return Math.floor((Math.random() * (70 - 65 + 1)) + 65);
}
    function Random2(from, to) {
      return Math.floor((Math.random() * (1 - 0 + 1)) + 0);
}
    function Random3(from, to) {
      return Math.floor((Math.random() * (9 - 0 + 1)) + 0);
}
if (Random2()) {
     myElement = Random3();
}
else {
     myElement = String.fromCharCode(Random1());
}
Color += myElement;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Duke
  • 29
  • 10
1
function getRandomColor()
{
    var color = "#";

    for (var i = 0; i < 3; i++)
    {
        var part = Math.round(Math.random() * 255).toString(16);

        color += (part.length > 1) ? part : "0" + part;
    }

    return color;
}
Chunky Chunk
  • 16,553
  • 15
  • 84
  • 162
1

This method will get a random number, convert it to a hexidecimal string and then extract a part of it, giving you a random hex.

function randomColor() {
    return "#" + Math.random().toString(16).slice(2,8);
}
GMchris
  • 5,439
  • 4
  • 22
  • 40
  • 1
    Hi Anish, thanks for your answer, however answers on SO should explain _why_ or _how_ a piece of code answers the question, rather than just pasting a block of code. Please see [How do I write a good answer?](http://stackoverflow.com/help/how-to-answer) – Tim Malone May 26 '16 at 23:06
  • 2
    if Math.random() returns 0.125 the result is `"#2"` (invalid color) – Kamil Kiełczewski Mar 19 '19 at 11:36
1

Many answers make more calls than necessary to Math.random(). Or they hope that the hex representation of that number, will have six characters.

First multiply the random float to be in the range [0, 0xffffff + 1). Now our number has the form 0xRRRRRR and some change, which is a number with 24 significant bits. Read off four bits at a time, and use that random number [0, 15] and convert it to its matching hexadecimal character in lookup.

function randomColor() {
    var lookup = "0123456789abcdef";
    var seed = Math.random() * 0x1000000;
    return (
        "#" +
        lookup[(seed & 0xf00000) >> 20] +
        lookup[(seed & 0x0f0000) >> 16] +
        lookup[(seed & 0x00f000) >> 12] +
        lookup[(seed & 0x000f00) >> 8] +
        lookup[(seed & 0x0000f0) >> 4] +
        lookup[seed & 0x00000f]
    );
};
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
cdosborn
  • 3,111
  • 29
  • 30
  • if you already random number with 6 digit of hexadecimal why not use it and done ? – pery mimon May 07 '18 at 11:32
  • @perymimon what do you mean by "use it". The whole point is to convert a number to a string. If you just use it, it wouldn't be a string. If you use Number.toString(16), then you're not guaranteed a string with 6 digits, if the number is random. – cdosborn May 07 '18 at 21:58
  • Updated the answer to remove the criticism of answers which were padding with zeroes. Padding doesn't bias the colors, or make them in any way less random. Each digit has the same probability of being any number - zero or not. I think there are better shorter answers to this question. – cdosborn May 07 '18 at 22:21
1

Possibly the simplest

'#' + Math.random().toString(16).substring(9)
kiran goud
  • 803
  • 2
  • 10
  • 17
1

Use this:

// RGBA()
function getRandomRGBA() {
    function numbers() {
        var x = Math.floor(Math.random() * 256);
        return x;
    }

    alpha = 1.0;
    return (
        "rgba(" +
        numbers() +
        ", " +
        numbers() +
        ", " +
        numbers() +
        ", " +
        alpha.toFixed(1) +
        ")"
    );
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lisa
  • 323
  • 3
  • 14
0
var html = '';
var red;
var green;
var blue;
var rgbColor;

for ( var i = 1; i <= 100; i += 1) {
  red = Math.floor(Math.random() * 256 );
  green = Math.floor(Math.random() * 256 );
  blue = Math.floor(Math.random() * 256 );
  rgbColor = 'rgb(' + red + ',' + green + ',' + blue + ')';
  html += '<div style="background-color:' + rgbColor + '"></div>';  
}

document.write(html);
Durul Dalkanat
  • 7,266
  • 4
  • 35
  • 36
0

This line should randomly change the color for you:

setInterval(function(){y.style.color=''+"rgb(1"+Math.floor(Math.random() * 100)+",1"+Math.floor(Math.random() * 100)+",1"+Math.floor(Math.random() * 100)+")"+'';},1000);
0

I have generated 100 different colors of different contrast, and you can increase values according to your need:

Example on Feedle: http://jsfiddle.net/zFbfE/29/ -

// CHANGE THE INITIAL SEED HERE
Math.seed = 23;

/**
 * Math.seededRandom()
 *
 */
Math.seededRandom = function(max, min) {
    max = max || 1;
    min = min || 0;

    Math.seed = (Math.seed * 9301 + 49297) % 233280;
    var rnd = Math.seed / 233280.0;

    return min + rnd * (max - min);
}

var c, r = 0,
    l = 100000,
    t,
    random = [],
    seededRandom = [];

for(var i=0; i<100; i++)
{
    random[i] = 0;
    seededRandom[i] = 0;
}

// Do some loops withouth benchmarking
// to have a "fair" comparison
/*for (c = 0; c < l; ++c) {
    r = 5+5;
}*/


// benchmark Math.random()
t = new Date().getTime();
s = '';


// benchmark Math.seededRandom()
t = new Date().getTime();
while(l--){
    r = Math.seededRandom();
    seededRandom[(r*100)|0] += 1;
}

var inc = 0;
for(c=0; c<seededRandom.length; c++) {
    //var inc=15;
    for(var i=0; i<seededRandom.length; i++)
    {
        if(i!==c) {
            if(seededRandom[c] == seededRandom[i]) {
            seededRandom[c] += inc;
            inc = inc + 10;
              //    console.log(seededRandom[c]);
            }
        }
    }
    inc = inc > 255 ? 0 : inc;
}

var a=[], b=[], d=[], inc=0, dec=255;
for(c=0; c<seededRandom.length; c++) {
    a[c] = (seededRandom[c] % 100) + inc;
    b[c] = dec - Math.floor(seededRandom[c]/100);
    if(b[c] < 0)
        b[c] = b[c]* - 1;
    if(a[c] > 255)
        a[c] -= 255;
    d[c] = Math.floor(b[c]/2);
    inc += 5;
    dec -= 5;
}


var app = angular.module("myAppp", []).controller('myCtrl',function($scope, $http) {
$scope.id = [];
for(var i=0; i<seededRandom.length; i++)
    $scope.id.push(i);

// Generate random number
$scope.Icon = [];$scope.Icon2 = [], $scope.Icon3 = [];

var ran = 0, inc = 5, dec = 255;
for(var i=0;i<seededRandom.length;i++)
{
    $scope.Icon.push(a[i]%100);
    $scope.Icon2.push(b[i]%100);
    $scope.Icon3.push(d[i]%100);
    console.log(a[i] + "|" + b[i] + "|" + d[i]);
}

});

It works for me and I think it would be helpful for you also.

One best thing in this example is, it will generate 100 random colors and colors would be same on every page load.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shubham Nigam
  • 3,844
  • 19
  • 32
0
function randomColor(format = 'hex') {
    const rnd = Math.random().toString(16).slice(-6);
    if (format === 'hex') {
        return '#' + rnd;
    }
    if (format === 'rgb') {
        const [r, g, b] = rnd.match(/.{2}/g).map(c=>parseInt(c, 16));
        return `rgb(${r}, ${g}, ${b})`;
    }
}
jt3k
  • 642
  • 6
  • 17
0

Try out this package - https://www.npmjs.com/package/gen-random-colors.

It also provides the ability to configure the color set from 0 to 5 (0 is the darkest).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kurumkan
  • 2,635
  • 3
  • 31
  • 55
0

I like parseInt for this case:

parseInt(Math.random()*0xFFFFFFFF).toString(16)
Jony-Y
  • 1,579
  • 1
  • 13
  • 30
0

function getHashColor() {
  var hash = "0123456789ABCDEF";
  var hashColor = "#";
  for (var i = 0; i < 6; i++)
    hashColor += hash[Math.floor(Math.random() * hash.length)];

  document.getElementById('demo').style.background = hashColor
}
<div id="demo" style="background:red;height:300px;width:300px"></div>
<button type="button" onclick="getHashColor()">Clik Me</button>
Tariq Javed
  • 483
  • 3
  • 7
0

A working single-line solution (with padding leading zeroes):

var color = "#" + "colors".split("").map(function(){return parseInt(Math.random()*0x10).toString(16);}).join("");
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
alexroat
  • 1,687
  • 3
  • 23
  • 34
0

With recursion:

var randomColor = (s='') => s.length === 6 ? '#' + s : randomColor(s + '0123456789ABCDEF'[Math.floor(Math.random() * 16)]);
randomColor();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
REDDY PRASAD
  • 1,309
  • 2
  • 14
  • 29
0

Use:

function randomColor(){
  var num = Math.round(Math.random() * Math.pow(10,7));
  // Converting number to hex string to be read as RGB
  var hexString = '#' + num.toString(16);

  return hexString;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anmol Bhardwaj
  • 636
  • 6
  • 18
0

Review

A lot of the answers here are based on Math.random().toString(16). They sometimes multiply a random number by some number and assume that a conversion to a hexadecimal string will always produce a floating point hexadecimal representation which has at least six digits after the dot (and they use those digits as the color).

This is a wrong assumption

Because there is a lot of numbers which actually give less than six digits (after the dot). If Math.random() choose such a number, then the resulting hexadecimal color will be invalid (unless someone handles this case). Here is an example generator (which I write based on this converter) for such values.

function calc() {
  let n = hex2dec(hexInput.value)
  console.log(`${n} -> ${n.toString(16)}` );
}

// Source: https://stackoverflow.com/questions/5055723/converting-hexadecimal-to-float-in-javascript/5055821#5055821
function hex2dec(hex) {
    hex = hex.split(/\./);
    var len = hex[1].length;
    hex[1] = parseInt(hex[1], 16);
    hex[1] *= Math.pow(16, -len);
    return parseInt(hex[0], 16) + hex[1];
}
Put some 5-digit (or less) hexdecimal number in range 0-1<br>
<input id="hexInput" value="0.2D4EE">
<button onclick="calc()">Calc</button>

I already gave two answers to your question without this assumption: RGB and hexadecimal so in this answer I will not put in another solution.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
0

I WANT MATERIAL-COLORS UI. So with this answer stackoverflow answer

and with this github repo defaultPalette i made this javascript where you can just import to and you can call it just by const color= defaultPalette(); or const color = defaultPalette('flatui');

    <!-- language: lang-js -->   
    const defaultPalette = {
    // Red, Pink, Purple, Deep Purple, Indigo, Blue, Light Blue, Cyan, Teal, Green, Light Green, Lime, Yellow, Amber, Orange, Deep Orange, Brown, Grey, Blue Grey
    '50': ['#FFEBEE', '#FCE4EC', '#F3E5F5', '#EDE7F6', '#E8EAF6', '#E3F2FD', '#E1F5FE', '#E0F7FA', '#E0F2F1', '#E8F5E9', '#F1F8E9', '#F9FBE7', '#FFFDE7', '#FFF8E1', '#FFF3E0', '#FBE9E7', '#EFEBE9', '#FAFAFA', '#ECEFF1'],
    '100': ['#FFCDD2', '#F8BBD0', '#E1BEE7', '#D1C4E9', '#C5CAE9', '#BBDEFB', '#B3E5FC', '#B2EBF2', '#B2DFDB', '#C8E6C9', '#DCEDC8', '#F0F4C3', '#FFF9C4', '#FFECB3', '#FFE0B2', '#FFCCBC', '#D7CCC8', '#F5F5F5', '#CFD8DC'],
    '200': ['#EF9A9A', '#F48FB1', '#CE93D8', '#B39DDB', '#9FA8DA', '#90CAF9', '#81D4FA', '#80DEEA', '#80CBC4', '#A5D6A7', '#C5E1A5', '#E6EE9C', '#FFF59D', '#FFE082', '#FFCC80', '#FFAB91', '#BCAAA4', '#EEEEEE', '#B0BEC5'],
    '300': ['#E57373', '#F06292', '#BA68C8', '#9575CD', '#7986CB', '#64B5F6', '#4FC3F7', '#4DD0E1', '#4DB6AC', '#81C784', '#AED581', '#DCE775', '#FFF176', '#FFD54F', '#FFB74D', '#FF8A65', '#A1887F', '#E0E0E0', '#90A4AE'],
    '400': ['#EF5350', '#EC407A', '#AB47BC', '#7E57C2', '#5C6BC0', '#42A5F5', '#29B6F6', '#26C6DA', '#26A69A', '#66BB6A', '#9CCC65', '#D4E157', '#FFEE58', '#FFCA28', '#FFA726', '#FF7043', '#8D6E63', '#BDBDBD', '#78909C'],
    '500': ['#F44336', '#E91E63', '#9C27B0', '#673AB7', '#3F51B5', '#2196F3', '#03A9F4', '#00BCD4', '#009688', '#4CAF50', '#8BC34A', '#CDDC39', '#FFEB3B', '#FFC107', '#FF9800', '#FF5722', '#795548', '#9E9E9E', '#607D8B'],
    '600': ['#E53935', '#D81B60', '#8E24AA', '#5E35B1', '#3949AB', '#1E88E5', '#039BE5', '#00ACC1', '#00897B', '#43A047', '#7CB342', '#C0CA33', '#FDD835', '#FFB300', '#FB8C00', '#F4511E', '#6D4C41', '#757575', '#546E7A'],
    '700': ['#D32F2F', '#C2185B', '#7B1FA2', '#512DA8', '#303F9F', '#1976D2', '#0288D1', '#0097A7', '#00796B', '#388E3C', '#689F38', '#AFB42B', '#FBC02D', '#FFA000', '#F57C00', '#E64A19', '#5D4037', '#616161', '#455A64'],
    '800': ['#C62828', '#AD1457', '#6A1B9A', '#4527A0', '#283593', '#1565C0', '#0277BD', '#00838F', '#00695C', '#2E7D32', '#558B2F', '#9E9D24', '#F9A825', '#FF8F00', '#EF6C00', '#D84315', '#4E342E', '#424242', '#37474F'],
    '900': ['#B71C1C', '#880E4F', '#4A148C', '#311B92', '#1A237E', '#0D47A1', '#01579B', '#006064', '#004D40', '#1B5E20', '#33691E', '#827717', '#F57F17', '#FF6F00', '#E65100', '#BF360C', '#3E2723', '#212121', '#263238'],
    'A100': ['#FF8A80', '#FF80AB', '#EA80FC', '#B388FF', '#8C9EFF', '#82B1FF', '#80D8FF', '#84FFFF', '#A7FFEB', '#B9F6CA', '#CCFF90', '#F4FF81', '#FFFF8D', '#FFE57F', '#FFD180', '#FF9E80'],
    'A200': ['#FF5252', '#FF4081', '#E040FB', '#7C4DFF', '#536DFE', '#448AFF', '#40C4FF', '#18FFFF', '#64FFDA', '#69F0AE', '#B2FF59', '#EEFF41', '#FFFF00', '#FFD740', '#FFAB40', '#FF6E40'],
    'A400': ['#FF1744', '#F50057', '#D500F9', '#651FFF', '#3D5AFE', '#2979FF', '#00B0FF', '#00E5FF', '#1DE9B6', '#00E676', '#76FF03', '#C6FF00', '#FFEA00', '#FFC400', '#FF9100', '#FF3D00'],
    'A700': ['#D50000', '#C51162', '#AA00FF', '#6200EA', '#304FFE', '#2962FF', '#0091EA', '#00B8D4', '#00BFA5', '#00C853', '#64DD17', '#AEEA00', '#FFD600', '#FFAB00', '#FF6D00', '#DD2C00'],
    'flatui': ['#1ABC9C', '#2ECC71', '#3498DB', '#9B59B6', '#34495E', '#16A085', '#27AE60', '#2980B9', '#8E44AD', '#2C3E50', '#F1C40F', '#E67E22', '#E74C3C', '#ECF0F1', '#95A5A6', '#F39C12', '#D35400', '#C0392B', '#BDC3C7', '#7F8C8D'],
    'metro': ['#A4C400', '#60A917', '#008A00', '#00ABA9', '#1BA1E2', '#0050EF', '#6A00FF', '#AA00FF', '#F472D0', '#D80073', '#A20025', '#E51400', '#FA6800', '#F0A30A', '#E3C800', '#825A2C', '#6D8764', '#647687', '#76608A', '#A0522D']
}
const defaultBase = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700', 'flatui', 'metro']

const randomIntFromInterval = (min, max) => { // min and max included
    return Math.floor(Math.random() * (max - min + 1) + min)
}


export default (choosePalette)=>{
    if (choosePalette === undefined) {
        const nrindexdefault = defaultBase.length - 1;
        const number = randomIntFromInterval(0, nrindexdefault);

        const defaultPaletteColorsArray = defaultPalette[defaultBase[number]];
        const nrindexcolor = defaultPaletteColorsArray.length - 1;
        const defaultColor = randomIntFromInterval(0, nrindexcolor)
        return defaultPaletteColorsArray[defaultColor];
    } else {
        const defaultPaletteColorsArray = defaultPalette[choosePalette];
        const nrindexcolor = defaultPaletteColorsArray.length - 1;
        const defaultColor = randomIntFromInterval(0, nrindexcolor)
        return defaultPaletteColorsArray[defaultColor];
    }

}
0

create a unique color based on any random value

    selectColor(numberOrString) {
      if (typeof numberOrString === "string") {
        // convert string to number
        numberOrString = numberOrString.toLowerCase().split('').reduce(function (a, b) {
          a = ((a << 5) - a) + b.charCodeAt(0); // explained here: https://stackoverflow.com/a/7616484/112731
          return a & a
        }, 0);
      }
      const hue = numberOrString * 137.508; // use golden angle approximation
      return `hsl(${hue},50%,75%)`;
    }
A. El-zahaby
  • 1,130
  • 11
  • 32
0

Generating Hue, Saturation and Lightness over the hex representation gives more meaningful control.

function rndm( max, min = 0 ){ // [ min, max ]
    return min + Math.floor( Math.random() *( max - min + 1 ));
}
function rndmColour() { // Hue Saturation Lightness
    return `hsl(${rndm( 360 )},${rndm( 100 )}%,${rndm( 100 )}%)`;
}
baz
  • 1,317
  • 15
  • 10
-1

Random rgb color in JS

const getRandomArbitrary = (min, max) => parseInt(Math.random() * (max - min) + min, 10)

const generateRandomRGBColor = () => 
    `rgb(${getRandomArbitrary(0, 255)}, ${getRandomArbitrary(0, 255)}, ${getRandomArbitrary(0, 255)})`;

// generateRandomRGBColor()

Or you can use online tool to generate colors palette - I have built https://colorswall.com/palette/generate for this purpose.

desertnaut
  • 57,590
  • 26
  • 140
  • 166
colorswall
  • 188
  • 1
  • 4
  • 2
    Based on the domain/URL of your link(s) being the same as, or containing, your user name, you appear to have linked to your own site/a site you're affiliated with. If you do, you must disclose that it's your site in your post. If you don't disclose affiliation, it's considered spam. Please take time to read: [**How to not be a spammer**](https://stackoverflow.com/help/promotion), – Vickel Sep 27 '21 at 21:56
  • [What is *good* self promotion?](https://meta.stackexchange.com/questions/182212/what-signifies-good-self-promotion-or-self-promotion-part-infinity), What is the [exact definition of *spam*](https://meta.stackoverflow.com/questions/260638/what-is-the-exact-definition-of-spam-for-stack-overflow) for Stack Overflow? and [What makes something spam](https://meta.stackexchange.com/questions/58032/what-are-the-spam-and-rude-or-abusive-offensive-flags-and-how-do-they-wor/58035#58035) – Vickel Sep 27 '21 at 21:56
  • 1
    As @Vickel says - I have edited your post to make the affiliation explicit. Please keep this in mind for the future. – desertnaut Sep 27 '21 at 21:57
  • Sorry, thank a lot. – colorswall Sep 28 '21 at 15:22
-2
function generateRandomColor()
{
    var randomColor = '#'+Math.floor(Math.random()*16777215).toString(16);
    return randomColor;
    //random color will be freshly served
}
document.body.style.backgroundColor = generateRandomColor() // -> #e1ac94
someDiv.style.color = generateRandomColor() // -> #34c7aa
-2

Using HexaDecimal for a random color generation:(#000000 - #FFFFFF)

The syntax is pretty straightforward. We specify a hexadecimal color as #RRGGBB. We know that each hexadecimal color (RR, GG, and BB) is defined by 8 bytes. Remember, each byte can represent 256 values.

  • RR - 16 * 16 (0,1,2,3... F)=256. Similary for GG and BB.

This means that the hexadecimal color system can take on 256(R) x 256(G) x 256(B) = 16,777,216 values.

We use Math.random() and Math.floor() to get a number that results in the range 0 and 16777215.

Math.floor(Math.random()*16777215)

Finally, the Number needs to be converted into base 16(hexadecimal), We can get this by using toString(base).

Math.floor(Math.random()*16777215).toString(16);
//->12ef556
let randomColor = '#'+Math.floor(Math.random()*16777215).toString(16);
MVS KIRAN
  • 115
  • 1
  • 6
  • 1
    this is plain wrong, youcan get a hexadecimal number that is too small, resulting in a string that is shorter than 6 characters, like `Math.floor(0.03*16777215).toString(16);` – user151496 Jan 11 '22 at 14:54