Search code examples
algorithmcolor-gradient

Plotting times of day to a fixed color gradient?


I'm making an appointments app.

I have this gradient structure (created in Pixelmator), with which I want to mark the times of day:

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:

gradient from green to yellow to green to blue

Can anyone point me in the right direction to understanding how to make the algorithm I need here? Do I have to use a different color value system, like RGB?

Thanks in advance for any and all help!


Solution

  • Pixelmator looks like it's using RGB gradients. Demo:

    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">