javascriptcssmix-blend-mode

Getting a measure of difference from mix blend mode


Is there a way of getting a measure of difference when mix-blend-mode: difference is set on a text? like average change in font colour?

Basically given the code below:

.container {
    background-color: #fff;
}

.text {
    mix-blend-mode: difference;
    color: #000;
}

How can I get a measure that the text colour has 100% changed. The text was black originally but with mix-blend-mode: difference; on a white background it has become white which is 100%. I want a way of querying this change.


Solution

  • The only way I can think of doing this at a browser script level is recreating the scenario on a Canvas renderer context.

    This code is specifically targeted for the terms and conditions applied to your question, so it may need to be altered for other scenarios:

    function getComputedContainerTextColor(element) {
      const canvas = document.createElement("canvas");
      canvas.width = 1;
      canvas.height = 1;
    
      const context = canvas.getContext("2d");
    
      const containerComputedStyle = window.getComputedStyle(element.parentElement);
    
      context.fillStyle = containerComputedStyle.backgroundColor;
      context.fillRect(0, 0, 1, 1);
      
      const textComputedStyle = window.getComputedStyle(element);
    
      context.globalCompositeOperation = textComputedStyle.mixBlendMode;
      context.fillStyle = textComputedStyle.color;
      context.fillRect(0, 0, 1, 1);
    
      const imageData = context.getImageData(0, 0, 1, 1);
    
      return [ imageData.data[0], imageData.data[1], imageData.data[2], imageData.data[3] ];
    }
    
    const text = document.querySelector(".text");
    const color = getComputedContainerTextColor(text);
    
    console.log(color);
    .container {
        background-color: #fff;
    }
    
    .text {
        mix-blend-mode: difference;
        color: #000;
    }
    <div class="container">
      <span class="text">hello world</span>
    </div>

    This creates a 1x1 px canvas in the background, gets the computed background color of the container, and the computed blend mode and color of the text element, applies them in the same order, and then extracts the image data - grabbing the 4 color indices (RGBA).