від зеленого до червоного кольору залежить від відсотка


84

У мене є система опитування, і я хочу, щоб відповіді на це опитування були кольоровими. Наприклад: якщо це 10%, то це буде червоний, якщо 40% - жовтий, а якщо 80% - зелений, то я хочу, щоб мій код JavaScript використовував кольори rgb для створення кольору відповідно до заданого відсотка.

function hexFromRGB(r, g, b) {
    var hex = [
        r.toString( 16 ),
        g.toString( 16 ),
        b.toString( 16 )
    ];
    $.each( hex, function( nr, val ) {
        if ( val.length === 1 ) {
            hex[ nr ] = "0" + val;
        }
    });
    return hex.join( "" ).toUpperCase();
}  

Тепер я хочу шістнадцяткову формулу від відсотків.


Відповіді:


87

Це може бути більше, ніж вам потрібно, але це дозволяє встановити будь-яку довільну карту кольорів:

var percentColors = [
    { pct: 0.0, color: { r: 0xff, g: 0x00, b: 0 } },
    { pct: 0.5, color: { r: 0xff, g: 0xff, b: 0 } },
    { pct: 1.0, color: { r: 0x00, g: 0xff, b: 0 } } ];

var getColorForPercentage = function(pct) {
    for (var i = 1; i < percentColors.length - 1; i++) {
        if (pct < percentColors[i].pct) {
            break;
        }
    }
    var lower = percentColors[i - 1];
    var upper = percentColors[i];
    var range = upper.pct - lower.pct;
    var rangePct = (pct - lower.pct) / range;
    var pctLower = 1 - rangePct;
    var pctUpper = rangePct;
    var color = {
        r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper),
        g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper),
        b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper)
    };
    return 'rgb(' + [color.r, color.g, color.b].join(',') + ')';
    // or output as hex if preferred
};

1
Ого, спасибі, містер @Jacob ^ - ^ https://jsfiddle.net/JeancarloFontalvo/1sco9Lpe/3/
Jeancarlo Fontalvo

Це саме те, що мені потрібно для проекту. Велике спасибі @Jacob!
Савадо

1
Ісусе, це дивно
Талбой

Дуже дякую. Це просто пригодилось для проекту, над яким я працюю!
rayalois22

122

Проста схема використання HSL разом із скрипкою:

function getColor(value){
    //value from 0 to 1
    var hue=((1-value)*120).toString(10);
    return ["hsl(",hue,",100%,50%)"].join("");
}

за необхідності налаштуйте насиченість та світність. і скрипка .

function getColor(value) {
  //value from 0 to 1
  var hue = ((1 - value) * 120).toString(10);
  return ["hsl(", hue, ",100%,50%)"].join("");
}
var len = 20;
for (var i = 0; i <= len; i++) {
  var value = i / len;
  var d = document.createElement('div');
  d.textContent = "value=" + value;
  d.style.backgroundColor = getColor(value);
  document.body.appendChild(d);
}


3
Отже, це чорна скринька. Будь-яке пояснення?
Саїд Неаматі,

6
Від червоного до зеленого. var hue = (значення * 120) .toString (10);
Цянь Чень,

3
Як ви можете адаптувати це для включення мінімального та максимального значення? Наприклад, getColor(12,0,100)( getColor(value, min, max))?
Адвокат диявола

Подряпин, це не працює на 100%: stackoverflow.com/questions/40110721/…
адвокат диявола

@SaeedNeamati Встановлює відтінок від 0 до 120 (представляючи червоний через зелений) на основі переданого вами значення (від 0 до 1). Він перетворює відтінок у рядок (від "0" до "120"), а потім повертає рядок, що кодує колір у форматі hsl (відтінок, насиченість, легкість), з насиченістю встановленим на 100% та яскравістю встановленим на 50%.
mattsoave

38

Ви можете зробити це за допомогою декількох рядків коду (не враховуючи коментарів), не потребуючи жодних кольорових карт.

function hsl_col_perc(percent, start, end) {
  var a = percent / 100,
      b = (end - start) * a,
      c = b + start;

  // Return a CSS HSL string
  return 'hsl('+c+', 100%, 50%)';
}
//Change the start and end values to reflect the hue map
//Refernece : http://www.ncl.ucar.edu/Applications/Images/colormap_6_3_lg.png

/*
Quick ref:
    0 – red
    60 – yellow
    120 – green
    180 – turquoise
    240 – blue
    300 – pink
    360 – red
*/      

Приклад: https://jsfiddle.net/x363g1yc/634/

Немає необхідності в кольорових картах (якщо це нелінійна зміна кольору, про яку не просили)

Попередження: Це не сумісно з IE8 або нижче. (Дякую Бернгарду Фюрсту)


Використовувати кольорову модель HSL - це круто, але в Internet Explorer 8 це не працює, на жаль.
Бернхард Фюрст,

