JavaScript计算较暗颜色

4

我该如何将这个计算结果的颜色变暗而不是变亮?

function increase_brightness(hex, percent){
    // strip the leading # if it's there
    hex = hex.replace(/^\s*#|\s*$/g, '');

    // convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
    if(hex.length == 3){
        hex = hex.replace(/(.)/g, '$1$1');
    }

    var r = parseInt(hex.substr(0, 2), 16),
        g = parseInt(hex.substr(2, 2), 16),
        b = parseInt(hex.substr(4, 2), 16);

    return '#' +
       ((0|(1<<8) + r + (256 - r) * percent / 100).toString(16)).substr(1) +
       ((0|(1<<8) + g + (256 - g) * percent / 100).toString(16)).substr(1) +
       ((0|(1<<8) + b + (256 - b) * percent / 100).toString(16)).substr(1);
}

src = JavaScript 计算更亮的颜色

演示 http://jsbin.com/utavax/3/edit


你尝试过使用负百分比吗? - Felice Pollano
4个回答

6

您可以更改

return '#' +
   ((0|(1<<8) + r + (256 - r) * percent / 100).toString(16)).substr(1) +
   ((0|(1<<8) + g + (256 - g) * percent / 100).toString(16)).substr(1) +
   ((0|(1<<8) + b + (256 - b) * percent / 100).toString(16)).substr(1);

to

return '#' +
   ((0|(1<<8) + r * (1 - percent / 100)).toString(16)).substr(1) +
   ((0|(1<<8) + g * (1 - percent / 100)).toString(16)).substr(1) +
   ((0|(1<<8) + b * (1 - percent / 100).toString(16)).substr(1);

这将解决你的问题。演示

但是,较暗的颜色并不是一个好的定义。较暗的颜色可以被解释为亮度或饱和度较低。因此,更好的方法是将RGB颜色空间转换为HSB颜色空间,并调整S/B通道,然后将它们转换回来。


一些关于为什么原始代码中负值不可行的解释。

以-100作为百分比,某个通道(比如r)小于128。那么

r + (256 - r) * percent / 100

如果小于0,则加上1 << 8 = 256。

((0|(1<<8) + r + (256 - r) * percent / 100)

数字小于256。

将一个小于256的数字通过调用toString(16)最多会生成两个十六进制数,因此.substr(1)仅包含0或1个数字。将所有这些错误的数字组合在一起将无法生成正确的十六进制表示的颜色。


4

我修改了你原来的函数,通过基本上将原始RGB值乘以一个百分比(向上或向下)的方法来实现廉价版的变亮/变暗。

function adjust(hexInput: string, percent: number) {
    let hex = hexInput;

    // strip the leading # if it's there
    hex = hex.replace(/^\s*#|\s*$/g, "");

    // convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
    if (hex.length === 3) {
        hex = hex.replace(/(.)/g, "$1$1");
    }

    let r = parseInt(hex.substr(0, 2), 16);
    let g = parseInt(hex.substr(2, 2), 16);
    let b = parseInt(hex.substr(4, 2), 16);

    const calculatedPercent = (100 + percent) / 100;

    r = Math.round(Math.min(255, Math.max(0, r * calculatedPercent)));
    g = Math.round(Math.min(255, Math.max(0, g * calculatedPercent)));
    b = Math.round(Math.min(255, Math.max(0, b * calculatedPercent)));

    return `#${r.toString(16).toUpperCase()}${g.toString(16).toUpperCase()}${b
        .toString(16)
        .toUpperCase()}`;
}

console.log(adjust("#49D174", -14)) // Darken by 14% = #3FB464 
console.log(adjust("#49D174", -27)) // Darken by 27% = #359955

该函数将百分比作为整数处理,但很容易改为小数。负数使其变暗,正数使其变亮。

0

我从Stylus1, 2)中获取了主要思路,并从Stack Overflow答案中提取了一些代码部分,制作了一个库darken_color.js

以下是一些使用示例:

darken('lightgreen', '0.1'); // -> #63e763 
darken('lightgreen', '10'); // -> #63e763
darken('#90EE90', '10'); // -> #63e763
darken('#9e9', '10%'); // ->  #98ed98

-1
return '#' +
   ((0|(1<<8) + r + (256 - r) * percent / 100).toString(16)).substr(1) +
   ((0|(1<<8) + g + (256 - g) * percent / 100).toString(16)).substr(1) +
   ((0|(1<<8) + b + (256 - b) * percent / 100).toString(16)).substr(1);

在这里,您正在将一些百分比的rgb添加到当前值中,从而使颜色变亮。如果您使用负值的百分比,则会从当前值中减去该值,并使颜色变暗。


给定百分比为-100,某些通道<128。然后,在加上1<<8之后,该通道的值小于256,并且toString()结果不再是3个字符长,因此颜色无效。这就是为什么负值不可以的原因。 - xiaoyi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接