Search code examples
svgsvg-filters

How to merge SVG masks?


I'm trying to "merge" two masks in SVG and apply them in a way that the white part of both masks is visible in the shape I apply it to.

I read that the solution might be feComposite, but I can't get it working... This is what i have so far:

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <mask id="mask1" x="0" y="0" width="200" height="200">
      <rect x="0" y="0" width="200" height="200" fill="black"/>
      <rect x="0" y="0" width="100" height="100" fill="white"/>
    </mask>
    <mask id="mask2" x="0" y="0" width="200" height="200">
      <rect x="0" y="0" width="200" height="200" fill="black"/>
      <rect x="100" y="100" width="100" height="100" fill="white"/>
    </mask>
    <filter id="combinedMask">
            <feComposite in="mask1" in2="mask2" operator="over"/>
    </filter>
  </defs>
  
  <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#combinedMask)"/>
</svg

The desired output in the case above would be this: output


Solution

  • You can combine the two masks in a mask.

    <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <mask id="mask1" x="0" y="0" width="200" height="200">
          <rect x="0" y="0" width="100" height="100" fill="white"/>
        </mask>
        <mask id="mask2" x="0" y="0" width="200" height="200">
          <rect x="100" y="100" width="100" height="100" fill="white"/>
        </mask>
        <mask id="combinedMask" x="0" y="0" width="200" height="200">
          <rect width="200" height="200" fill="white" mask="url(#mask1)"/>
          <rect width="200" height="200" fill="white" mask="url(#mask2)"/>
        </mask>
      </defs>
      <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#combinedMask)"/>
    </svg>