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.