0

Currently I"m working on a small script in scriptish which takes in a user ID (currently on our forums, we have userID from 1 to 63) and colors it with a random color using this following function:

function setNickColor(nick) 
var spans = nick.getElementsByTagName('span');
var uid = nick.getAttribute('hovercard-id');

if (colors[uid] == null)
    storeColor(uid, Math.random().toString(15).substring(2,8));

This gives me a random color generated in 24 bits(for rgb color) individually for each person that installed the script. I'd like to have each ID generate a fixed random color. I don't understand how to work the ID into the function so that it's still random yet generates a random color still.

I looked at seeds but it's a bit difficult to understand what they do because I'm very new to javascript

user1066886
  • 202
  • 3
  • 12

2 Answers2

0

"Fixed" and "random" are two very opposite things. Forget random. According to your description you really just want "fixed".

Now for solution: take an arbitrary hash of ID and then reduce it to just 3 bytes to form RGB value that'd correspond to that ID.

Oleg V. Volkov
  • 21,719
  • 4
  • 44
  • 68
  • Thanks for the answer. I've been looking around google and it seems as though all the hash functions are overly complicated for my needs. Do you recommend any hash function in particular (as far as I can see there is no native hash function?) – user1066886 Mar 04 '13 at 11:05
  • Hint: search for "checksum" too. In this context it it same as hash. This question about fast checksums have link to JS implementation for CRC32, which should be enough for your purposes: http://stackoverflow.com/questions/421419/good-choice-for-a-lightweight-checksum-algorithm – Oleg V. Volkov Mar 04 '13 at 13:13
0

As I see it there are two main components of your solution:

  1. Generate a random color for a userid.
  2. Associate this random color with the userid on subsequent requests.

Since you've already done the first one, it leaves the second one. Here are some options depending on what kind of flexibility the back end system provides you:

  1. You could write a webservice, call it from your javascript function. The payload for your call would be the userid and the generated color, which your webservice would store in the back end database. Your template would then check for each user if the color isn't set, generate a random one and set it (and refresh the page, for the initial setup).

  2. You could set a cookie in the browser that represents the color you generated, then load this cookie and use it to alter the userid being displayed. The downside to this is that it is browser dependent (on the same machine, on two browsers, you could have two different colors for the same userid), and if the person clears their cookies the color will be regenerated.

  3. The third option is what Oleg suggested - create some hash of the userid (its a one-way algorithm so you are guaranteed the same result given the same input), and then take a component of this hash as the basis of your color. The benefits are you avoid the cookie and the webservice problem; but the challenges are you need to make your color generator a bit more "random" as it may be you end up with colors that aren't that visually distinct.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • I feel like what Oleg suggested for a hash function is the best solution at the moment. However, as far as I can tell, there's no native hash function in javascript? Every time I google public hash code, it's overly complicated for my needs and ends up being larger than my original code. Is there anything you'd recommend to ease this? – user1066886 Mar 04 '13 at 11:10
  • You mean other than #1 and #2? :) – Burhan Khalid Mar 04 '13 at 11:12
  • I have little experience with a webservice unfortunately. This is actually my end plan (users will be able to set their color in the browser which is sent to heroku) but for now I just want to stick with a simple solution before expanding, as my experience with javascript began 3 hours ago. – user1066886 Mar 04 '13 at 11:14
  • The simplest option is #2, set a cookie with javascript. – Burhan Khalid Mar 04 '13 at 11:16
  • Unfortunately the code isn't for myself, it's being used by about 10 other people and I would like it to be the same across the board for everyone – user1066886 Mar 04 '13 at 11:18
  • It will be the same for anyone who accesses the page that has your javascript - the only thing different will be the color (obviously). – Burhan Khalid Mar 04 '13 at 11:19