Random color generator

Viewed 838177

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?

63 Answers

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

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

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)}`

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:

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

'#' + Math.round((0x1000000 + 0xffffff * Math.random())).toString(16).slice(1)

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

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"));

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

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);
}

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.

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
}

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]
    );
};

Possibly the simplest

'#' + Math.random().toString(16).substring(9)

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) +
        ")"
    );
}

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.

I like parseInt for this case:

parseInt(Math.random()*0xFFFFFFFF).toString(16)

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>

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

var color = "#" + "colors".split("").map(function(){return parseInt(Math.random()*0x10).toString(16);}).join("");

With recursion:

var randomColor = (s='') => s.length === 6 ? '#' + s : randomColor(s + '0123456789ABCDEF'[Math.floor(Math.random() * 16)]);
randomColor();

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;
}

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.

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];
    }

}
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

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.

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);
Related