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

sta*_*ack 53 html javascript css jquery colors

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

其实我有一个文本(这个文本的颜色是动态的,它的颜色可以随机制作).这是文成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)
Run Code Online (Sandbox Code Playgroud)

是否有创建create_opp_color()功能的想法?

Onu*_*rım 140

更新:GitHub上的生产就绪代码.


我就是这样做的:

  1. 将HEX转换为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);
}
Run Code Online (Sandbox Code Playgroud)

示例输出:

在此输入图像描述

高级版:

这有一个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) {
        // http://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);
}
Run Code Online (Sandbox Code Playgroud)

示例输出:

在此输入图像描述

  • 我使用内置的 .padStart 函数进行返回。return "#" + r.padStart(2, '0') + g.padStart(2, '0') + b.padStart(2, '0'); https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart (2认同)

Ger*_*amo 13

简洁大方。

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

invertHex('00FF00'); // Returns FF00FF
Run Code Online (Sandbox Code Playgroud)

  • 不知道它做什么或如何工作,但它确实简单而优雅:) (2认同)
  • 如果有人能解释它是如何工作的,我会非常高兴。 (2认同)
  • @ Ar2`Number(`0x1 $ {hex}`)`首先,它获取给定的十六进制(字符串)值,并将其转换为HEX`^ 0xFFFFFF`,然后使用`0xFFFFFF`对那个值进行按位执行。现在只能这样解释,如果您想尽快将数字取反,例如。3> 7、8> 2、1> 9等。简单地将数字与10相减,然后将其绝对。那是该部分的工作,除了十六进制值。其余的基本上是格式化和删除第一个值,这是等式的溢出。 (2认同)
  • 非常漂亮和简单,但请注意,它“镜像到颜色的中间”,因此接近中间的颜色会得到非常接近的颜色。例如 invertHex('808080'); 产生几乎相同颜色的“7F7F7F”。 (2认同)

Fen*_*nec 11

CSS 怎么样,filter: invert(1)它具有良好的跨浏览器兼容性,并且可以处理文本和图像或任何内容。

\n

对于黑白反转颜色,添加更多滤镜,filter: saturate(0) grayscale(1) brightness(.7) contrast(1000%) invert(1)

\n

这是一个 ColorPicker 示例(注意文本颜色):

\n

\r\n
\r\n
const colorPicker = document.querySelector("input");\nconst background = document.querySelector("div");\nconst invertedText = document.querySelector("b");\n\ncolorPicker.oninput = (e) => {\n  const color = e.target.value;\n  background.style.background = color;\n  invertedText.style.color = color;\n  invertedText.innerText = color;\n}
Run Code Online (Sandbox Code Playgroud)\r\n
body {\n  font-family: Arial;\n  background: #333;\n}\n\ndiv {\n  position: relative;\n  display: inline-flex;\n  justify-content: center;\n  align-items: center;\n  min-width: 100px;\n  padding: .5em 1em;\n  border: 2px solid #FFF;\n  border-radius: 15px;\n  background: #378ad3;\n}\n\nb {\n  /* Inverting the color \xe1\x90\xaf\xe1\x90\xaf\xe1\x90\xaf\xe1\x90\xaf\xe1\x90\xaf\xe1\x90\xaf\xe1\x90\xaf\xe1\x90\xaf\xe1\x90\xaf\xe1\x90\xaf\xe1\x90\xaf\xe1\x90\xaf */\n  filter: saturate(0) grayscale(1) brightness(.7) contrast(1000%) invert(1);\n}\n\ninput {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  opacity: 0;\n  cursor: pointer;\n}
Run Code Online (Sandbox Code Playgroud)\r\n
<div>\n  <b>#378ad3</b>\n  <input type="color" value="#378ad3"/>\n</div>
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n


rap*_*dko 10

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

mix-blend-mode: difference;
color:white;
Run Code Online (Sandbox Code Playgroud)

  • 注意事项:!E或Microsoft Edge当前不支持mix-blend-mode,并且根据您的使用情况,可能不太可能正常失败。 (2认同)

Jam*_*sgt 10

@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>
Run Code Online (Sandbox Code Playgroud)


mig*_*svq 5

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

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

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