在输入范围内生成红色和绿色之间的颜色。

32

可能是重复问题:
基于数字的颜色编码

我希望用户可以从1-100的范围内进行选择,当数字小于50时,区域的颜色变得更深绿,而随着数字接近100,颜色则变成更接近红色。

我试图让当数值趋向于中心时,颜色应该接近白色(其中50=全白)。

我尝试了这里的答案:如何生成在红色和绿色之间的颜色来表示功率?,但没有成功... 50最终变成了一种混淆的绿色...

以下是我的HTML代码:

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

以下是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']");​

示例代码:http://jsfiddle.net/maniator/tKrM9/1/

我已经尝试了许多不同的 r、g、b 组合,但似乎总是得不到正确的结果。


2
@Jean-FrançoisCorbett 你到底是什么意思? - Naftali
3个回答

47
您之所以得到混浊的绿色,是因为您在RGB空间中创建渐变的方式。要获得更清晰的渐变,您可以使用HSV模型,如您链接的问题的答案中所提到的
通过将H(色相)值在0(红色)和120(绿色)之间缩放,您将获得一个漂亮干净的过渡。然而,在中点(60)处,您将得到明亮的黄色,而不是您打算的白色。您可以通过修改S(饱和度)值来解决这个问题-在0饱和度时,您将得到白色(1会给您完全的颜色饱和度)。
这里有一个简单的示例,它将饱和度从1缩放到0,再从0缩放到1,当输入值从0到50到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. 使用jquery-colors很容易转换颜色模型,尽管自己编写也不太难。


16

我在这里得到了一些帮助,使用了一个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']");​

示例代码:http://jsfiddle.net/maniator/tKrM9/53/


+1 正是我正在寻找的。非常好的解决方案。 - Danscho

5
以一种非常模糊的方式,我认为我会这样做:
使范围从1到50具有最大的绿色(FF),并且红色和蓝色的缩放值分别从1的00开始,一直到50时红色和蓝色都为FF。
(示例值:1-> 00FF00,25-> 7FFF7F,50-> FFFFFF)
然后在51-100之间,保持红色为FF,同时缩小蓝色和绿色,使得当达到100时,蓝色和绿色趋近于0。
(示例值:51-> FFFFFF,75-> FF7F7F,100-> FF0000)
这保证了在0处有亮绿色,在50处有白色,在100处有红色。
中间的区域可能不完美,只是因为眼睛对不同颜色强度的解释不同(我们对某些颜色比其他颜色更敏感),但它应该能让你接近理想效果。
我修改了您fiddle中的代码如下,并且实现了我所描述的效果:
$(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']");

1
你有可以给我看的例子吗? :-) - Naftali
@Neal 添加了一个代码示例,可以放入你的fiddle中。(我将var引用更改为全局变量,但这很容易修复。) - Beska
你的解决方案可行 :-) 我添加了我自己的解决方案,可以让我对颜色更加灵活 :-) - Naftali

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接