I would like to calculate color value according to given number.
0 -> pure red
100 -> pure green
example: 75 -> color, which is 75% from red to green.
I need this for expiration counter, which shows appropriate colors as days count down.
The function R*0.2126+ G*0.7152+ B*0.0722 is said to calculate the perceived brightness (or equivalent grayscale color) for a given an RGB color. Assuming we use the interval [0,1] for all RGB values, we can calculate the following: yellow = RGB(1,1,0) => brightness=0.9278.
The RGB color 0, 255, 255 is a light color, and the websafe version is hex 00FFFF, and the color name is aqua. The color can be described as light saturated cyan. A complement of this color would be 128, 128, 128, and the grayscale version is 179, 179, 179.
Hex color codes start with a pound sign or hashtag (#) and are followed by six letters and/or numbers. The first two letters/numbers refer to red, the next two refer to green, and the last two refer to blue. The color values are defined in values between 00 and FF (instead of from 0 to 255 in RGB).
You could indeed go for the solution provided by @KamilT. Disadvantage of this method (imo) is that the colors in the middle (around 50) will get brownish and not very nice compared to your full red and green.
I think it would be much nicer to follow the color spectrum, and passing over orange and yellow, in stead of that ugly brownish.
This can easily by achieved by working with HSL values rather then RGB values. If you set the Hue value based on your number between 0 and 100 to a value between 0°(red) and 120°(green), and keep your Saturation at 100% and your Lightness at 50%, you should get nice bright colors.
I found a way to convert between rgb and hsl here: HSL to RGB color conversion
And I wrote a simple function to calculate your rgb value using the conversion function from the answer above:
// convert a number to a color using hsl
function numberToColorHsl(i) {
// as the function expects a value between 0 and 1, and red = 0° and green = 120°
// we convert the input to the appropriate hue value
var hue = i * 1.2 / 360;
// we convert hsl to rgb (saturation 100%, lightness 50%)
var rgb = hslToRgb(hue, 1, .5);
// we format to css value and return
return 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
}
And I set up a fiddle to demonstrate the diffrences between the HSL method and the RGB method: http://jsfiddle.net/rE6Rk/1/
update a more versatile version:
If you do not want to work with a range from red to green, you can slightly adapt the above method. The value that determines the actual color in a hsl
representation is the hue
, so that's the one we'll need to calculate.
If you define the range of your hue, by providing the 0 and 1 value as parameters, the calculation of the hue value becomes basic math. Have a look at the updated method:
function percentageToHsl(percentage, hue0, hue1) {
var hue = (percentage * (hue1 - hue0)) + hue0;
return 'hsl(' + hue + ', 100%, 50%)';
}
As you can see I changed the API a bit. The parameters are as follows:
percentage
: a value between 0 and 1hue0
: the hue value of the color you want to get when the percentage
is 0hue1
: the hue value of the color you want to get when the percentage
is 1Also, there is no longer a need to calculate the rgb value, modern browsers support hsl values as is.
So now you can use the method as follows:
// green(120) to red(0)
color = percentageToHsl(perc, 120, 0);
// blue(225) to pink(315)
color = percentageToHsl(perc, 225, 315);
// blue (225) to yellow(45 + 360)
color = percentageToHsl(perc, 225, 405);
So if you want to go clockwise you have to make hue0 < hue1. If you want to go counter clockwise you have to make hue0 > hue1. And since these are degrees, you can just add or subtract 360 to force the direction. You can even use this technique to wrap around the hue circle multiple times.
I've created a new fiddle to demonstrate: https://jsfiddle.net/r438s65s/
The answer by Pevara is great. I have adapted his jsfiddle to my needs, and maybe it is useful for others too: http://jsfiddle.net/rE6Rk/8/
It allows to have an uneven distribution of colors. In my case I wanted everything below 0.5 (50) to be red. And a 0.75 would be in the middle between red and green. So instead of working with hard borders 0 and 1, they can both be shifted.
The changes are in the numberToColorHsl() function only: * the i is a floating point 0-1 instead of the int 0-100 * additional params min/max
/**
* Convert a number to a color using hsl, with range definition.
* Example: if min/max are 0/1, and i is 0.75, the color is closer to green.
* Example: if min/max are 0.5/1, and i is 0.75, the color is in the middle between red and green.
* @param i (floating point, range 0 to 1)
* param min (floating point, range 0 to 1, all i at and below this is red)
* param max (floating point, range 0 to 1, all i at and above this is green)
*/
function numberToColorHsl(i, min, max) {
var ratio = i;
if (min> 0 || max < 1) {
if (i < min) {
ratio = 0;
} else if (i > max) {
ratio = 1;
} else {
var range = max - min;
ratio = (i-min) / range;
}
}
// as the function expects a value between 0 and 1, and red = 0° and green = 120°
// we convert the input to the appropriate hue value
var hue = ratio * 1.2 / 3.60;
//if (minMaxFactor!=1) hue /= minMaxFactor;
//console.log(hue);
// we convert hsl to rgb (saturation 100%, lightness 50%)
var rgb = hslToRgb(hue, 1, .5);
// we format to css value and return
return 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
}
The visuals explain it better than words.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With