Question

IS there any quick way of accomplishing this?

For example the start color #EEEEEE and end color #FFFFFF would make something like #FEFFEE.

Was it helpful?

Solution

Of course the hex is encoded as a number but for it to make any kind of sense, you have to first extract the rgb components :

function rgb(string){
    return string.match(/\w\w/g).map(function(b){ return parseInt(b,16) })
}
var rgb1 = rgb("#EEEEEE");
var rgb2 = rgb("#FFFFFF");

Then simply take an intermediate of all components :

var rgb3 = [];
for (var i=0; i<3; i++) rgb3[i] = rgb1[i]+Math.random()*(rgb2[i]-rgb1[i])|0;

And finally rebuild the color as a standard hex string :

var newColor = '#' + rgb3
    .map(function(n){ return n.toString(16) })
    .map(function(s){ return "00".slice(s.length)+s}).join(''); 

Note that in order to get better results, depending on your goal, for example if you want to keep the luminosity, using a different color space than RGB (say HSL or HSV) might be useful.

OTHER TIPS

d3 does this extremely well by creating colour scales:

var color = d3.scale.linear()
    .domain([-1, 0, 1])
    .range(["red", "white", "green"]);

color(-1)   // "#ff0000" red
color(-0.5) // "#ff8080" pinkish
color(0)    // "#ffffff" white
color(0.5)  // "#80c080" getting greener
color(0.7)  // "#4da64d" almost there..
color(1)    // "#008000" totally green!

If I understand the question in the right way, you want each digit to be in the same range. Do you mean each digit or each component (color channel). For each digit see my fiddle

The key is:

for(var i = 0;i < 6; i++) {
    color += (Math.floor(Math.random() * (end-start+1)) + start).toString(16);
}

with start and end from 0 to 15

or each channel:

for(var i = 0;i < 3; i++) {
    color += (Math.floor(Math.random() * (end-start+1)) + start).toString(16);
}

with start and end between 0 and 255

Denys Séguret's version in ES6

const rgb = string => string.match(/\w\w/g).map(b => parseInt(b, 16))
const rgbrnd = (rgb1, rgb2) => {
  const rgb3 = [];
  for (let i = 0; i < 3; i++) rgb3[i] = rgb1[i] + Math.random() * (rgb2[i] - rgb1[i]) | 0;
  return '#' + rgb3
    .map(n => n.toString(16).padStart(2, '0'))
    .join('');
};


const rgb1 = rgb("#00FF00"); // green 
const rgb2 = rgb("#FF0000"); // red
console.log(rgbrnd(rgb1, rgb2))

Try:

function getRandomColor(start, end){
    var min=parseInt(start.replace("#",""), 16);
    var max=parseInt(end.replace("#",""), 16);
    return "#"+Math.floor((Math.random() * (max - min) + min)).toString(16).toUpperCase();
}    

Here is a Fiddle to play with.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top