PHP/JS: A three-color scaled color value

So as usual when I make a thread, i’m mostly musing to myself and wondering if there’s a better/simpler solution than my initial impulse.

I need a scale, such that for a given input value (Let’s assume an integer), generate an RGB value such that the color shifts from a certain green, to a certain yellow at 50%, to a certain red at 100%; to apply via a CSS color value.

Impulse: Mathematically scale each of the color values between transition points; each gap will require its own values to scale from/to.

Domain: 0-432,000; any value off scale is treated as its endcap value.
Range: (76,148,67) 0%, (184,134,11) 50%, (220,20,60) 100%

MinColor = Range[(Value // 216000)]
MaxColor = Range[(Value // 216000)+1]
Percent = (Value % 216000) / 216000
CorrectColor = (MinColor[0]+((MaxColor[0]-MinColor[0])*Percent), MinColor[1]+((MaxColor[1]-MinColor[1])*Percent), MinColor[2]+((MaxColor[2]-MinColor[2])*Percent))

Am I missing a trick here? I can’t imagine this is the first time someone’s had to tackle this problem.

To be honest I do not understand what you want to do.
What is a scale in that case? Do you mean a gradiant?
And how can an Integer represent a RGB value and why 432000? When you use RGB you have 16.8M as the maximum value (256256256)
Or do you want the user to input 9 integers?

I am confused :slight_smile:

So a scale in this case i’m kind of stealing D3.js’s definition of. Basically, the scale is: Take in value, give out value that fits on the chart; scale the input (Domain) to be represented as a pixel coordinate (Range) that would be in the chart.

In this case, i’m taking an integer value (A time in seconds) and scaling it into a color gradient (an RGB value).

432000 is 5 days, in seconds.
So at 0 seconds, the color will be Green.
At 2 and a half days, the color will be Yellow.
At 5 days (or more), the color will be Red.

And a sliding value inbetween. I realize that browsers dont do floats for RGB, but I dont… think that’s going to be supremely relevant to the situation.

Ah not it is much clearer.

But I don’t think this could be done easier. I would put all „color steps“ in an array and then get the interval for each step by dividing total length by length of array -1. then I would calculate the single steps by looping through all array entries step by step like you already do

1 Like

Would it perhaps be easier to switch to dealing with HSL instead of RGB? Takes a bunch of that funky math away.

How is the math easier?

If i need to go from (113,37.7%,42.2%) to (43,88.7%,38.2%), with a full range between… I still have to do the math, no?

If you want to go around the colour wheel of saturated hues, you need to go around the path shown here by arrows . . . .

You could go directly from red to green in a straight line avoiding the 90 degree sharp turn at yellow :grinning:.

Except I specifically do want to go through yellow in this case.

Also… what color is the midpoint of the direct line between red and green in the HSL wheel?

Then you will have to make a sharp turn!

HSL = (60, 100, 25) when RGB = (128, 128, 0)

so… Yellow.

How exactly is that not taking a sharp turn through yellow?

Yellow is HSL = (50, 100, 50).

It’s still not a direct route from red to green.

You cant go direct from red to green in a gradient without passing through another color; yellow (shift hue), white (shift saturation), or black (shift lightness).
And at any point, you’re going to have to round that sharp corner - through yellow, through black, or through white.

You can on that 3D colour cube drawing. You go diagonally across the face of the cube that has black, red, yellow and green at its corners. Half way in between is a fairly dark yellow:

Colour picker

… yes, thank you for agreeing with me?

Anyway, this is beyond the scope of conversation at this point.

I dont see how operating in HSL values is any different than RGB values in terms of the amount of maths that needs to be done to gradient between three marked points.

Because you really only need to tweak the first number in HSL to transition from green to yellow to red.

I’m not thrilled with having this google search link, but it shows the google color picker and shows the HSL values as you slide the colors. If you notice, in HSL, the only number that changes is the first one. The other two remain constant to change the hue.

Another option would be to tweak the saturation and lightness, and have benchmarks in the code to change the hue. So the green would get duller and darker, then switch to yellow which would then get duller and darker then switch to red and rinse and repeat. Might be a better User experience than the fugly colors which exist on the color wheel between the three colors…

Again, If I want to hit a certain color at 50%, and a certain different color at 100%, how is any of the math between those points, which have DIFFERENT Saturation and Lightness components, any easier than the RGB ones?

This isnt going from 120,100,50 to 60,100,50.

Again, If I want to hit a certain color at 50%, and a certain different color at 100%, how is any of the math between those points, which have DIFFERENT Saturation and Lightness components, any easier than the RGB ones?

This isnt going from 120,100,50 to 60,100,50. It’s going from (for example) 113,37,42 to 43,88,38.

If I want a color 25% of the way along that span, is it not the mathematical location of 25% of the difference between each of the H S and L valueS?

If you work in RGB then over your 5 days you could gradually change red from 255 to 0 and green from 0 to 255. After 2.5 days it would be a yucky darkish yellow. To go via yellow when working in RGB you would need to change green from 0 to 255 for 2.5 days then change red from 255 to 0 for the remaining 2.5 days.

So… perhaps we can stick to the actual problem as stated.

I have 3 fixed color points. Move between the three of them, on a gradient,
Or if you care to break it down, go from the first point to the second; then go from the second to the third.

The three points are non-negotiable.

No! For a start the hue value is in degrees 0 to 360.

Red is HSL=(0, 100, 50) and green is HSL = (120, 100, 50) so 25% would be HSL = (30, 100, 50) and 50% would be HSL = (60, 100, 50) which is yellow.