如何根据当前颜色生成相反的颜色?

IT技术 javascript jquery html css colors
2021-02-05 14:25:49

我正在尝试创建与当前颜色相反的颜色。我的意思是如果当前颜色是黑色,那么我需要生成白色

其实我有一个文本(这个文本的颜色是动态的,它的颜色可以随意制作)这是文成div,我需要设置文本的相反颜色background-colordiv我希望该文本(颜色透视)中清晰div

相反的颜色表示:暗/亮

我有当前的文本颜色,我可以将它传递给这个函数:

var TextColor = #F0F0F0;    // for example (it is a bright color)

function create_opp_color(current color) {

    // create opposite color according to current color

}

create_opp_color(TextColor); // this should be something like "#202020" (or a dark color)

有什么想法可以创建create_opp_color()功能吗?

6个回答

更新GitHub 上的生产就绪代码


这就是我要做的:

  1. 将十六进制转换为 RGB
  2. 反转 R、G 和 B 分量
  3. 将每个组件转换回 HEX
  4. 用零和输出填充每个组件。
function invertColor(hex) {
    if (hex.indexOf('#') === 0) {
        hex = hex.slice(1);
    }
    // convert 3-digit hex to 6-digits.
    if (hex.length === 3) {
        hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
    }
    if (hex.length !== 6) {
        throw new Error('Invalid HEX color.');
    }
    // invert color components
    var r = (255 - parseInt(hex.slice(0, 2), 16)).toString(16),
        g = (255 - parseInt(hex.slice(2, 4), 16)).toString(16),
        b = (255 - parseInt(hex.slice(4, 6), 16)).toString(16);
    // pad each with zeros and return
    return '#' + padZero(r) + padZero(g) + padZero(b);
}

function padZero(str, len) {
    len = len || 2;
    var zeros = new Array(len).join('0');
    return (zeros + str).slice(-len);
}

示例输出:

在此处输入图片说明

进阶版:

这有一个bw选项可以决定是反转为黑色还是白色;所以你会得到更多的对比度,这通常对人眼更好。

function invertColor(hex, bw) {
    if (hex.indexOf('#') === 0) {
        hex = hex.slice(1);
    }
    // convert 3-digit hex to 6-digits.
    if (hex.length === 3) {
        hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
    }
    if (hex.length !== 6) {
        throw new Error('Invalid HEX color.');
    }
    var r = parseInt(hex.slice(0, 2), 16),
        g = parseInt(hex.slice(2, 4), 16),
        b = parseInt(hex.slice(4, 6), 16);
    if (bw) {
        // https://stackoverflow.com/a/3943023/112731
        return (r * 0.299 + g * 0.587 + b * 0.114) > 186
            ? '#000000'
            : '#FFFFFF';
    }
    // invert color components
    r = (255 - r).toString(16);
    g = (255 - g).toString(16);
    b = (255 - b).toString(16);
    // pad each with zeros and return
    return "#" + padZero(r) + padZero(g) + padZero(b);
}

示例输出:

在此处输入图片说明

是的。这就是所谓的微图书馆。更易于维护,包含 SRP 等。
2021-03-20 14:25:49
@OnurYıldırım 添加了积分。不过很好的提醒。
2021-03-27 14:25:49
我使用内置的 .padStart 函数进行返回。return "#" + r.padStart(2, '0') + g.padStart(2, '0') + b.padStart(2, '0'); developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-04-01 14:25:49
你做了一个函数库放到github上?:-)凉爽的
2021-04-03 14:25:49
这个“相反”问题的答案,将颜色设置为具有背景颜色的前景,几乎相同。根据原始问题更改小提琴可能会导致低对比度颜色(没有“bw”)或背景和白色背景jsfiddle.net/cffcd5bj/5希望@stack 对其进行调整以避免出现不需要的低对比度颜色对。
2021-04-08 14:25:49

简单而优雅。

function invertHex(hex) {
  return (Number(`0x1${hex}`) ^ 0xFFFFFF).toString(16).substr(1).toUpperCase()
}

invertHex('00FF00'); // Returns FF00FF
如果有人能解释它是如何工作的,我会非常高兴。
2021-03-23 14:25:49
@Ar2 Number(0x1${hex})首先,它采用给定的十六进制(字符串)值并将其转换为十六进制^ 0xFFFFFF,然后对该值执行按位执行0xFFFFFF,如果您想反转数字,我现在只能像这样解释尽快,例如。3 > 7, 8 > 2, 1 > 9 等等。简单地用数字减去 10 并绝对它。除了十六进制值之外,这就是该部分的作用。其余的基本上是格式化和删除作为等式溢出的第一个值。
2021-04-04 14:25:49
感人的!说明:^ 如果两位中只有一位为 1,则按位将每一位设置为 1;toString(16)该数字将显示为十六进制值;substr(1)返回结果字符串,但跳过第一项;toUpperCase()这是非常明显的。
2021-04-04 14:25:49
真的很好很简单,但请注意它“反映在颜色的中间”,所以靠近中间的颜色会得到非常接近它的颜色。例如 invertHex('808080'); 产生几乎相同颜色的“7F7F7F”。
2021-04-11 14:25:49
不知道它做什么或如何工作,但它确实简单而优雅:)
2021-04-13 14:25:49

使用 CSS 实现此目的的简单方法:

mix-blend-mode: difference;
color:white;
注意事项:混合模式目前不受 !E 或 Microsoft Edge 等支持,并且根据您的用例,可能不太可能正常失败。
2021-03-20 14:25:49

@Onur 的答案bw 部分的纯 CSS 实现

  <input type="color" oninput="['--r','--g','--b'].forEach((k,i)=>this.nextElementSibling.style.setProperty(k,parseInt(event.target.value.slice(1+i*2,3+i*2),16)))" />
 
  <div style="--r: 0; --g: 0; --b: 0; --c: calc(-1 * ((var(--r) * 0.299 + var(--g) * 0.587 + var(--b) * 0.114) - 186) * 255)">
    <div style="background-color: rgb(var(--r), var(--g), var(--b)); color: rgb(var(--c), var(--c), var(--c))">Test</div>
  </div>

注意可访问性 (AA/AAA)。颜色对比本身是无用的。对于色盲的人来说,真正不同的颜色根本没有对比。恕我直言,这种颜色的计算可能是这样的:

(为简单起见,请使用“HLS”)

  • 将 Hue 旋转 180º 以获得(可能无用的)最大颜色对比度
  • 计算亮度差异。
  • (计算色差......不必要,它是最大或几乎)
  • 计算对比度。
  • 如果生成的颜色符合要求,计算结束,如果不符合,则循环:
    • 如果亮度差不够,则将计算出的颜色亮度 (L) 增加或减少一定数量或比例(根据原始颜色亮度增加或减少:> 或 < 比中间值)
    • 检查它是否符合您的要求,如果计算结束。
    • 如果亮度可以再增加(或降低),则没有符合要求的有效颜色,只需尝试黑色和白色,取其中“最好的一个”(可能是对比度较大的那个)并结束。