Search code examples
javascriptalgorithmcolors

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


Solution

  • 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);
    }