Подтвердить что ты не робот

Генерировать цвета между красным и зеленым для диапазона ввода

Возможный дубликат:
Цветовое кодирование на основе номера

Я хочу, чтобы пользователь мог выбирать из диапазона от 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']");​

Fiddle: http://jsfiddle.net/maniator/tKrM9/1/

Я пробовал много разных комбинаций r, g, b, но я действительно не могу понять, как это правильно.

4b9b3361

Ответ 1

Я придумал этот ответ с помощью здесь, в котором используется функция 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']");​

Fiddle: http://jsfiddle.net/maniator/tKrM9/53/

Ответ 2

Вы получаете путаную зелень из-за того, как вы создаете свой градиент в пространстве RBG. Чтобы получить "более чистый" градиент, вы можете использовать модель HSV, как указано в ответе на вопрос, который вы связали с.

Градиент RGB (сверху) против HSV (внизу)top gradient uses RGB, bottom uses HSV

При масштабировании значения H (оттенок) между 0 (красный) и 120 (зеленый) вы получите хороший чистый переход. Однако в середине (60) вы получите яркий желтый цвет, а не ваш белый. Вы можете решить эту проблему, изменив значение S (насыщенность) - при насыщении 0, вы получите белый цвет (1 дает полную насыщенность цвета).

Вот грубый пример, который масштабирует насыщенность от 1 до 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, хотя это не слишком сложно, чтобы катить свои собственные.

Ответ 3

В очень ручном волнообразном способе, я думаю, я сделаю так:

Сделать диапазон от 1 до 50 максимальным зеленым (FF) и масштабированным значением для красного и синего в диапазоне от 00 для красного и синего в 1, вплоть до FF для красного и синего в 50.

(Пример значений: 1 → 00FF00, 25 → 7FFF7F, 50 → FFFFFF)

Затем из 51-100 держите красный цвет в FF, уменьшая яркость синего и зеленого цветов так, чтобы синий и зеленый приближались 0 до 100.

(Пример значений: 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']");