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

时间:2022-11-21 20:20:16

I'm trying to create a color opposite of current color. I mean if current color is black, then I need to generate white.

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

Actually I have a text (the color of this text is dynamic, its color can be made at random). That text is into a div and I need to set the opposite color of that text for the background-color of div. I would like that text be clear in the div (color perspective).

实际上我有一个文本(这个文本的颜色是动态的,它的颜色可以随意制作)。该文本属于div,我需要为div的背景色设置与该文本相反的颜色。

The opposite color means: Dark / Bright

相反的颜色表示:暗/亮

I have the current color of text and I can pass it to this function:

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

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)

Is there any idea to create create_opp_color() function ?

有没有创建create_opp_color()函数的想法?

5 个解决方案

#1


51  

UPDATE: Production-ready code on GitHub.

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


This is how I'd do it:

我是这样做的:

  1. Convert HEX to RGB
  2. 十六进制转换为RGB
  3. Invert the R,G and B components
  4. 把R G B的分量反过来
  5. Convert each component back to HEX
  6. 将每个组件转换回十六进制
  7. Pad each component with zeros and output.
  8. 用0和输出填充每个组件。
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);
}

Example Output:

示例输出:

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

Advanced Version:

高级版:

This has a bw option that will decide whether to invert to black or white; so you'll get more contrast which is generally better for the human eye.

它有一个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://*.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);
}

Example Output:

示例输出:

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

#2


3  

Watch out Accesibility (AA/AAA). Colour contrast by itself is useless. Really different colors can have no contrast at all for colour blind people. IMHO a calculation for such a color could go like this:

小心Accesibility(AA / AAA)。色彩对比本身是没有用的。真正不同的颜色对于色盲的人来说根本没有对比。对这种颜色的计算可以是这样的:

