How can I generate the opposite color according to current color?

前端 未结 11 537
北海茫月
北海茫月 2020-11-28 01:53

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

相关标签:
11条回答
  • 2020-11-28 02:27

    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.

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

    0 讨论(0)
  • 2020-11-28 02:27

    It is possible to convert a HEX color using the snippets

    function invertColor(color) {
          return '#' + ("000000" + (0xFFFFFF ^ parseInt(color.substring(1),16)).toString(16)).slice(-6);
      }
    
    0 讨论(0)
  • 2020-11-28 02:28

    This is a simple function that invert an hexadecimal color

    const invertColor = (col) => {
      const colors = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
      let inverseColor = '#'
      col.replace('#','').split('').forEach(i => {
        const index = colors.indexOf(i)
        inverseColor += colors.reverse()[index]
      })
      return inverseColor
    }
    
    

    Codepen example

    0 讨论(0)
  • 2020-11-28 02:38

    UPDATE: Production-ready code on GitHub.


    This is how I'd do it:

    1. Convert HEX to RGB
    2. Invert the R,G and B components
    3. Convert each component back to HEX
    4. Pad each component with zeros and output.
    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.

    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);
    }
    

    Example Output:

    0 讨论(0)
  • 2020-11-28 02:38

    Pure CSS implementation of @Onur's answer bw part.

      <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>

    0 讨论(0)
  • 2020-11-28 02:40

    Simple and elegant.

    function invertHex(hex) {
      return (Number(`0x1${hex}`) ^ 0xFFFFFF).toString(16).substr(1).toUpperCase()
    }
    
    invertHex('00FF00'); // Returns FF00FF
    
    0 讨论(0)
提交回复
热议问题