代码之家  ›  专栏  ›  技术社区  ›  Naftali

为输入范围生成介于红色和绿色之间的颜色[重复]

  •  32
  • Naftali  · 技术社区  · 14 年前

    可能重复:
    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 回复  |  直到 9 年前
        1
  •  47
  •   Community Mohan Dere    9 年前

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

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

    通过在0(红色)和120(绿色)之间缩放H(色调)值,您将获得一个很好的干净过渡。然而,在中点(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 ,尽管自己滚动并不太难。

        2
  •  16
  •   Community Mohan Dere    9 年前

    我在一些人的帮助下得出了这个答案 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']");​
    

    小提琴: http://jsfiddle.net/maniator/tKrM9/53/

        3
  •  5
  •   Beska    14 年前

    以一种非常波浪形的方式,我想我会这样做:

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

    (样本值:1->00FF00、25->7FFF7F、50->FFFFFF)

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

    (样本值:51->FFFFFF,75->FF7F7F,100->FF 0000)

    这保证在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']");