从绿色到红色取决于百分比

我有一个投票系统,我希望这个投票的答案是有色人种的。 例如: 如果是10% 就是红色,如果是40% 就是黄色,如果是80% 就是绿色,所以我希望我的 javascript 代码使用 rgb 颜色来根据给定的百分比生成一个颜色。

function hexFromRGB(r, g, b) {
var hex = [
r.toString( 16 ),
g.toString( 16 ),
b.toString( 16 )
];
$.each( hex, function( nr, val ) {
if ( val.length === 1 ) {
hex[ nr ] = "0" + val;
}
});
return hex.join( "" ).toUpperCase();
}

现在我要百分比的巫术。

86568 次浏览
function hexFromRGBPercent(r, g, b) {
var hex = [
Math.floor(r / 100 * 255).toString( 16 ),
Math.floor(g / 100 * 255).toString( 16 ),
Math.floor(b / 100 * 255).toString( 16 )
];
$.each( hex, function( nr, val ) {
if ( val.length === 1 ) {
hex[ nr ] = "0" + val;
}
});
return hex.join( "" ).toUpperCase();
}

这要归功于 Andrew 他更快。

这可能超出了您的需要,但是它允许您设置任意颜色的映射:

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
};

修改雅各布代码中的这两行:

var lower = percentColors[i - 1];
var upper = percentColors[i];

to:

var lower = (i === 0) ?  percentColors[i] : percentColors[i - 1];
var upper = (i === 0) ? percentColors[i + 1] : percentColors[i];

如果你想让它适用于两个极端(即0.0和1.0)。

Based on Jacobs answer I made a loadbar. 这个是从绿色到红色,但是你可以改变颜色。 对于那些感兴趣的人,这里是我的代码和 jsfiddle (http://jsfiddle.net/rxR3x/)

var percentColors = [
{ pct: 0, color: '#00FF00' },   { pct: 3, color: '#12FF00' },   { pct: 6, color: '#24FF00' },
{ pct: 10, color: '#47FF00' },  { pct: 13, color: '#58FF00' },  { pct: 16, color: '#6AFF00' },
{ pct: 20, color: '#7CFF00' },  { pct: 23, color: '#8DFF00' },  { pct: 26, color: '#9FFF00' },
{ pct: 30, color: '#B0FF00' },  { pct: 33, color: '#C2FF00' },  { pct: 36, color: '#D4FF00' },
{ pct: 40, color: '#E5FF00' },  { pct: 43, color: '#F7FF00' },  { pct: 46, color: '#FFF600' },
{ pct: 50, color: '#FFE400' },  { pct: 53, color: '#FFD300' },  { pct: 56, color: '#FFC100' },
{ pct: 60, color: '#FFAF00' },  { pct: 63, color: '#FF9E00' },  { pct: 66, color: '#FF8C00' },
{ pct: 70, color: '#FF7B00' },  { pct: 73, color: '#FF6900' },  { pct: 76, color: '#FF5700' },
{ pct: 80, color: '#FF4600' },  { pct: 83, color: '#FF3400' },  { pct: 86, color: '#FF2300' },
{ pct: 90, color: '#FF1100' },  { pct: 93, color: '#FF0000' },  { pct: 96, color: '#FF0000' },
{ pct: 100, color: '#FF0000' }
];
var getColorPercent = function(selector, percent, time){
var i = 0;
var percentInterval = setInterval(function() {
i++;
if(percent >= percentColors[i].pct) {
console.log(percentColors[i].color);
$(selector).css('background-color', percentColors[i].color);
}
if(percentColors[i].pct>=percent) {
clearInterval(percentInterval);
}
}, time/25);
$(selector).animate({width:(200/100)*percent}, time);
}
getColorPercent('#loadbar_storage', 100, 1500);

var percentColors = [
{ pct: 0, color: '#00FF00' },	{ pct: 3, color: '#12FF00' },	{ pct: 6, color: '#24FF00' },
{ pct: 10, color: '#47FF00' },	{ pct: 13, color: '#58FF00' },	{ pct: 16, color: '#6AFF00' },
{ pct: 20, color: '#7CFF00' },	{ pct: 23, color: '#8DFF00' },	{ pct: 26, color: '#9FFF00' },
{ pct: 30, color: '#B0FF00' },	{ pct: 33, color: '#C2FF00' },	{ pct: 36, color: '#D4FF00' },
{ pct: 40, color: '#E5FF00' },	{ pct: 43, color: '#F7FF00' },	{ pct: 46, color: '#FFF600' },
{ pct: 50, color: '#FFE400' },	{ pct: 53, color: '#FFD300' },	{ pct: 56, color: '#FFC100' },
{ pct: 60, color: '#FFAF00' },	{ pct: 63, color: '#FF9E00' },	{ pct: 66, color: '#FF8C00' },
{ pct: 70, color: '#FF7B00' },	{ pct: 73, color: '#FF6900' },	{ pct: 76, color: '#FF5700' },
{ pct: 80, color: '#FF4600' },	{ pct: 83, color: '#FF3400' },	{ pct: 86, color: '#FF2300' },
{ pct: 90, color: '#FF1100' },	{ pct: 93, color: '#FF0000' },	{ pct: 96, color: '#FF0000' },
{ pct: 100, color: '#FF0000' }
];
var getColorPercent = function(selector, percent, time) {
var i = 0;
var percentInterval = setInterval(function() {
i++;
if (percent >= percentColors[i].pct) {
$(selector).css('background-color', percentColors[i].color);
}
if (percentColors[i].pct >= percent) {
clearInterval(percentInterval);
}
}, time / 25);
$(selector).animate({
width: (200 / 100) * percent
}, time);
}
getColorPercent('#loadbar', 100, 1500);
#loadbar_wrapper {
width: 200px;
height: 25px;
border: 1px solid #CECECE;
}


