mattstuehler
mattstuehler

Reputation: 9332

Javascript algorithm/function to generate RGB values for a color along the visible light spectrum

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...

enter image description here

... 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

Answers (4)

Ali
Ali

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

Aloso
Aloso

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.

Computer screen at a closer look

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:

enter image description here

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

Juan Lopes
Juan Lopes

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

omegascorp
omegascorp

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

Related Questions