Проблема: У меня есть четырехсторонний градиент со значениями цвета 0%, 33%, 66% и 100%. Я хочу узнать значение цвета в любой точке этого градиента в процентах.

Я думаю, что мне нужна какая-то мультистопная интерполяция оттенка, но мне было интересно, существует ли простой способ JavaScript сделать это, прежде чем я сначала погрузлюсь в голову и начну пытаться написать свою собственную.

Цвет перестает работать с:

 //0%
  var stop1 = { r: 25, g: 47, b: 97 };

  //33%
  var stop2 = { r: 75, g: 183, b: 183 };

  //66%
  var stop3 = { r: 237, g: 120, b: 87 };

  //100%
  var stop4 = { r: 209, g: 74, b: 88 };
2
StueyKent 5 Сен 2016 в 19:38

2 ответа

Лучший ответ

Вы можете использовать дельту интервала шагов и рассчитать цвет с правильным соотношением.

Как это устроено.

Например, мы ищем цвет 70%, и сначала мы получаем интервал

[66, 100]

Затем построить соотношение

  • дельта процентов и левый интервал (left)

    70 - 66 => 4
    
  • дельта правого интервала и процент (right)

    100 - 70 => 30
    
  • дельта правого и левого интервала (delta)

    100 - 66 => 34
    
  • с помощью сгенерированных выше соотношений можно рассчитать правильный цвет между двумя цветами с частями.

    (color of left interval * right + color of right interval * left) / delta => color
    

Повторите последний шаг для всех цветов и верните результат.

Рабочий пример:

* обозначает заданные цвета, при наведении указывается процентное значение и значение RGB.

function getColor(percent) {
    function getInterval(range) {
        function getRatio(color) {
            return Math.floor((colors[range[0]][color] * right + colors[range[1]][color] * left) / delta);
        }

        var left = percent - range[0],
            right = range[1] - percent,
            delta = range[1] - range[0];

        return { r: getRatio('r'), g: getRatio('g'), b: getRatio('b') };
    }

    return colors[percent] || getInterval(stops.reduce(function (r, a, i, aa) {
        return a < percent ? [a, aa[i + 1]] : r;
    }, [0, 0]));
}

var stops = [0, 33, 66, 100],
    colors = { 0: { r: 25, g: 47, b: 97 }, 33: { r: 75, g: 183, b: 183 },  66: { r: 237, g: 120, b: 87 }, 100: { r: 209, g: 74, b: 88 } },
    i, color, rgb;

for (i = 0; i <= 100; i++) {
    color = getColor(i),
    rgb =  ['r', 'g', 'b'].map(function (k) { return color[k]; });
    document.body.innerHTML += '<span style="color: #fff; background-color: rgb(' + rgb + ');" title="' + (colors[i] ? '* ' : '') + i + ' % rgb(' + rgb.join(', ') + ')">' + (colors[i] ? '*&nbsp;' : '&nbsp;&nbsp;') + '</span>';
}
2
Nina Scholz 7 Сен 2016 в 08:52

Я также нашел эту симпатичную маленькую библиотеку для игры с цветами: chroma.js

0
StueyKent 7 Сен 2016 в 09:49