(Use "HLS" for simplicity)

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

  • Rotate Hue 180º to get the (maybe useless) maximal color contrast
  • 旋转色调180º(可能是无用的)最大的颜色对比
  • Calculate Brightness Difference.
  • 计算亮度差异。
  • ( Calculate Colour Difference... unnecesary, it's maximal or almost )
  • (计算色差…不必要的,它是最大值或几乎)
  • Calculate Contrast Ratio.
  • 计算对比度。
  • If the resulting color complies the requirements calculation ends, if not, loop:
    • If Brightness Difference is not enought increase or decrese calculated color luminosity (L) by a certain amount or ratio (up or down depending on the original colour brightness: > or < than the mid value)
    • 如果亮度差异不应该增加或减少计算出来的颜色光度(L)以一定的数量或比例增加或减少(根据原始颜色亮度的高低:>或 <中间值)< li>
    • Check if it complies your requirements, if it does calculation ends.
    • 检查它是否符合您的要求,是否计算结束。
    • if luminosity can be increased (or decrased) any more there is no valid color to comply the requirements, just try black and white, take "the best one" of those (probably the one with bigger contrast ratio) and end.
    • 如果光度可以增加(或减少),没有有效的颜色来满足要求,只要尝试黑白,取其中的“最佳”(可能是对比度更大的那个),然后结束。
  • 如果由此产生的颜色符合要求计算结束后,如果没有,循环:如果亮度差异并非能增加或递减计算颜色亮度(L)由一定数量或比率(向上或向下取决于最初的颜色亮度:>或 <比价值)中期检查它是否符合您的需求,如果真的计算结束。如果光度可以增加(或减少),没有有效的颜色来满足要求,只要尝试黑白,取其中的“最佳”(可能是对比度更大的那个),然后结束。< li>

#3


3  

In my understanding of your question, by opposite color you mean inverted color.

在我对你的问题的理解中,用相反的颜色你是指倒装的颜色。

InvertedColorComponent = 0xFF - ColorComponent

So for the color red (#FF0000) this means: R = 0xFF or 255 G = 0x00 or 0 B = 0x00 or 0

对于红色(#FF0000)表示:R = 0xFF或255 G = 0x00或0 B = 0x00或0

inverted color red (#00FFFF) is:

反色红色(#00FFFF)是:

R = 0xFF - 0xFF = 0x00 or 255 - 255 = 0
G = 0xFF - 0x00 = 0xFF or 255 - 0 = 255
B = 0xFF - 0x00 = 0xFF or 255 - 0 = 255

Another examples:

另一个例子:

Black (#000000) becomes White (#FFFFFF).

黑色(#000000)变成白色(# ffff)。

Orange (#FFA500) becomes #005AFF

橘色(# FFA500)变成了# 005等于off

#4


1  

Simply flipping background color to text color won't work with some middle range values, e.g. 0x808080. I had tried with shifting the color values instead - (v + 0x80) % 0x100. See a demo here.

简单地将背景颜色转换为文本颜色就不能使用中间值,例如0x808080。我尝试过改变颜色值——(v + 0x80) % 0x100。看到一个演示。

Agreeing with the comment from miguel-svq - although expecting to see more detailed algorithms for each calculation step.

同意migue -svq的评论——尽管希望看到每个计算步骤的更详细的算法。

#5


1  

Simple way to achieve this with CSS:

使用CSS实现这一点的简单方法:

mix-blend-mode: difference;
color:white;

#1


51  

UPDATE: Production-ready code on GitHub.

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


This is how I'd do it:

我是这样做的:

  1. Convert HEX to RGB
  2. 十六进制转换为RGB
  3. Invert the R,G and B components
  4. 把R G B的分量反过来
  5. Convert each component back to HEX
  6. 将每个组件转换回十六进制
  7. Pad each component with zeros and output.
  8. 用0和输出填充每个组件。
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);
}

Example Output:

示例输出:

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

Advanced Version:

高级版:

This has a bw option that will decide whether to invert to black or white; so you'll get more contrast which is generally better for the human eye.

它有一个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://*.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);
}

Example Output:

示例输出:

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

#2


3  

Watch out Accesibility (AA/AAA). Colour contrast by itself is useless. Really different colors can have no contrast at all for colour blind people. IMHO a calculation for such a color could go like this:

小心Accesibility(AA / AAA)。色彩对比本身是没有用的。真正不同的颜色对于色盲的人来说根本没有对比。对这种颜色的计算可以是这样的:

(Use "HLS" for simplicity)

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

  • Rotate Hue 180º to get the (maybe useless) maximal color contrast
  • 旋转色调180º(可能是无用的)最大的颜色对比
  • Calculate Brightness Difference.
  • 计算亮度差异。
  • ( Calculate Colour Difference... unnecesary, it's maximal or almost )
  • (计算色差…不必要的,它是最大值或几乎)
  • Calculate Contrast Ratio.
  • 计算对比度。
  • If the resulting color complies the requirements calculation ends, if not, loop:
    • If Brightness Difference is not enought increase or decrese calculated color luminosity (L) by a certain amount or ratio (up or down depending on the original colour brightness: > or < than the mid value)
    • 如果亮度差异不应该增加或减少计算出来的颜色光度(L)以一定的数量或比例增加或减少(根据原始颜色亮度的高低:>或 <中间值)< li>
    • Check if it complies your requirements, if it does calculation ends.
    • 检查它是否符合您的要求,是否计算结束。
    • if luminosity can be increased (or decrased) any more there is no valid color to comply the requirements, just try black and white, take "the best one" of those (probably the one with bigger contrast ratio) and end.
    • 如果光度可以增加(或减少),没有有效的颜色来满足要求,只要尝试黑白,取其中的“最佳”(可能是对比度更大的那个),然后结束。
  • 如果由此产生的颜色符合要求计算结束后,如果没有,循环:如果亮度差异并非能增加或递减计算颜色亮度(L)由一定数量或比率(向上或向下取决于最初的颜色亮度:>或 <比价值)中期检查它是否符合您的需求,如果真的计算结束。如果光度可以增加(或减少),没有有效的颜色来满足要求,只要尝试黑白,取其中的“最佳”(可能是对比度更大的那个),然后结束。< li>

#3


3  

In my understanding of your question, by opposite color you mean inverted color.

在我对你的问题的理解中,用相反的颜色你是指倒装的颜色。

InvertedColorComponent = 0xFF - ColorComponent

So for the color red (#FF0000) this means: R = 0xFF or 255 G = 0x00 or 0 B = 0x00 or 0

对于红色(#FF0000)表示:R = 0xFF或255 G = 0x00或0 B = 0x00或0

inverted color red (#00FFFF) is:

反色红色(#00FFFF)是:

R = 0xFF - 0xFF = 0x00 or 255 - 255 = 0
G = 0xFF - 0x00 = 0xFF or 255 - 0 = 255
B = 0xFF - 0x00 = 0xFF or 255 - 0 = 255

Another examples:

另一个例子:

Black (#000000) becomes White (#FFFFFF).

黑色(#000000)变成白色(# ffff)。

Orange (#FFA500) becomes #005AFF

橘色(# FFA500)变成了# 005等于off

#4


1  

Simply flipping background color to text color won't work with some middle range values, e.g. 0x808080. I had tried with shifting the color values instead - (v + 0x80) % 0x100. See a demo here.

简单地将背景颜色转换为文本颜色就不能使用中间值,例如0x808080。我尝试过改变颜色值——(v + 0x80) % 0x100。看到一个演示。

Agreeing with the comment from miguel-svq - although expecting to see more detailed algorithms for each calculation step.

同意migue -svq的评论——尽管希望看到每个计算步骤的更详细的算法。

#5


1  

Simple way to achieve this with CSS:

使用CSS实现这一点的简单方法:

mix-blend-mode: difference;
color:white;