Change the Hue of a RGB Color in javascript

前端 未结 2 1536
天涯浪人
天涯浪人 2021-01-31 23:00

Similar to this (how to increase brightness) I want to change the Hue of a RGB (Hex) Color.

Say changeHue(\"#FF0000\", 40) returns \"#FFAA00\"

相关标签:
2条回答
  • 2021-01-31 23:23

    Here is the solution I found. I hope its usable and might help in the future. Any improvements or further solutions are very welcome.

    Change Hue

    // Changes the RGB/HEX temporarily to a HSL-Value, modifies that value 
    // and changes it back to RGB/HEX.
    
    function changeHue(rgb, degree) {
        var hsl = rgbToHSL(rgb);
        hsl.h += degree;
        if (hsl.h > 360) {
            hsl.h -= 360;
        }
        else if (hsl.h < 0) {
            hsl.h += 360;
        }
        return hslToRGB(hsl);
    }
    
    // exepcts a string and returns an object
    function rgbToHSL(rgb) {
        // strip the leading # if it's there
        rgb = rgb.replace(/^\s*#|\s*$/g, '');
    
        // convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
        if(rgb.length == 3){
            rgb = rgb.replace(/(.)/g, '$1$1');
        }
    
        var r = parseInt(rgb.substr(0, 2), 16) / 255,
            g = parseInt(rgb.substr(2, 2), 16) / 255,
            b = parseInt(rgb.substr(4, 2), 16) / 255,
            cMax = Math.max(r, g, b),
            cMin = Math.min(r, g, b),
            delta = cMax - cMin,
            l = (cMax + cMin) / 2,
            h = 0,
            s = 0;
    
        if (delta == 0) {
            h = 0;
        }
        else if (cMax == r) {
            h = 60 * (((g - b) / delta) % 6);
        }
        else if (cMax == g) {
            h = 60 * (((b - r) / delta) + 2);
        }
        else {
            h = 60 * (((r - g) / delta) + 4);
        }
    
        if (delta == 0) {
            s = 0;
        }
        else {
            s = (delta/(1-Math.abs(2*l - 1)))
        }
    
        return {
            h: h,
            s: s,
            l: l
        }
    }
    
    // expects an object and returns a string
    function hslToRGB(hsl) {
        var h = hsl.h,
            s = hsl.s,
            l = hsl.l,
            c = (1 - Math.abs(2*l - 1)) * s,
            x = c * ( 1 - Math.abs((h / 60 ) % 2 - 1 )),
            m = l - c/ 2,
            r, g, b;
    
        if (h < 60) {
            r = c;
            g = x;
            b = 0;
        }
        else if (h < 120) {
            r = x;
            g = c;
            b = 0;
        }
        else if (h < 180) {
            r = 0;
            g = c;
            b = x;
        }
        else if (h < 240) {
            r = 0;
            g = x;
            b = c;
        }
        else if (h < 300) {
            r = x;
            g = 0;
            b = c;
        }
        else {
            r = c;
            g = 0;
            b = x;
        }
    
        r = normalize_rgb_value(r, m);
        g = normalize_rgb_value(g, m);
        b = normalize_rgb_value(b, m);
    
        return rgbToHex(r,g,b);
    }
    
    function normalize_rgb_value(color, m) {
        color = Math.floor((color + m) * 255);
        if (color < 0) {
            color = 0;
        }
        return color;
    }
    
    function rgbToHex(r, g, b) {
        return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
    }
    

    Usage

    changeHue("#FF0000", 40) --> returns #ffaa00  
    changeHue("#D61E1E", 180) --> returns #1ed6d6 
    changeHue("#2244BB", -80) --> returns #21bb66 
    

    References

    • RGB to HSL
    • HSL to RGB
    • Inital Hex to RGB Conversion
    0 讨论(0)
  • 2021-01-31 23:29

    If you're not afraid of libraries and a few kb won't ruin your project, you could try sc-color rather than reimplementing the wheel...

    Here's a jsfiddle using sc-color. The crux of the code is here:

    var c = sc_color("#FF0000").hue(40).hex6();
    $("#test").css("background-color", c);
    

    Disclosure: I'm the author of sc-color

    0 讨论(0)
提交回复
热议问题