为输入范围生成红色和绿色之间的颜色

时间:2012-08-07 15:34:42

标签: javascript colors range interpolation

  

可能重复:
  Color coding based on number

我希望用户能够从1-100的范围中进行选择,其中当数字小于50时,区域的颜色变为深绿色,并且当颜色变得接近100时,颜色变得更红了。

我试图让它变得更加朝向中心的范围,颜色应该接近白色(其中50 =全白)。

我从这里尝试了答案:Generate colors between red and green for a power meter?无济于事...... 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的许多不同组合,但我似乎无法做到正确。

3 个答案:

答案 0 :(得分:41)

由于你在RBG空间中创建渐变的方式,你得到了混乱的绿色。要获得“更干净”的渐变,您可以使用上面提到的HSV模型in the answer of the question you linked to

RGB渐变(顶部)vs HSV(底部) top gradient uses RGB, bottom uses HSV

通过将H(色调)值缩放到0(红色)和120(绿色)之间,您将获得良好的干净过渡。但是,在中点(60),你会得到明亮的黄色,而不是你想要的白色。你可以通过修改S(饱和度)值来解决这个问题 - 在0饱和度时,你最终会得到白色(1会给你全色饱和度。

这是一个粗略的例子,当输入值从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。使用jquery-colors可以很容易地在颜色模型之间进行转换,尽管自己滚动并不是很难。

答案 1 :(得分:14)

我在here的帮助下得出了这个答案,http://jsfiddle.net/maniator/tKrM9/53/使用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']");​

小提琴:{{3}}

答案 2 :(得分:4)

以一种非常手工的方式,我想我会这样做:

使1-50的范围具有最大绿色(FF),红色和蓝色的缩放值范围从00表示红色,蓝色表示1,一直到FF表示红色,蓝色表示50表示。 / p>

(样品值:1 - > 00FF00,25 - > 7FFF7F,50 - > FFFFFF)

然后从51-100开始,在FF处保持红色,同时缩小蓝色和绿色,使蓝色和绿色在达到100时接近0.

(样品值:51-> FFFFFF,75-> FF7F7F,100-> FF0000)

这保证在0时为白色,白色为50,红色为100。

介于两者之间的区域可能并不完美,只是因为眼睛不同地解释不同的颜色强度(我们在某些颜色上比其他颜色更好),但它应该让你非常接近。

我将你的小提琴中的代码修改为以下内容,它完成了我所描述的内容:

$(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']");