#loadbar {
width: 0px;
height: 25px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="loadbar_wrapper">
<div id="loadbar"></div>
</div>

您可以在几行代码(不包括注释)中完成此操作,而不需要任何颜色映射。

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
*/

例子: https://jsfiddle.net/x363g1yc/634/

不需要颜色映射(除非它是一个非线性颜色变化,这是没有要求)

警告: 这与 IE8或以下版本不兼容。(感谢 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>

一个使用 HSL 和小提琴的简单方案:

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 翻译: 小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴,小提琴.

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);
}

这种方法在这种情况下工作得很好(百分比从0到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)';
}

HSL will work in IE8 using jquery-ui-1.10.4.

我修改了 jongo45的答案以接受函数中的轻量级。

function getColor(value, lightness) {
//value from 0 to 1
var hue = ((value) * 120).toString(10);
return ["hsl(", hue, ",100%,", lightness, "%)"].join("");
}

This is what I came up with:

function rgbify(maxval, minval, val, moreisgood) {
var intnsty = (val - minval) / (maxval - minval);
var r, g;
if (moreisgood) {
if (intnsty > 0.5) {
g = 255;
r = Math.round(2 * (1 - intnsty) * 255);
} else {
r = 255;
g = Math.round(2 * intnsty * 255);
}


} else { //lessisgood
if (intnsty > 0.5) {
r = 255;
g = Math.round(2 * (1 - intnsty) * 255);
} else {
g = 255;
r = Math.round(2 * intnsty * 255);
}
}
return "rgb(" + r.toString() + ", " + g.toString() + ", 0)";
}

Jsfiddle

如果较高的值应该是红色或绿色,则 moreisgood标志将切换。 maxvalminval是范围的阈值。 val是要转换为 rgb 的值

Mattisdada 的代码对我来说真的很有帮助,当时我正在制作一个图表来显示一些测验结果的统计数据。我稍微修改了一下,以允许“剪切”百分比(不确定正确的术语是什么) ,并沿着颜色轮两边工作,例如从绿色(120)到红色(0) ,反之亦然。

function pickColourByScale(percent, clip, saturation, start, end)
{
var a = (percent <= clip) ? 0 : (((percent - clip) / (100 - clip))),
b = Math.abs(end - start) * a,
c = (end > start) ? (start + b) : (start - b);
return 'hsl(' + c + ','+ saturation +'%,50%)';
}

基本上,通过设置一个百分比值来剪切缩放,低于这个值的所有东西都会被着色为你的开始颜色。它还根据100% 剪辑重新计算缩放。

让我们来看一个示例场景,其中输入以下值:

  • 百分比: 75
  • 剪辑: 50
  • 饱和度: 100(不重要,我用它来突出显示 Chart.js 图表)
  • 开始: 0(红色)
  • 完: 120(绿色)

    1. 我检查百分比是否小于剪辑,如果是,返回0% 。否则,我重新计算百分比-75% 是50% 和100% 之间的一半,所以我得到50% 。这是0.5。
    2. 我知道开始和结束的区别。您需要使用 Math.abs () ,以防开始色调值大于结束色调值。然后将差值乘以步骤1中得到的结果,看看需要偏移多少起始色调值。
    3. 如果开始值大于结束值,那么您需要沿着色轮朝相反的方向移动。相应地加入或减去起始值。

