Generowanie kolorów między czerwonym i zielonym dla zakresu wejściowego [duplikat]

Możliwy duplikat:
kodowanie kolorów na podstawie liczby

Chcę, aby użytkownik mógł wybierać z zakresu od 1-100, gdzie gdy liczby stają się mniejsze niż 50, kolor obszaru staje się ciemniejszy zielony, a gdy kolor staje się bliżej 100, kolor staje się bardziej czerwony.

Staram się zrobić to tak, aby jako zakres bardziej w kierunku środka, kolor powinien być zbliżony do białego (gdzie 50 = pełna Biel).

Próbowałem odpowiedź stąd: wygenerować Kolory między czerwonym i zielonym dla miernika mocy? bezskutecznie.... 50 kończy się mętną zielenią...

Mam następujący html:

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

I następujące 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/

Próbowałem wielu różnych kombinacji r, g, b, ale naprawdę nie wydaje mi się, aby to dobrze.

Author: Community, 2012-08-07

3 answers

Dostajesz mętną zieleń ze względu na sposób, w jaki tworzysz gradient w przestrzeni RBG. Aby uzyskać "czystszy" gradient, możesz użyć modelu HSV, jak wspomniano w odpowiedzi na pytanie, do którego podlinkowałeś .

gradient RGB (Góra) vs HSV (dół)górny gradient wykorzystuje RGB, dolny HSV

Skalując wartość H (odcień) między 0 (czerwony) a 120 (zielony), uzyskasz ładne, czyste Przejście. Jednak w środkowym punkcie (60) skończysz z jasnożółtym zamiast zamierzonego biały. Możesz to rozwiązać, modyfikując wartość s (saturation) - przy nasyceniu 0 skończysz na białym (1 daje pełne nasycenie kolorów.

Oto prosty przykład, który skaluje nasycenie z 1 do 0 i z powrotem do 1, gdy wartość wejściowa przechodzi z 0 do 50 do 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. konwersja pomiędzy modelami kolorów jest łatwa przy użyciu jquery-colors , chociaż nie jest zbyt trudna do przewijania.

 40
Author: Shawn Chin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:23

Wymyśliłem tę odpowiedź z pomocą TUTAJ , który używa funkcji Interpolate, w której mogę łatwo ustawić początek i koniec kolorów.

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/

 13
Author: Neal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:05

W bardzo ręczny sposób, myślę, że zrobiłbym to w ten sposób:

Aby zakres od 1-50 miał maksymalną wartość zieloną (FF), a skalowana wartość dla Czerwonego i niebieskiego wynosi od 00 dla Czerwonego i niebieskiego przy 1, aż do FF dla Czerwonego i niebieskiego przy 50.

(przykładowe wartości: 1 -> 00FF00, 25 -> 7FFF7F, 50 - > FFFFFF)

Następnie od 51-100 trzymaj czerwony na FF, jednocześnie skalując niebieski i zielony, aby niebieski i zielony zbliżyły się do 0, gdy osiągniesz 100.

(przykładowe wartości: 51 ->FFFFFF, 75 - > FF7F7F, 100 - > FF0000)

To gwarantuje, że będziesz błyszczący zielony na 0, biały na 50, a czerwony na 100.

Obszary pomiędzy mogą nie być idealne, po prostu dlatego, że oko inaczej interpretuje różne intensywności kolorów( w niektórych kolorach jesteśmy lepsi niż w innych), ale powinno cię to zbliżyć.

Zmodyfikowałem kod w Twoim fiddle na następujący i robi to, co opisuję:

$(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']");
 4
Author: Beska,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-07 16:02:03