Javascript 为输入范围生成红色和绿色之间的颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11849308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Generate colors between red and green for an input range
提问by Naftali aka Neal
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.
我希望用户能够从 1-100 的范围中进行选择,当数字小于 50 时,该区域的颜色变得更深绿色,并且随着颜色变得接近 100,颜色变得更红.
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).
我试图使范围更接近中心,颜色应该接近白色(其中 50 = 全白)。
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...
我从这里尝试了答案:为功率计生成红色和绿色之间的颜色?无济于事.... 50 最终成为一个混乱的绿色...
I have the following html:
我有以下 html:
<span><span class="value">50</span><input type="range" /></span>?
And the following javascript:
以及以下 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/
小提琴: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.
我尝试了许多不同的 r,g,b 组合,但我似乎真的做对了。
采纳答案by Naftali aka Neal
I came up with this answer with some help from here, which uses an Interpolate
function in which I can set the start and end colors easily.
我在here的一些帮助下想出了这个答案,它使用了一个Interpolate
可以轻松设置开始和结束颜色的功能。
function Interpolate(start, end, steps, count) {
var s = start,
e = end,
final = s + (((e - s) / steps) * count);
return Math.floor(final);
}
function Color(_r, _g, _b) {
var r, g, b;
var setColors = function(_r, _g, _b) {
r = _r;
g = _g;
b = _b;
};
setColors(_r, _g, _b);
this.getColors = function() {
var colors = {
r: r,
g: g,
b: b
};
return colors;
};
}
$(document).on({
change: function(e) {
var self = this,
span = $(self).parent("span"),
val = parseInt(self.value),
red = new Color(232, 9, 26),
white = new Color(255, 255, 255),
green = new Color(6, 170, 60),
start = green,
end = white;
$(".value", span).text(val);
if (val > 50) {
start = white,
end = red;
val = val % 51;
}
var startColors = start.getColors(),
endColors = end.getColors();
var r = Interpolate(startColors.r, endColors.r, 50, val);
var g = Interpolate(startColors.g, endColors.g, 50, val);
var b = Interpolate(startColors.b, endColors.b, 50, val);
span.css({
backgroundColor: "rgb(" + r + "," + g + "," + b + ")"
});
}
}, "input[type='range']");?
回答by Shawn Chin
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.
由于您在 RBG 空间中创建渐变的方式,您得到了混乱的绿色。要获得“更干净”的渐变,您可以使用链接到的问题的答案中提到的 HSV 模型。
RGB gradient (top) vs HSV (bottom)
RGB 渐变(顶部)与 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.
通过在 0(红色)和 120(绿色)之间缩放 H(色调)值,您将获得一个漂亮干净的过渡。但是,在中点 (60) 处,您最终会得到亮黄色而不是您想要的白色。您可以通过修改 S(饱和度)值来解决这个问题——在 0 饱和度时,您最终会得到白色(1 为您提供全色饱和度。
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/
这是一个粗略的例子,当输入值从 0 到 50 到 100 时,将饱和度从 1 缩放到 0 再缩放回 1 - 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.
ps 使用jquery-colors可以轻松地在颜色模型之间进行转换,尽管推出自己的模型并不难。
回答by Beska
In a very hand wavy way, I think I would do it this way:
以一种非常手动的方式,我想我会这样做:
Make the range from 1-50 have maximum green (FF), and a scaled value for both red and blue ranging from 00 for red and blue at 1, all the way up to FF for red and blue at 50.
使 1-50 的范围具有最大绿色 (FF),红色和蓝色的缩放值范围从 00 代表红色和蓝色为 1,一直到 FF 代表红色和蓝色为 50。
(Sample values: 1 -> 00FF00, 25 -> 7FFF7F, 50 -> FFFFFF)
(示例值:1 -> 00FF00、25 -> 7FFF7F、50 -> FFFFFF)
Then from 51-100, keep red at FF, while scaling back blue and green so that blue and green approach 0 as you reach 100.
然后从 51 到 100,将红色保持在 FF,同时缩小蓝色和绿色,以便在达到 100 时蓝色和绿色接近 0。
(Sample values: 51 -> FFFFFF, 75 -> FF7F7F, 100 -> FF0000)
(样本值:51 -> FFFFFF,75 -> FF7F7F,100 -> FF0000)
This is guaranteed to give you brilliant green at 0, white at 50, and red at 100.
这可以保证在 0 时为您提供亮绿色,在 50 时为白色,在 100 时为您提供红色。
The areas in between may not be exactly perfect, simply because the eye interprets different color intensities differently (we're better at some colors than others), but it should get you pretty close.
两者之间的区域可能并不完全完美,仅仅是因为眼睛对不同颜色强度的解释不同(我们在某些颜色上比其他颜色更好),但它应该让你非常接近。
I modified the code in your fiddle to the following, and it does what I describe:
我将您小提琴中的代码修改为以下内容,它执行我所描述的:
$(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);
if (val <= 50)
{
r = Math.floor((255 * (val / 50))),
g = 255,
b = Math.floor((255 * (val / 50)));
}
else
{
r = 255,
g = Math.floor((100 - val) / 50 * 255),
b = Math.floor((100 - val) / 50 * 255);
}
span.css({
backgroundColor: "rgb(" + r + "," + g + "," + b + ")"
});
}
}, "input[type='range']");