1

I want to randomize a color by a given id (that it can be any number start from 0) in javascript. For example:

//number is the id I want to give the function
    function getRandomColor(number) {
    var letters = '0123456789ABCDEF';
    var color = '#';
    var generatedNumber = Math.floor(Math.random() * 16);
    var otherNumber = //something to unite generatedNumber and number(the given id) in a valid number
        for (var i = 0; i < 6; i++ ) {
            color += letters[otherNumber];
        }
        return color;
    }

How could I do it?

tina
  • 243
  • 5
  • 25
  • I don't understand what you mean by "by a given id", is the colour to be completely random and if not, what is the parameter you're giving influencing the result? And can you clarify what exactly is not working in the code you are showing? – Pekka Jan 27 '17 at 11:42
  • The parameter is a number. The color must be randomize using the parameter. – tina Jan 27 '17 at 11:47
  • But using it *in what way?* To what end? Can you clarify what your goal is with this => how is the number expected to influence the result? – Pekka Jan 27 '17 at 11:48
  • 1
    You might find that you have better luck with a semi-random algorithm that works over a different colorspace than RGB. By simply choosing random RGB colors, you will end up with quite a few dark, similar looking colors. If instead you chose random numbers for the H and S parts of an HSL color, you'll end up with a "better" selection of colors. – spender Jan 27 '17 at 11:49
  • The end is to use the same color for the same element in a graph dinamically draw with svg and the legend (not related to it, but in the same page) – tina Jan 27 '17 at 11:50
  • So you have a set of different elements and you want those to have colours that are random, but the same for certain elements? – Pekka Jan 27 '17 at 11:51
  • Spender can you please make me an example? It could be perfect for my case. – tina Jan 27 '17 at 11:51
  • Pekka: no, I have a set of elements in a graph. I want them to have all randomized different colours. Every element in the graph must have the SAME color in the legend, that is done in another way in the page, so it's not really related to the graph. – tina Jan 27 '17 at 11:54
  • @tina ah, ok. In that case I think it would be *vastly* better to create an array of random colours earlier on in the code, and then pass those to both the legend and the respective elements. – Pekka Jan 27 '17 at 11:56
  • @tina See my answer below – spender Jan 27 '17 at 12:07

3 Answers3

6

You need to move the random part inside of the for loop.

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

console.log(getRandomColor());

You could omit the string with the numbers and letters and use toString with base 16.

For keeping the same color for the same id, you could use an object for keeping the color.

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

var getColor = function() {
        var colors = {};
        return function (id) {
            return colors[id] = colors[id] || getRandomColor();
        };
    }();


console.log(getColor('foo'));
console.log(getColor('bar'));
console.log(getColor('baz'));
console.log(getColor('foo'));
console.log(getColor('baz'));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • This is a random generator that NOT consider the given number – tina Jan 27 '17 at 11:44
  • Well, how exactly is it *supposed* to consider the number? What do you want to achieve here? – Pekka Jan 27 '17 at 11:45
  • what is `number` doing? – Nina Scholz Jan 27 '17 at 11:46
  • the code you are showing wark perfectly without a number as argument, I want to use the argument number for randomize the color – tina Jan 27 '17 at 11:46
  • @tina, yes, but how? – Nina Scholz Jan 27 '17 at 11:47
  • That's my question... Starting from this number I want to randomize a color, I don't know how – tina Jan 27 '17 at 11:48
  • Can you tell us what your end goal with this is? What is the feature you want to build? As you can see there are two people here who don't quite understand what you want to do :) – Pekka Jan 27 '17 at 11:49
  • 1
    Just a pointer, its better to use `string.charAt` instead of `index`. [More information](http://stackoverflow.com/questions/5943726/string-charatx-or-stringx). Yes, its supported after ES3, so should not pose much threat, but as a convention, using `.charAt` would imply, operand is a string. When you do `variable[key]`, variable can be `Array` or string (*key being index*) or `Object`(*key being property name*). So just my reading the line, you cannot make sure what `variable` holds – Rajesh Jan 27 '17 at 11:50
  • @tina, now each `id` has the same color assigned. – Nina Scholz Jan 27 '17 at 11:57
  • +1 but as a nitpick, the new example certainly does what the OP requested, but it feels very smelly to conflate generating a random colour, and managing the objects that are going to *get* the colour. Probably doesn't matter in the OP's case, but in any serious software project a fundamentally different approach (generating the random colours earlier, and feeding them to the object renderer and to the legend) would probably be warranted. – Pekka Jan 27 '17 at 11:59
1

Following from my comment above, it might be better to manipulate the color in the HSL colorspace, so that you get bold colors. The trick is to maintain a constant luminance while randomising the hue and saturation.

For any combination of hue and saturation, 100% luminance will always be white and 0% luminance will always be black. The strongest impression of color will be seen with a luminance value right in the middle i.e. 50%.

You could do this as follows:

var h = Math.floor(Math.random() * 360); //hue is measured in degrees from 0-359
var s = Math.floor(Math.random() * 256); //saturation is a value from 0-255


$("#theElement").css("background-color","hsla(" + h + ", " + s + "%, 50%, 1)");
#theElement{
  width: 100px;
  height: 100px;
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=theElement></div>

So, say you want to generate a palette of 16 colors:

var colors = [];
for(var i = 0; i < 16; ++i)
{
    var h = Math.floor(Math.random() * 360); //hue is measured in degrees from 0-359
    var s = Math.floor(Math.random() * 256); //saturation is a value from 0-255
    colors.push("hsla(" + h + ", " + s + "%, 50%, 1)");
}
var paletteIndex = 3; //for example
$("#theElement").css("background-color", colors[paletteIndex]);
spender
  • 117,338
  • 33
  • 229
  • 351
  • Your solution was better for randomize colors, but I need to use a given id in my function, in order to have the same color for the same element in my page (see my comments under my question) – tina Jan 27 '17 at 12:12
  • @tina So make an array of colors up front so that they can be reused. I added some info to demonstrate this. – spender Jan 27 '17 at 12:18
0
var possibilities = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'];
var newColor = '';
var x = 1;
var z = ''
do { 
z = Math.floor((Math.random() * 16) + 1);
    if (possibilities[z] !== undefined){
      newColor = newColor + possibilities[z]; 
      x++;
    }
}
while (x<7);
console.log("#"+newColor)
Hugo
  • 61
  • 3