Це правда, я
зміню

Можете пояснити startі endв цьому?
Адвокат диявола

1
Ні, endце різниця між початковим і кінцевим кольором у наведеному вище коді. hsl_col_perc(100, 60, 120)призведе до бірюзового замість зеленого. Вам потрібно змінити другий рядок на b = (end-start)*aабо просто зробити його однорядковим, оскільки це було б легше читати.
рів

1
Дякуємо за те, що залишили у швидкому кольоровому номері HSL!
ohsully

13

Цей метод добре працює в цьому випадку (відсотки від 0 до 100):

function getGreenToRed(percent){
            r = percent<50 ? 255 : Math.floor(255-(percent*2-100)*255/100);
            g = percent>50 ? 255 : Math.floor((percent*2)*255/100);
            return 'rgb('+r+','+g+',0)';
        }

6
function hexFromRGBPercent(r, g, b) {
    var hex = [
        Math.floor(r / 100 * 255).toString( 16 ),
        Math.floor(g / 100 * 255).toString( 16 ),
        Math.floor(b / 100 * 255).toString( 16 )
    ];
    $.each( hex, function( nr, val ) {
        if ( val.length === 1 ) {
            hex[ nr ] = "0" + val;
        }
    });
    return hex.join( "" ).toUpperCase();
}

Кредит дістається Ендрю. Він був швидшим.


5

Я знаю, що це спочатку старе запитання щодо JavaScript, але я тут шукав рішення лише для CSS , тому, можливо, це допоможе іншим однаково: Це насправді досить просто:

Використовуйте відсоток як значення кольору HSL! Червоний до Зеленого охоплює H від 0до 128. (Щоб ви могли збільшити відсоток, 1.2якщо хочете). Приклад:

background-color:hsl(perc,100%,50%);

Де perc - це просто число без %знака.


3

Ось що я придумав:

function rgbify(maxval, minval, val, moreisgood) {
    var intnsty = (val - minval) / (maxval - minval);
    var r, g;
    if (moreisgood) {
        if (intnsty > 0.5) {
            g = 255;
            r = Math.round(2 * (1 - intnsty) * 255);
        } else {
            r = 255;
            g = Math.round(2 * intnsty * 255);
        }

    } else { //lessisgood
        if (intnsty > 0.5) {
            r = 255;
            g = Math.round(2 * (1 - intnsty) * 255);
        } else {
            g = 255;
            r = Math.round(2 * intnsty * 255);
        }
    }
    return "rgb(" + r.toString() + ", " + g.toString() + ", 0)";
}

jsfiddle

В moreisgoodпрапор перемикає , якщо більш високі значення повинні бути червоним або зеленим. maxvalі minvalє пороговими значеннями для вашого діапазону. val- це значення, яке потрібно перетворити на rgb


3

Перехід від redдо greenкольору з допомогою HLS. Значення має бути від 0 до 100, в цьому випадку імітуючи відсоток (%).

function getColorFromRedToGreenByPercentage(value) {
    const hue = Math.round(value);
    return ["hsl(", hue, ", 50%, 50%)"].join("");
}

Дуже приємно, тому що підтримує пристойні приглушені кольори, якщо вони вам потрібні :)
dijipiji,

3

