Отображение времени суток с фиксированным цветовым градиентом? - PullRequest
1 голос
/ 13 июля 2020

Я назначаю приложение для встреч.

У меня есть эта градиентная структура (созданная в Pixelmator), с помощью которой я хочу отметить время дня:

gradient from green to yellow to blue

In the intended scheme, 8am would be solid green, 12 noon would be solid yellow, and 8pm would be solid blue.

I need an algorithm to take the times of day and turn them into those colors, but I can't figure it out, particularly from noon to evening.

These colors are composed using the HSB value system: all colors have S and B at 100%, and from left to right the hue values are 121 (green), 60 (yellow), and 229 (blue).

The progression from the green to yellow is (morning to noon) is straightforward, because it's just a linear scaling from 121 to 60, but from yellow to blue (noon to evening), is not; this is clear if you think about the fact that going from 60 to 229 in a linear fashion would first duplicate the green-to-yellow gradient, just in reverse order, and then would go to from green to blue. In other words, a strictly linear progression would make the gradient look more like this:

градиент от зеленого к желтому, от зеленого к синему

Может ли кто-нибудь указать мне в правильном направлении, чтобы понять, как создать алгоритм, который мне здесь нужен? Должен ли я использовать другую систему значений цвета, например RGB?

Заранее благодарим за любую помощь!

Ответы [ 3 ]

3 голосов
/ 13 июля 2020

Pablo-No дает разумный ответ, подходит ли переход желто-> синего цвета к go через красный. Но исходное изображение OP не go через красный цвет, оно проходит через какой-то серый цвет. Возможно, чтобы этого добиться, следует использовать насыщенность S.

// Assume time is a real value between 8 (8am) and 20 (8pm)
// H is between 0 and 360
// S and B are between 0 and 100
B = 255;
if (time < 12)
{
    // Before noon, linearly go from H=121 (green) to H=60 (yellow)
    H = (time - 8) * (60-121)/4.0 + 121;
    S = 100;
}
else
{
    // After noon, linearly go from H=60 (green) to H=229 (blue)
    // But in the middle, where the color goes green, linearly scale
    // Saturation down to zero and back to 100.
    H = (time - 12) * (229-60)/8.0 + 60;
    auto secondGreenTime = (121-60)*8.0/(229-60) + 12;
    if (time < secondGreenTime)
        S = (time - 12) * (-100.0)/(secondGreenTime-12) + 100;
    else
        S = (time - secondGreenTime) * 100.0/(20-secondGreenTime);
}
2 голосов
/ 16 июля 2020

Pixelmator выглядит так, как будто он использует градиенты RGB. Демо:

const canvas = document.getElementById("gradient");
const ctx = canvas.getContext("2d");
for (let i = 0; i < canvas.width; i++) {
  const alpha = (i + 0.5) / canvas.width;
  const r = 2 * Math.min(alpha, 1 - alpha);
  const g = Math.min(1, 2 * (1 - alpha));
  const b = Math.max(0, 2 * alpha - 1);
  ctx.fillStyle = `rgba(${255*r},${255*g},${255*b})`
  ctx.fillRect(i, 0, 1, canvas.height);
}
<canvas id="gradient" width="240" height="40">
1 голос
/ 13 июля 2020

Вот алгоритм для этого:

  1. Преобразование часа в 24 часа и передача минут и секунд в дробную или десятичную дробь (например, 8:30 -> 8,5, 8:20 - > 25/3)
  2. Вычтите 8 из часа (теперь у нас есть число от 0 до 12)
  3. Если час h находится между 0 и 4, мы сделаем ((-h+4)*(61/4))+60 иначе мы сделаем ((-h+12)*(191/8))-131
  4. Если значение отрицательное, мы добавим 360

Полученное значение будет значением оттенка цвета

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...