这是一个我正在工作的函数,以编程方式使十六进制颜色变亮或变暗。只需要传入一个像“3F6D2A”这样的字符串来表示颜色(col),并传入一个base10整数(amt)来表示要变亮或变暗的量。为了变暗,传入一个负数(即-20)。

我这么做的原因是,到目前为止,我找到的所有解决方案似乎都把问题复杂化了。我有一种感觉,只需几行代码就可以完成。请让我知道,如果你发现任何问题,或有任何调整,以加快它。

有趣的灯光 上校(16号); return键(col . & 0x0000FF) + amt) | ((((col > > 8) & 0x00FF) + amt) < < 8) | (16 (col > >) + amt) < < 16) . toString (16); 的 / /测试 控制台(照明颜色(“3F6D2A”,40);

对于开发人员来说,这里有一个更容易阅读的版本:

函数 LightenDarkenColor(col, amt) { var num = parseInt(col, 16); var r = (num >> 16) + amt; var b = ((num >> 8) &0x00FF) + amt; var g = (num & 0x0000FF) + amt; var 新颜色 = g |(b << 8) |(第16<<条); 返回 newColor.toString(16); } 测试 console.log(LightenDarkenColor(“3F6D2A”, -40));

最后一个版本可以处理开头可能有(也可能没有)“#”的颜色。加上调整不适当的颜色值:

function LightenDarkenColor(col,amt) {
    var usePound = false;
    if ( col[0] == "#" ) {
        col = col.slice(1);
        usePound = true;
    }

    var num = parseInt(col,16);

    var r = (num >> 16) + amt;

    if ( r > 255 ) r = 255;
    else if  (r < 0) r = 0;

    var b = ((num >> 8) & 0x00FF) + amt;

    if ( b > 255 ) b = 255;
    else if  (b < 0) b = 0;
    
    var g = (num & 0x0000FF) + amt;

    if ( g > 255 ) g = 255;
    else if  ( g < 0 ) g = 0;

    return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16);
}

好了,现在它不只是几行,但它看起来更简单,如果你不使用“#”,不需要检查颜色超出范围,它只是几行。

如果不使用“#”,你可以像这样在代码中添加它:

var myColor = "3F6D2A";
myColor = LightenDarkenColor(myColor,10);
thePlaceTheColorIsUsed = ("#" + myColor);

我想我的主要问题是,我说的对吗?这不是包括大多数(正常)情况吗?如果是的话,最快最小的方法是什么?我想在动画和小环境中使用,所以速度是这里的第一个最重要的因素,尺寸第二,准确性第三,可读性?嗯?不在要求清单上(对不起,我知道你们中有一半人正在泪眼汪汪!)


当前回答

下面是一个基于Eric的回答的超级简单的一行代码

