-2

I have a scale of numbers from -10 to +10 that I want to convert to a color scale (-10 = red, 0 = purple, 10 = blue). I'm thinking I should do this using rgb and adjusting the lightness of both red and blue using x, y co-ordinates and the formula 'y = mx+c'. I'm having trouble getting my head around how to write the functions so any help would be appreciated.

Also open to other suggestions!

martybutts
  • 23
  • 5
  • Possible duplicate of [Algorithm: How do I fade from Red to Green via Yellow using RGB values?](http://stackoverflow.com/questions/6394304/algorithm-how-do-i-fade-from-red-to-green-via-yellow-using-rgb-values) – charsi Aug 21 '16 at 01:14
  • Search for how to create an algorhythm for the conversion. --http://stackoverflow.com/questions/6394304/algorithm-how-do-i-fade-from-red-to-green-via-yellow-using-rgb-values – charsi Aug 21 '16 at 01:15

2 Answers2

0

Here:

//from problem
let rangeMin = -10;
let rangeMax = 10;

//width of the range
let width = rangeMax - rangeMin;

//other
let canvas = document.getElementById("cv");
let ctx = canvas.getContext("2d");
let step = rangeMin;
let msStep = 250;
let intervalId;

function scale(x) {
  if (typeof x !== "number" || x > rangeMax || x < rangeMin)
    throw "out of allowed range";
  //The interesting part of the code
  return [Math.round(0xff * (1 - ((x - rangeMin) / width))), 0, Math.round(0xff * ((x - rangeMin) / width))];
}

function draw() {
  let rgb = scale(step);
  ctx.fillStyle = `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  step++;
  if (step > rangeMax) clearInterval(intervalId);
}

intervalId = setInterval(draw, msStep);
<html>
  <body>
    <canvas id="cv" width="400" height="100" style="border:1px solid #000000;">no canvas support</canvas>
  </body>
</html>

You need to translate the range of -10 to 10 to 0 to 255 and the inverse, 255 to 0 because for additive colors, red + blue = purple, meaning it can just start at red and increase blue while decreasing red.

First shift the start to zero (this doesnt affect the width of the range and therefore not the result), (x - rangeMin). Then calculate the percentage in the range, ((x - rangeMin) / width), note that the inverse is just one minus the percentage, 1 - ((x - rangeMin) / width). Finally multiply that with the target range (which already starts at zero, otherwise shifts need to be done again), 0xff * ((x - rangeMin) / width) and 0xff * (1 - ((x - rangeMin) / width)) respectively.

ASDFGerte
  • 4,695
  • 6
  • 16
  • 33
0

I have a scale of numbers from -10 to +10 that I want to convert to a color scale (-10 = red, 0 = purple, 10 = blue).

You can create an object to store properties ranging from -10 to 10; use css transition to generate colors between red to blue, set to values of object; utilize <input type="range"> with step set to 1, input event set element background-color to color stored at object corresponding to <input type="range"> .value

window.onload = function() {
  var range = document.querySelector("input[type=range]");
  var color = document.querySelector("div");
  var output = document.querySelector("output");
  range.setAttribute("disabled", "disabled");
  var colors = {};
  var i = -10;
  color.style.color = "blue";
  colors[i] = getComputedStyle(color).getPropertyValue("color");
  var interval = setInterval(function() {
    colors[++i] = getComputedStyle(color).getPropertyValue("color");
    output.innerHTML = "loading " + Object.keys(colors).length + " colors..."
  }, 100);
  setTimeout(function() {
    clearInterval(interval);
    range.removeAttribute("disabled");
    range.value = output.innerHTML = colors[0];
    color.style.backgroundColor = colors[0];
    color.style.display = "block";
    color.style.transition = "none";
    range.focus();
    console.log(JSON.stringify(colors, null, 2));
    alert(Object.keys(colors).length 
          + " colors loaded,\n select color with range input");
    range.oninput = function(e) {
      color.style.backgroundColor = colors[this.value];
      output.innerHTML = colors[this.value];          
    }
  }, 2005);
}
div {
  height: 200px;
  outline: thin solid #000;
  color: red;
}

div, input[type="range"], output {
  font-size: 32px;
  position: relative;
  text-align: center;
  width: 200px;
  left:calc(50vw - 100px);
}
<input type="range" min="-10" max="10" step="1" value="0" />
<div style="transition: color 2s linear;"></div>
<br><output>loading colors...</output>
guest271314
  • 1
  • 15
  • 104
  • 177