svgsvg-filterscompositing

Applying destination-out compositing in SVG


I'd like to apply destination-out compositing to my SVG so that one shape can "erase" other, existing shapes. According to what I've read on the documentation for the <feComposition> SVG element, this should work, but it doesn't produce the desired result. I am attempting to use the in="BackgroundImage" attribute to apply my filter to everything in the SVG document that occurs before the filter is used.

<svg viewBox="0 0 100 100">
  <filter id="destination-out">
    <feComposite in="BackgroundImage" operator="out" />
  </filter>
  <polyline points="0,25 100,25" stroke="black" />
  <polyline points="0,50 100,50" stroke="black" />
  <polyline points="0,20 100,60" stroke="black" filter="url(#destination-out)" />
</svg>

Here's a jsBin showing what this code produces. I would like the third, diagonal <polyline> to not be visible at all; instead I want it to "erase" the places where it intersects the first two <polyline>s.

Legacy browser support is not important for my purposes; this just needs to work in the latest version of Chrome.


Solution

  • BackgroundImage is not a supported input type in any major current browser and has been deprecated for future browsers.

    To accomplish what you want to do, you're going to have to input the shapes you want to use in the filter as a SourceGraphic input and the shape that you want to use as the second input via an feImage. feImage supports direct fragment references everywhere except Firefox, so to get full cross browser support you will need to inline that shape as a separate SVG data URI in your feImage.

    Here is a version that works in non-Firefox.

    <svg width="100px" height="100px" viewBox="0 0 100 100">
    <defs>
      <polyline id="second-shape" points="0,20 100,60" stroke="black" stroke-width="3"/>
    
      <filter id="destination-out">
       <feImage x="0" y="0" width="100" height="100" xlink:href="#second-shape"/>
       <feComposite in="SourceGraphic" operator="out" />
      </filter>
    
      </defs>
      <g filter="url(#destination-out)" >
      <polyline points="0,25 100,25" stroke="red" />
      <polyline points="0,50 100,50" stroke="blue" />
      </g>
    
    </svg>