简体   繁体   English

在javascript中更改RGB颜色的色相

[英]Change the Hue of a RGB Color in javascript

Similar to this (how to increase brightness) I want to change the Hue of a RGB (Hex) Color. 类似(如何增加亮度),我想更改RGB(十六进制)颜色的色相。

Say changeHue("#FF0000", 40) returns "#FFAA00" changeHue("#FF0000", 40)返回"#FFAA00"

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 参考文献

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... 如果您不惧怕库并且只有几KB不会破坏您的项目,则可以尝试使用sc-color而不是重新实现。

Here's a jsfiddle using sc-color. 这是一个使用sc-color的jsfiddle 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 披露:我是sc-color的作者

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM