JavaScript: Translating numerical values to color spectrum

I’m trying to create a function that turns numbers between -1 and 1 into colors. Here’s what I want:

  • When the value is 1, the color should be red (H:0)
  • At 0.5, it should be yellow (H:60)
  • At 0, it should be green (H:170)
  • At -1, it should be blue (H:200)

I want to use the HSL color model with S:100 and L:50 for all colors.

I found a script that changes percentages to colors from green to red, but I’m not sure how to adjust it to fit my needs:

function valueToHue(value, maxHue = 200, minHue = 0) {
  const hue = (value + 1) * (maxHue - minHue) / 2 + minHue;
  return `hsl(${hue}, 100%, 50%)`;
}

How can I modify this function to include blue and properly work within the -1 to 1 range? I’m struggling to figure out the right math for this. Any help would be great!

I’ve been working with color mapping in JavaScript for a while, and I think I can offer a slightly different approach that might be useful for your specific requirements. Instead of using a single linear equation, we can break it down into segments for more precise control:

function valueToHue(value) {
  let hue;
  if (value >= 0.5) {
    hue = 60 - (value - 0.5) * 120; // Yellow to Red
  } else if (value >= 0) {
    hue = 170 - value * 220; // Green to Yellow
  } else {
    hue = 200 - value * 30; // Blue to Green
  }
  return `hsl(${Math.round(hue)}, 100%, 50%)`;
}

This function divides the range into three parts, allowing for more accurate color transitions at each stage. It should give you a smoother gradient across the entire spectrum. Remember to adjust the multipliers if you need to fine-tune the color transitions further. Also, rounding the hue value can help prevent any potential floating-point issues.

hey mate, i think i can help. u could try adjusting the hue calculation like this:

function valueToHue(value) {
  let hue = value < 0 ? 200 - value * 30 : 170 - value * 170;
  return `hsl(${hue}, 100%, 50%)`;
}

this should give u the color range ur looking for. hope it helps!

I’ve implemented a solution that might work for your color mapping needs. Here’s a function that should cover the entire range from -1 to 1:

function valueToHue(value) {
  let hue;
  if (value >= 0) {
    hue = 170 - (value * 170);
  } else {
    hue = 170 + ((Math.abs(value) * 30));
  }
  return `hsl(${hue}, 100%, 50%)`;
}

This function handles both positive and negative values separately, ensuring a smooth transition between colors. It should give you red at 1, yellow at 0.5, green at 0, and blue at -1, as requested. You may need to fine-tune the calculations slightly to get the exact hues you want, but this should serve as a solid starting point.