function adjust(color, amount) {
    return '#' + color.replace(/^#/, '').replace(/../g, color => ('0'+Math.min(255, Math.max(0, parseInt(color, 16) + amount)).toString(16)).substr(-2));
}

例子:

adjust('#ffffff', -20) => "#ebebeb"
adjust('000000', 20) => "#141414"

其他回答

你考虑过RGB > HSL转换吗?然后上下移动亮度?这就是我要走的路。

快速查找一些算法得到了以下网站。

PHP: http://serennu.com/colour/rgbtohsl.php

Javascript: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript

编辑以上链接不再有效。你可以查看git hub的页面源或要旨

或者,另一个StackOverflow问题可能是一个好地方。


尽管这不是OP的正确选择,但以下是我最初建议的代码的近似值。(假设你有rgb/hsl转换函数)

var SHADE_SHIFT_AMOUNT = 0.1; 

function lightenShade(colorValue)
{
    if(colorValue && colorValue.length >= 6)
    {
        var redValue = parseInt(colorValue.slice(-6,-4), 16);
        var greenValue = parseInt(colorValue.slice(-4,-2), 16);
        var blueValue = parseInt(colorValue.slice(-2), 16);

        var hsl = rgbToHsl(redValue, greenValue, blueValue);
        hsl[2]= Math.min(hsl[2] + SHADE_SHIFT_AMOUNT, 1);
        var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
        return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
    }
    return null;
}

function darkenShade(colorValue)
{
    if(colorValue && colorValue.length >= 6)
    {
        var redValue = parseInt(colorValue.slice(-6,-4), 16);
        var greenValue = parseInt(colorValue.slice(-4,-2), 16);
        var blueValue = parseInt(colorValue.slice(-2), 16);

        var hsl = rgbToHsl(redValue, greenValue, blueValue);
        hsl[2]= Math.max(hsl[2] - SHADE_SHIFT_AMOUNT, 0);
        var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
        return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
    }
    return null;
}

这样的假设:

你有hslToRgb和rgbToHsl函数。 参数colorValue是一个#RRGGBB形式的字符串

虽然我们讨论的是css,但在IE9/Chrome/Firefox中有指定hsl/hsla的语法。

我在c#中需要它,它可以帮助。net开发人员

public static string LightenDarkenColor(string color, int amount)
    {
        int colorHex = int.Parse(color, System.Globalization.NumberStyles.HexNumber);
        string output = (((colorHex & 0x0000FF) + amount) | ((((colorHex >> 0x8) & 0x00FF) + amount) << 0x8) | (((colorHex >> 0xF) + amount) << 0xF)).ToString("x6");
        return output;
    }

我尝试了你的函数,有一个小错误:如果最终的'r'值只有1位,结果就会出现'a0a0a',而正确的值是'0a0a0a'。 我只是通过添加这个而不是你的返回来快速修复它:

var rStr = (r.toString(16).length < 2)?'0'+r.toString(16):r.toString(16);
var gStr = (g.toString(16).length < 2)?'0'+g.toString(16):g.toString(16);
var bStr = (b.toString(16).length < 2)?'0'+b.toString(16):b.toString(16);

return (usePound?"#":"") + rStr + gStr + bStr;

也许不是很好,但确实有用。顺便说一句,功能很好。这正是我需要的。:)

我做了一个优秀的xcolor库的移植,以消除它的jQuery依赖。里面有很多功能,包括调亮和调暗颜色。

实际上,将十六进制转换为RGB是一个完全独立于颜色变亮或变暗的功能。请保持衣物干燥。在任何情况下,一旦你有了RGB颜色,你可以把你想要的光级别和你必须的光级别之间的差值加到每个RGB值上:

var lightness = function(level) {
    if(level === undefined) {
        return Math.max(this.g,this.r,this.b)
    } else {
        var roundedLevel = Math.round(level) // fractions won't work here
        var levelChange = roundedLevel - this.lightness()

        var r = Math.max(0,this.r+levelChange)
        var g = Math.max(0,this.g+levelChange)
        var b = Math.max(0,this.b+levelChange)

        if(r > 0xff) r = 0xff
        if(g > 0xff) g = 0xff
        if(b > 0xff) b = 0xff

        return xolor({r: r, g: g, b: b})
    }
}

var lighter = function(amount) {
    return this.lightness(this.lightness()+amount)
}

更多信息请参见https://github.com/fresheneesz/xolor。

这是基于函数的。我更喜欢使用步骤而不是百分比,因为这对我来说更直观。

例如,蓝色值200的20%与蓝色值40的20%有很大不同。

不管怎样,这是我的修改,谢谢你原来的功能。

function adjustBrightness(col, amt) {

    var usePound = false;

    if (col[0] == "#") {
        col = col.slice(1);
        usePound = true;
    }

    var R = parseInt(col.substring(0,2),16);
    var G = parseInt(col.substring(2,4),16);
    var B = parseInt(col.substring(4,6),16);

    // to make the colour less bright than the input
    // change the following three "+" symbols to "-"
    R = R + amt;
    G = G + amt;
    B = B + amt;

    if (R > 255) R = 255;
    else if (R < 0) R = 0;

    if (G > 255) G = 255;
    else if (G < 0) G = 0;

    if (B > 255) B = 255;
    else if (B < 0) B = 0;

    var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
    var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
    var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));

    return (usePound?"#":"") + RR + GG + BB;

}