10

I want to display a color between red, yellow, green depending on a number between 1 to 100.

1 being green and 100 being red, 50 being yellow. I want to basically create a gradient between that.

So far, I tried:

$r = floor(255 * ($number / 100));
$g = 255 - $r;

And it somewhat does it, but gives me brownish & dark colors, & no yellow at all.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Quicky
  • 163
  • 2
  • 7
  • 3
    possible duplicate of [Generate colors between red and green for an input range](http://stackoverflow.com/questions/11849308/generate-colors-between-red-and-green-for-an-input-range) – Naftali Dec 12 '12 at 13:50

4 Answers4

12

It's because you shouldn't change both channels at once but rise R in the first half and lower G in the second.

Try a function like this:

function GreenYellowRed($number) {
  $number--; // working with 0-99 will be easier

  if ($number < 50) {
    // green to yellow
    $r = floor(255 * ($number / 50));
    $g = 255;

  } else {
    // yellow to red
    $r = 255;
    $g = floor(255 * ((50-$number%50) / 50));
  }
  $b = 0;

  return "$r,$g,$b";
}

To test it:

$output = "";
for ($i = 1; $i <= 100; $i++) {
  $rgb = GreenYellowRed($i);
  $output .= "<div style='background-color: rgb($rgb)'>$rgb</div>";
}
echo $output;
Czechnology
  • 14,832
  • 10
  • 62
  • 88
2

After a bit of looking, none of the solutions looked pleasing. As stated above, HSV is probably the way to go, since modern browsers can render color with it just fine.

To get a good idea of the colors you are working with, check out this color wheel:

http://www.colorspire.com/rgb-color-wheel/

I want to start with blue, so I use 255 for normalization.

function temp_color($temp){

    $start = 40;
    $end = 85;

    $normal = round(255-((($temp - $start)/($end-$start))*255));

    $color = "hsl($normal, 100%, 30%);";
    $span = "<span style=\"color: $color\">$temp</span>";

    return $span;
}   
2

I've found that dealing with the HSV color model is easier than the RGB model. It helps you easily choose the color you want to work with; with RGB you'd need to understand how different values of R, G and B will combine to give you the color you want/don't want.

Also, this SO question might be useful: How can I cycle through hex color codes in PHP?

Community
  • 1
  • 1
no.good.at.coding
  • 20,221
  • 2
  • 60
  • 51
2

I don't know of a mathematical model for a "color curve" that passes through specified RGB color values (e.g. what you describe as green/yellow/red), which would allow you to calculate any intermediate color in that curve. In any case, a model of a function (which is what that would be) is only as good as the data points it needs to fit, so you 'd have to be much more specific than green/yellow/red to get decent results even if someone points out the math.

Remember that we are not interested in mathematical interpolation here, but rather in "color-space interpolation" (a term which I just made up) -- in other words, what would look like a "natural" interpolation to a human.

An easier solution for those of us who do not have the necessary color theory knowledge, and which I 'd suggest, is to pre-select a number of colors with a color picker tool, divide the 0-100 range into as many bands as the colors you picked, and use simple integer division to project from 0-100 to a color band.

Food for thought: Indeed, how does SO decide the color of the upvote count for comments?

Update: I just asked the above over on meta. Let's see...

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806