Generate colors between red and green for an input range

Naftali aka Neal picture Naftali aka Neal · Aug 7, 2012 · Viewed 49.7k times · Source

Possible Duplicate:
Color coding based on number

I want for a user to be able to select from a range from 1-100, where as the numbers become less than 50, the color of the area becomes darker green, and as the color becomes closer to 100, the color becomes more red.

I am trying to make it so that as the range in more towards the center, the color should be close to white (where 50 = full white).

I tried the answer from here: Generate colors between red and green for a power meter? to no avail.... 50 ends up being a muddled green...

I have the following html:

<span><span class="value">50</span><input type="range" /></span>​

And the following javascript:

$(document).on({
    change: function(e) {

        var self = this,
            span = $(self).parent("span"),
            val = parseInt(self.value);
        if (val > 100) {
            val = 100;
        }
        else if (val < 0) {
            val = 0;
        }
        $(".value", span).text(val);
        var r = Math.floor((255 * val) / 100),
            g = Math.floor((255 * (100 - val)) / 100),
            b = 0;
        span.css({
            backgroundColor: "rgb(" + r + "," + g + "," + b + ")"
        });
    }
}, "input[type='range']");​

Fiddle: http://jsfiddle.net/maniator/tKrM9/1/

I have tried many different combinations of r,g,b but I really cannot seem to get it right.

Answer

Shawn Chin picture Shawn Chin · Aug 7, 2012

You're getting the muddled green because of the way you're creating your gradient in RBG space. To get a "cleaner" gradient, you can use the HSV model as mentioned in the answer of the question you linked to.

RGB gradient (top) vs HSV (bottom) top gradient uses RGB, bottom uses HSV

By scaling the H (hue) value between 0 (red) and 120 (green) you'll get a nice clean transition. However, at the mid point (60) you'll end up with bright yellow instead of your intended white. You can address this by modifying the S (saturation) value -- at 0 saturation, you'll end up with white (1 gives you full colour saturation.

Here's a crude example which scales the saturation from 1 to 0 and back to 1 as the input value goes from 0 to 50 to 100 - http://jsfiddle.net/xgJ2e/2/

var hue = Math.floor((100 - val) * 120 / 100);  // go from green to red
var saturation = Math.abs(val - 50)/50;   // fade to white as it approaches 50

p.s. Converting between colour models is easy using jquery-colors, although it's not too hard to roll your own.