На основі відповіді Джейкобса я зробив loadbar. Це від зеленого до червоного, але ви можете змінити кольори. Для тих, хто цікавиться, ось мій код та jsfiddle ( http://jsfiddle.net/rxR3x/ )

var percentColors = [
    { pct: 0, color: '#00FF00' },   { pct: 3, color: '#12FF00' },   { pct: 6, color: '#24FF00' },
    { pct: 10, color: '#47FF00' },  { pct: 13, color: '#58FF00' },  { pct: 16, color: '#6AFF00' },
    { pct: 20, color: '#7CFF00' },  { pct: 23, color: '#8DFF00' },  { pct: 26, color: '#9FFF00' },
    { pct: 30, color: '#B0FF00' },  { pct: 33, color: '#C2FF00' },  { pct: 36, color: '#D4FF00' },
    { pct: 40, color: '#E5FF00' },  { pct: 43, color: '#F7FF00' },  { pct: 46, color: '#FFF600' },
    { pct: 50, color: '#FFE400' },  { pct: 53, color: '#FFD300' },  { pct: 56, color: '#FFC100' },
    { pct: 60, color: '#FFAF00' },  { pct: 63, color: '#FF9E00' },  { pct: 66, color: '#FF8C00' },
    { pct: 70, color: '#FF7B00' },  { pct: 73, color: '#FF6900' },  { pct: 76, color: '#FF5700' },
    { pct: 80, color: '#FF4600' },  { pct: 83, color: '#FF3400' },  { pct: 86, color: '#FF2300' },
    { pct: 90, color: '#FF1100' },  { pct: 93, color: '#FF0000' },  { pct: 96, color: '#FF0000' },
    { pct: 100, color: '#FF0000' }
];
var getColorPercent = function(selector, percent, time){
    var i = 0;
    var percentInterval = setInterval(function() {
         i++;
         if(percent >= percentColors[i].pct) {
            console.log(percentColors[i].color);
            $(selector).css('background-color', percentColors[i].color);
        }
        if(percentColors[i].pct>=percent) {
            clearInterval(percentInterval);
        }
    }, time/25);
    $(selector).animate({width:(200/100)*percent}, time);
}
getColorPercent('#loadbar_storage', 100, 1500);


2

Змініть ці два рядки в коді Якова:

var lower = percentColors[i - 1];
var upper = percentColors[i];

до:

var lower = (i === 0) ?  percentColors[i] : percentColors[i - 1];
var upper = (i === 0) ? percentColors[i + 1] : percentColors[i];

якщо ви хочете, щоб це працювало для двох крайнощів (тобто 0,0 та 1,0).


2

Я знаю, що це свого роду сутичка з темою, але я знайшов ще один спосіб зробити це.

Для цього ви також можете створити динамічне полотно розміром 100x1 і застосувати до нього градієнт, а потім із функції потрібно просто отримати піксельний колір відсотка розташування.

Ось код: Це глобально:

/* dynamic canvas */

// this should be done once in a page so out of function, makes function faster
var colorBook = $('<canvas />')[0];
colorBook.width = 101;
colorBook.height = 1;
var ctx = colorBook.getContext("2d");
var grd = ctx.createLinearGradient(0, 0, 101, 0);
grd.addColorStop(0, "rgb(255,0,0)"); //red
grd.addColorStop(0.5, "rgb(255,255,0)"); //yellow
grd.addColorStop(1, "rgb(0,255,0)"); //green    
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 101, 1);

Тоді функція:

function getColor(value) {
  return 'rgba(' + ctx.getImageData(Math.round(value), 0, 1, 1).data.join() + ')';
}

Демонстрація: https://jsfiddle.net/asu09csj/


1

HSL працюватиме в IE8 за допомогою jquery-ui-1.10.4.

Я змінив відповідь jongo45, щоб прийняти легкість у функції.

function getColor(value, lightness) {
    //value from 0 to 1
    var hue = ((value) * 120).toString(10);
    return ["hsl(", hue, ",100%,", lightness, "%)"].join("");
}

1

Код Меттісдади був для мене дуже корисним, поки я складав діаграму для відображення статистики деяких результатів вікторини. Я трохи змінив його, щоб дозволити "відсікання" відсотка (не впевнений, що це правильний термін), а також працювати в обидві сторони вздовж кольорового круга, наприклад, від зеленого (120) до червоного (0) і навпаки.

function pickColourByScale(percent, clip, saturation, start, end)
{
    var a = (percent <= clip) ? 0 : (((percent - clip) / (100 - clip))),
        b = Math.abs(end - start) * a,
        c = (end > start) ? (start + b) : (start - b);
    return 'hsl(' + c + ','+ saturation +'%,50%)';
}

В основному, встановивши відсоткове значення для відсікання масштабу, все нижче цього значення буде забарвлене як ваш початковий колір. Він також перераховує масштабування відповідно до 100% - кліпу.

Давайте розглянемо приклад сценарію, коли я вводжу такі значення:

  • відсотків: 75
  • кліп: 50
  • насиченість: 100 (неважливо, я використовую це для виділення діаграми Chart.js)
  • початок: 0 (червоний)
  • кінець: 120 (зелений)

    1. Я перевіряю, чи відсоток менше кліпу, і повертаю 0%, якщо він є. В іншому випадку я перераховую відсоток - 75% знаходиться на півдорозі між 50% і 100%, тож я отримую 50%. Це дає мені 0,5.
    2. Я отримую різницю між початком і кінцем. Вам потрібно використовувати Math.abs (), якщо ваше початкове значення відтінку більше, ніж ваше кінцеве значення відтінку. Потім я помножую різницю на результат, отриманий на кроці 1, щоб побачити, наскільки мені потрібно компенсувати значення початкового відтінку.
    3. Якщо початкове значення більше кінцевого, тоді вам потрібно рухатися вздовж кольорового круга у зворотному напрямку. Відповідно додайте або відніміть від початкового значення.

Я закінчую жовтим, який знаходиться на півдорозі між червоним та зеленим. Якби я не зробив перерахунок на кроці 1, я б закінчив з більш зеленуватим кольором, що може ввести в оману.


0

Я змінив відповідь zmc, щоб дати градієнт від зеленого (0%) до червоного (100%).

const getGreenToRed = (percent) => {
    const r = 255 * percent/100;
    const g = 255 - (255 * percent/100);
    return 'rgb('+r+','+g+',0)';
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.