Рассчитать цвет в линейном градиенте - PullRequest
0 голосов
/ 13 сентября 2018

Я хотел бы реализовать что-то вроде изображения PowerPoint ниже. Градиент, который идет между тремя значениями.

Начинается с A (-1), средняя точка - B (0), а конец - C (1).

Я понял, что могу сэкономить некоторые усилия, рассчитав «начало» как a-to-b, а «конец» - как b-to-c. Я могу сделать как 2 набора из 2 градиентов, вместо одного градиента с тремя значениями.

Но я в тупик (несмотря на поиск в Google) о том, как перейти от одного цвета к другому - в идеале в цветовом пространстве RGB.

Я бы хотел иметь что-то вроде этого -

const colourSpace = (value, startColor, endColor) => {...}

colorSpace(-0.25, red, yellow) // some sort of orangey color
colorSpace(1, yellow, green) // fully green
colorSpace(0.8, yellow, green) // mostly green

Это не интерфейсное приложение, поэтому нет CSS-градиентов - это то, на что Google в основном ссылался.

Спасибо всем, Олли

a three point gradient

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Я использовал Chroma для преобразования между цветовыми пространствами.

0 голосов
/ 13 сентября 2018

Если вы не слишком беспокоитесь о согласованности восприятия по всему цветовому пространству (для этого вам потребуется работать в чем-то вроде режима LAB), вы можете просто выполнить линейную интерполяцию в пространстве RGB.В основном вы берете расстояние (от 0 до 1), умножаете его на разные по координатам и добавляете к первому.Это позволит вам найти произвольные точки (то есть цвета) вдоль линии между любыми двумя цветами.

Например, между красным и желтым:

let canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d');

let rgb1 = [255, 0, 0]    // red
let rgb2 = [255, 255, 0]  // yellow

function getPoint(d, a1, a2) {
  // find a color d% between a1 and a2
  return a1.map((p, i) => Math.floor(a1[i] + d * (a2[i] - a1[i])))
}

// for demo purposes fill a canvas
for (let i = 0, j = 0; i < 1; i += .002, j++) {
  let rgb = getPoint(i, rgb1, rgb2)
  ctx.fillStyle = `rgba(${rgb.join(",")}, 1)`
  ctx.fillRect(j, 0, 1, 200);
}
<canvas id="canvas" width="500"></canvas>

Вы можете повторить это, чтобы получить несколько «остановок» в градиенте.

...