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?
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>
I doubt anything will be faster or shorter than this one:
"#"+((1<<24)*Math.random()|0).toString(16)
Challenge!
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).
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 http://blog.adamcole.ca/2011/11/simple-javascript-rainbow-color.html.
Who can beat it?
'#'+Math.random().toString(16).substr(-6);
Guaranteed to work all the time: http://jsbin.com/OjELIfo/2/edit
Based on @eterps comment the code above can still generate shorter strings if 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;
}
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();
}
I like this one: '#' + (Math.random().toString(16) + "000000").substring(2,8)
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(",") + ")";
}
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)`
'#'+Math.random().toString(16).slice(-3) // three-numbers format aka #f3c
'#'+Math.random().toString(16).slice(-6) // six-number format aka #abc123
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;
}
The article written by Paul Irish on Random Hex Color Code Generator in JavaScript is absolutely amazing. Use:
'#'+Math.floor(Math.random()*16777215).toString(16);
Here is the source link:
http://www.paulirish.com/2009/random-hex-color-code-snippets/
This can be very easily be found using Google Search:
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;
}
}
If you're a noob like me, clueless about hexadecimals and such, this might be more intuitive.
function r() { return Math.floor(Math.random() * 255) }
var color = 'rgb(' + r() + "," + r() + "," + r() + ')';
You just need to end up with a string such as 'rgb(255, 123, 220)'
Short answer with pad to exact size
'#'+((1<<24)*(Math.random()+1)|0).toString(16).substr(1)
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
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.
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 SO thread because the top answer has another comment linking to a Gist with the JS 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) : '';
}
// next two methods converted from Ruby to JS
// soured 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 golden ratio
const golden_ratio_conjugate = 0.618033988749895
let h = Math.random() // # use 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)
`#${crypto.getRandomValues(new Uint32Array(1))[0].toString(16).padStart(8, 0).slice(-6)}`
`#${crypto.getRandomValues(new Uint32Array(1))[0].toString(16).padStart(8, 0)}`
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
Array.prototype.reduce
makes it very clean.
["r","g","b"].reduce(function(res) {
return res + ("0"+~~(Math.random()*256).toString(16)).slice(-2)
}, "#")
Needs a shim for old browsers.
You could use this simple function
function getRandomColor(){
var color = "#" + (Math.random() * 0xFFFFFF << 0).toString(16);
return color;
}
There are so many ways you can accomplish this. Here's some I did:
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;
}
Extremely short one-liner
'#'+Math.random().toString(16).slice(-6)
Generates individual RGB 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);
}
function get_random_color() {
return "#" + (Math.round(Math.random() * 0XFFFFFF)).toString(16);
}
Use distinct-colors.
It generates a palette of visually distinct colors.
distinct-colors is highly configurable:
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))
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 euclidian distance from the others in the HSV cone
It allows you to restrict the hue, saturation, or value range, but 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.
/**
* 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);
}
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:
"#"+("000"+(Math.random()*(1<<24)|0).toString(16)).substr(-6)
Try this in the console:
for(i = 0; i < 200; i++) {
console.log("#" + ("000" + (Math.random()*(1<<24)|0).toString(16)).substr(-6));
}
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);
}
map (returns always 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
You can use colorchain.js to generate a sequence of colors with varying hues.
My version:
function RandomColor() {
var hex = (Math.round(Math.random()*0xffffff)).toString(16);
while (hex.length < 6) hex = "0" + hex;
return hex;
}
regexp (always returns 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
// BONUS here are values that makes Math.random() not give 6 digit 0.1769733428955078, 0.17698287963867188, 0.4149589538574219, 0.49722862243652344, 0.7051858901977539, 0.3124990463256836, 0.09694671630859375, 0.8300838470458984, 0.9915647506713867, 0.7658090591430664, 0.12326622009277344. Calculated using https://planetcalc.com/862/ (put hex num with 5 digits into source number eg. 0.2D4EE and input base 16, output 10 - and add/manipulate last digit to get wanted number.
A bit enhanced one-liner to make the approach more vivid
'#' + Math.round((0x1000000 + 0xffffff * Math.random())).toString(16).slice(1)
©2020 All rights reserved.