web-dev-qa-db-fra.com

Générez des couleurs entre le rouge et le vert pour une plage d'entrée

Duplicata possible:
Codage couleur basé sur le nombre

Je veux qu'un utilisateur puisse choisir parmi une plage de 1 à 100, où lorsque les nombres deviennent inférieurs à 50, la couleur de la zone devient vert plus foncé et lorsque la couleur se rapproche de 100, la couleur devient plus rouge .

J'essaie de faire en sorte que comme la plage soit plus vers le centre, la couleur doit être proche du blanc (où 50 = blanc complet).

J'ai essayé la réponse d'ici: Générer des couleurs entre le rouge et le vert pour un wattmètre? en vain .... 50 finit par être un vert confus ...

J'ai le html suivant:

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

Et le javascript suivant:

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

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

J'ai essayé de nombreuses combinaisons différentes de r, g, b mais je n'arrive vraiment pas à faire les choses correctement.

25
Neal

J'ai trouvé cette réponse avec l'aide de ici , qui utilise une fonction Interpolate dans laquelle je peux facilement définir les couleurs de début et de fin.

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

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

14
Neal

Vous obtenez le vert confus à cause de la façon dont vous créez votre dégradé dans l'espace RBG. Pour obtenir un gradient "plus propre", vous pouvez utiliser le modèle HSV comme mentionné dans la réponse à la question à laquelle vous avez lié .

Gradient RVB (haut) vs HSV (bas) top gradient uses RGB, bottom uses HSV

En ajustant la valeur H (teinte) entre 0 (rouge) et 120 (vert), vous obtiendrez une transition nette et agréable. Cependant, au point médian (60), vous vous retrouverez avec du jaune vif au lieu du blanc souhaité. Vous pouvez résoudre ce problème en modifiant la valeur S (saturation) - à 0 saturation, vous vous retrouverez avec du blanc (1 vous donne une saturation pleine couleur.

Voici un exemple grossier qui met à l'échelle la saturation de 1 à 0 et revient à 1 lorsque la valeur d'entrée passe de 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. La conversion entre les modèles de couleurs est facile à utiliser jquery-colors , bien qu'il ne soit pas trop difficile de rouler le vôtre.

42
Shawn Chin

D'une manière très ondulée, je pense que je le ferais de cette façon:

Faites de la plage de 1 à 50 un maximum de vert (FF) et une valeur mise à l'échelle pour le rouge et le bleu allant de 00 pour le rouge et le bleu à 1, jusqu'à FF pour le rouge et le bleu à 50.

(Exemples de valeurs: 1 -> 00FF00, 25 -> 7FFF7F, 50 -> FFFFFF)

Ensuite, de 51 à 100, gardez le rouge à FF, tout en reculant le bleu et le vert pour que le bleu et le vert approchent de 0 lorsque vous atteignez 100.

(Exemples de valeurs: 51 -> FFFFFF, 75 -> FF7F7F, 100 -> FF0000)

Cela vous garantit un vert brillant à 0, un blanc à 50 et un rouge à 100.

Les zones intermédiaires ne sont peut-être pas parfaitement parfaites, simplement parce que l'œil interprète différemment les différentes intensités de couleur (nous sommes meilleurs pour certaines couleurs que pour d'autres), mais cela devrait vous rapprocher assez.

J'ai modifié le code de votre violon comme suit, et il fait ce que je décris:

$(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
Beska