2

I'd like to determine a background-color C depending on an integer X (number of positive votes)

OK, I could do

if(x==0) c = '#000';
else if(x > 0 && x < 5 ) c = '#001'
else if(X<=5 <= 20) c = '#002';
//and so on...

But, how can I do this to make it gradual? I mean from 0 to 500 votes -> 500 tones of blue colors? (if I'm not wrong its posible two digits for HEX (if not, 15*15 xD))

Any ideas?

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Toni Michel Caubet
  • 19,333
  • 56
  • 202
  • 378

3 Answers3

3

Since you're just looking for ideas, here's one that nobody else will suggest. First, go look up "Catmull-Rom Spline" formulas. It boils down to a very simple matrix multiplication trick that gives you a formula for computing curves given a set of control points.

OK, so now that you know all about Catmull-Rom splines, you can write some code to do a curve in 3-space. Well, what's RGB if not a 3-dimensional space? So you pick a few good color control points (RGB colors), and then you use your handy Catmull-Rom implementation to generate a parametric curve through all those colors, with as many colors along the curve as you want.

The cool thing about the color progressions will be that they're really "smooth" across transitions.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Thanks for the upvotes - honestly this is a whole lot easier than it sounds, esp. if you remember even a little high-school algebra. I'm seriously stupid and I've implemented and re-implemented this a dozen times over the past 20 years. – Pointy Apr 02 '11 at 00:00
  • Oh, and if it's not clear: the "integer" would map to the parametric coefficient ("*t*") in the formulas. In other words, that value "moves along the curve", so to speak. The control points are in groups of four, so you go four at a time through them generating points. – Pointy Apr 02 '11 at 00:07
  • very very acurate! i will have a look ;) – Toni Michel Caubet Apr 02 '11 at 00:11
  • 1
    OK. I've actually got some old code on github (a Mandelbrot set program) that uses this trick, but it might be too horrible to be used outside of that hack :-) If I can find it I'll ad the URL here. **edit** [here it is](https://github.com/Pointy/Mandelbrot.js) – Pointy Apr 02 '11 at 00:37
  • Note that you might get nicer results if you do the interpolation in a different colorspace, like HSL. – rmmh Apr 02 '11 at 00:39
  • @sysrqb yes that's certainly worth a try - I don't recall whether I've ever done it, but it'd be really easy to try. The effect would definitely be different. – Pointy Apr 02 '11 at 00:43
2

I would probably use something like:

var blueness = x / 2;
if (blueness > 255) blueness = 255;
rgb(0, 0, blueness);

but you can use this sprintf implementation and use it like you would in any other language to convert to hex.

tster
  • 17,883
  • 5
  • 53
  • 72
2

Include raphaeljs on your page and paste the functions estimateColorForValue() and toHex() somewhere in your code. estimateColorForValue(hue, value, darkestValue, brightestValue) computes a color for some value, interpolating the color by seeing where in the range [darkestValue-brightestValue] value is. hue is in the range [0-1]: 0.1 for orange-browny, 0.4 for green, 0.8 for pinkish, and many more colors in between. small changes in hue drastically change the visual color.

For example: estimateColorForValue(.1, 15, 1, 20), can be explained as, for data ranging 1 through 20, compute color for value 15, in the orangy space.

toHex(estimateColorForValue(.1, 15, 1, 20)) ==> "#cf8415"

Code:

<script src="https://raw.github.com/DmitryBaranovskiy/raphael/master/raphael.js"></script>

<script>

function toHex(hsb) {
  return Raphael.hsb2rgb(hsb.h, hsb.s, hsb.b).hex;
}

function estimateColorForValue(hue, value, darkestValue, brightestValue) {
  // Constants to determine saturation and brightness
  var darkBrightness = 0.6;
  var brightBrightness = 1;
  var darkSaturation = 0.3;
  var brightSaturation = 1;

  // Compute saturation and brightness:
  var gradient = (value - darkestValue) / (brightestValue - darkestValue);
  var saturation = darkSaturation + gradient * (brightSaturation - darkSaturation);
  var brightness = darkBrightness + gradient * (brightBrightness - darkBrightness);

  return {h: hue, s:saturation, b:brightness};
}
</script>
Sami A. Haija
  • 1,910
  • 2
  • 14
  • 12