Reputation: 9332
I'm looking for a Javascript function/algorithm that will generate an RGB value for a color that's p% along the "visible light" spectrum.
For example - given the visible light spectrum...
... and given p=0, the function should return the RGB of red (0% across this spectrum. Given p=50, the function should approximately return the RBG of green (50% across the spectrum). Finally, given p=100, the function would return the RBG of violet.
The function doesn't need to be technically/scientifically precise - I'm just looking for a reasonably close approximation, with reasonable sensitivity. (E.g., the RGB for p=76 should be different than for p=77).
Ideally, I'm looking for a pure math formula. I.e., I'd like to avoid actually loading the image below onto a Canvas, than using context.getImageData to find the color of a pixel p% across the image.
Of course, I have no idea if that's possible...
Upvotes: 1
Views: 7295
Reputation: 113
see https://codepen.io/alijani/pen/zYVmzqR
function rainbow(x) { // 0 - 1535
let r = Math.trunc(x / 256); // 0 - 5 grbgrb
let c = x % 256;
if (r==0)
value = rgb(255,c,0);
else if (r==1)
value = rgb(255-c,255,0);
else if (r==2)
value = rgb(0,255,c);
else if (r==3)
value = rgb(0,255-c,255);
else if (r==4)
value = rgb(c,0,255);
else if (r==5) {
value = rgb(255,0,255-c);
return value;
}
function rgb(r,g,b) {
return "#"+(r).toString(16).padStart(2,'0')+(g).toString(16).padStart(2,'0')+(b).toString(16).padStart(2,'0');
}
Upvotes: 0
Reputation: 5447
Ideally, I'm looking for a pure math formula. I.e., I'd like to avoid actually loading the image below onto a Canvas, than using context.getImageData to find the color of a pixel p% across the image.
The visible light spectrum can't be put into a formula, because which color we see at a specific wavelength doesn't follow a mathematical term. The human eye and brain are much too complicated for that!
Yes, you can display every color using a red, green and blue light bulb like a PC screen. But that doesn't mean that yellow, cyan and magenta divide the light spectrum into accurate thirds! In computer science, however, this is easily assumed to be true.
This makes it easy to calculate on the colors:
Color hue [°] r g b hex
------------------------------------------
red 0 1 0 0 FF0000
yellow 60 1 1 0 FFFF00
green 120 0 1 0 00FF00
cyan 180 0 1 1 00FFFF
blue 240 0 0 1 0000FF
magenta 300 1 0 1 FF00FF
You can display the colors on a wheel: the left on is the one a programmer would prefer, the right one is more like a visible light spectrum:
Now you can easily see why the rgb value can't be calculated if you want to use the visible light spectrum: It doesn't follow any rule. Apart from that, there isn't just one visible light spectrum: Google it, you'll see that every image is slightly different.
I'd like to know what's the specific reason for getting the rgb value of a specific light wavelength: You can instead use the hue as the other answers suggest, but be aware that the hue has different proportions than the visible light spectrum.
If real proportions are important, you will have to load an image into a canvas (an image height of 1 pixel would be enough ;) ) or you can store all the values in a JSON array.
Upvotes: 0
Reputation: 10595
You can use the HSVtoRGB
function from this answer to create something easily.
function HSVtoRGB(h, s, v) {
var r, g, b, i, f, p, q, t;
if (arguments.length === 1) {
s = h.s, v = h.v, h = h.h;
}
i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
}
function rainbow(p) {
var rgb = HSVtoRGB(p/100.0*0.85, 1.0, 1.0);
return 'rgb('+rgb.r+','+rgb.g+','+rgb.b+')';
}
for(var i=0; i<100; i++) {
var span = document.createElement('span');
span.style.backgroundColor = span.style.color = rainbow(i);
span.textContent = 'i';
document.body.appendChild(span);
}
Upvotes: 2
Reputation: 141
You can use this lib https://github.com/moagrius/Color to set a color and change hue (https://en.wikipedia.org/wiki/Hue).
Example:
var color = new Color('#FF0000'); // red
color.hue(150);
color.getRGB(); // rgb(0, 255, 128) cerulean
color.hue(300);
color.getRGB(); // rgb(255, 0, 255) violet
color.hue(0);
color.getRGB(); // rgb(255, 0, 0) red
Upvotes: 0