最后是黄色,介于红色和绿色之间。如果我没有在步骤1中重新计算,我会得到一个更绿的颜色,这可能会误导。

我知道这有点跑题,但我找到了另一种方法。

要做到这一点,你也可以创建一个100x1维度的动态画布,并应用梯度到它,然后从功能,你只需要得到像素颜色的百分比位置。

密码如下: 这是全球性的:

/* dynamic canvas */


// this should be done once in a page so out of function, makes function faster
var colorBook = $('<canvas />')[0];
colorBook.width = 101;
colorBook.height = 1;
var ctx = colorBook.getContext("2d");
var grd = ctx.createLinearGradient(0, 0, 101, 0);
grd.addColorStop(0, "rgb(255,0,0)"); //red
grd.addColorStop(0.5, "rgb(255,255,0)"); //yellow
grd.addColorStop(1, "rgb(0,255,0)"); //green
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 101, 1);

Then the function:

function getColor(value) {
return 'rgba(' + ctx.getImageData(Math.round(value), 0, 1, 1).data.join() + ')';
}

演示: https://jsfiddle.net/asu09csj/

使用 HLS 从 red变为 green颜色。该值应该从0到100,在本例中是模拟百分比(%)。

function getColorFromRedToGreenByPercentage(value) {
const hue = Math.round(value);
return ["hsl(", hue, ", 50%, 50%)"].join("");
}

我知道这最初是一个旧的 javascript 问题,但是我在这里搜索 只有 CSS 解决方案,所以也许它同样可以帮助其他人: 其实很简单:

使用百分比作为 HSL 颜色值! 红色到绿色跨度 H 从 0128。(如果你愿意,你可以通过 1.2来提高这个百分比)。例如:

background-color:hsl(perc,100%,50%);

Perc 只是一个数字,没有 %符号。

我修改了 zmc 的答案,给出了从绿色(0%)到红色(100%)的渐变。

const getGreenToRed = (percent) => {
const r = (255 * percent) / 100;
const g = 255 - (255 * percent) / 100;
return 'rgb(' + r + ',' + g + ',0)';
};

编辑:

几年后再来看看... 这是一个对任何颜色都更灵活的实现。

const interpolateBetweenColors = (
fromColor,
toColor,
percent
) => {
const delta = percent / 100;
const r = Math.round(toColor.r + (fromColor.r - toColor.r) * delta);
const g = Math.round(toColor.g + (fromColor.g - toColor.g) * delta);
const b = Math.round(toColor.b + (fromColor.b - toColor.b) * delta);


return `rgb(${r}, ${g}, ${b})`;
};


const patches = document.getElementById('patches');


for (let i = 0; i <= 100; i += 5) {
const color = interpolateBetweenColors(
{ r: 0, g: 255, b: 0 },
{ r: 255, g: 0, b: 0 },
i
);
  

const patch = document.createElement('div');
patch.style.backgroundColor = color;
patch.style.width = '100px';
patch.style.height = '10px';
patches.appendChild(patch);
}
<div id="patches"></div>

使用与雅各布的最佳答案相似的逻辑,

我已经创建了一个 Javascript color-scales来处理它。您还可以输入多个颜色停止,以及设置一个透明度水平。

现场演示: https://codepen.io/dalisc/pen/yLVXoeR

包的链接在这里: https://www.npmjs.com/package/color-scales

示例用法:

const ColorScale = require("color-scales");
let colorScale = new ColorScale(0, 100, ["#ffffff", "#000000"], 0.5);
let rgbaStr = colorScale.getColor(50).toRGBAString(); // returns "rgba(127,127,127, 0.5)"

该包能够根据您的需要输出十六进制、 rgb 或 rgba 字符串。它还可以输出一个自定义 Color 对象({ r,g,b,a }) ,以备您需要挑选单个颜色组件时使用。

我在基于 Javascript 的应用程序上模仿 Tableau 仪表板时遇到过类似的问题。我意识到这是 Tableau 和 Microsoft Excel 等数据可视化工具的一个共同特性,所以我创建了一个 npm 包来在 Javascript 应用程序上处理它。如果希望减少代码,可以使用该包。