from green to red color depend on percentage
A simple scheme using HSL along with fiddle:
function getColor(value){
//value from 0 to 1
var hue=((1-value)*120).toString(10);
return ["hsl(",hue,",100%,50%)"].join("");
}
tweak saturation and luminosity as needed. and a fiddle.
function getColor(value) {
//value from 0 to 1
var hue = ((1 - value) * 120).toString(10);
return ["hsl(", hue, ",100%,50%)"].join("");
}
var len = 20;
for (var i = 0; i <= len; i++) {
var value = i / len;
var d = document.createElement('div');
d.textContent = "value=" + value;
d.style.backgroundColor = getColor(value);
document.body.appendChild(d);
}
This may be more than you need, but this lets you set up any arbitrary color map:
var percentColors = [
{ pct: 0.0, color: { r: 0xff, g: 0x00, b: 0 } },
{ pct: 0.5, color: { r: 0xff, g: 0xff, b: 0 } },
{ pct: 1.0, color: { r: 0x00, g: 0xff, b: 0 } } ];
var getColorForPercentage = function(pct) {
for (var i = 1; i < percentColors.length - 1; i++) {
if (pct < percentColors[i].pct) {
break;
}
}
var lower = percentColors[i - 1];
var upper = percentColors[i];
var range = upper.pct - lower.pct;
var rangePct = (pct - lower.pct) / range;
var pctLower = 1 - rangePct;
var pctUpper = rangePct;
var color = {
r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper),
g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper),
b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper)
};
return 'rgb(' + [color.r, color.g, color.b].join(',') + ')';
// or output as hex if preferred
};
You can do this in a few lines of code (not including comments) without the need for any color maps.
function hsl_col_perc(percent, start, end) {
var a = percent / 100,
b = (end - start) * a,
c = b + start;
// Return a CSS HSL string
return 'hsl('+c+', 100%, 50%)';
}
//Change the start and end values to reflect the hue map
//Refernece : http://www.ncl.ucar.edu/Applications/Images/colormap_6_3_lg.png
/*
Quick ref:
0 – red
60 – yellow
120 – green
180 – turquoise
240 – blue
300 – pink
360 – red
*/
Example: https://jsfiddle.net/x363g1yc/634/
No need for color maps (Unless it is a non-linear color change, which was not asked)
Warning: This is not compatible with IE8 or below. (Thanks Bernhard Fürst)
// Just used as a shortcut for below, completely optional
const red = 0,
yellow = 60,
green = 120,
turquoise = 180,
blue = 240,
pink = 300;
function hsl_col_perc(percent, start, end) {
var a = percent / 100,
b = (end - start) * a,
c = b + start;
// Return a CSS HSL string
return 'hsl(' + c + ', 100%, 50%)';
}
// Simple little animation
var percent = 0,
progressDiv = document.getElementById('progress'),
textDiv = document.getElementById('progress-text'),
progressContainerDiv = document.getElementById('progress-container')
function step(timestamp) {
percent = (percent < 100) ? percent + 0.5 : 0;
// Play with me!
let colour = hsl_col_perc(percent, red, green); //Red -> Green
progressDiv.style.backgroundColor = colour;
progressContainerDiv.style.borderColor = colour;
progressDiv.style.width = percent + '%';
textDiv.innerHTML = Math.floor(percent);
window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
#progress {
width: 0%;
white-space: nowrap;
text-wrap: none;
height: 50px;
}
#progress-container {
border: solid 2px black;
width: 200px;
}
<h1 id="progress-text"></h1>
<div id="progress-container">
<div id="progress"></div>
</div>
This method works well in this case (percent from 0 to 100):
function getGreenToRed(percent){
r = percent<50 ? 255 : Math.floor(255-(percent*2-100)*255/100);
g = percent>50 ? 255 : Math.floor((percent*2)*255/100);
return 'rgb('+r+','+g+',0)';
}
I know this is originally an old javascript question, but I got here searching for CSS only solution, so maybe it will help others equally: It's actually quite simple:
Use the percentage as a HSL color value!
Red to Green spans H from 0
to 128
.(so you can pump the percentage up by 1.2
if you want). Example:
background-color:hsl(perc,100%,50%);
Where perc is just the number, without the %
sign.