34

Is it possible to invert the action of a clip with SVG? I'd like to show the path between the two circles rather than inside the circles:

<svg width="50%" height="50%" viewbox="0 0 985 740" xmlns="http://www.w3.org/2000/svg">
  <g>
     <clipPath id="re8-clip" clip-rule="nonzero">
        <rect id="sa11" x="763.0" y="176.5" width="70.0" height="25.0" rx="50" ry="50" fill="ForestGreen"/>
        <rect id="sa12" x="516.0" y="127.5" width="70.0" height="25.0" rx="50" ry="50" fill="ForestGreen"/>
     </clipPath>
     <rect id="sa11" x="763.0" y="176.5" width="70.0" height="25.0" rx="50" ry="50" fill="ForestGreen"/>
     <rect id="sa12" x="516.0" y="127.5" width="70.0" height="25.0" rx="50" ry="50" fill="ForestGreen"/>
  </g>
  <path stroke="Black" stroke-width="1.5" fill="none" d="M 798.0 189.0 551.0 140.0" clip-path="url(#re8-clip)"/>
</svg>
Zach Jensz
  • 3,650
  • 5
  • 15
  • 30
kai
  • 1,970
  • 2
  • 22
  • 30

1 Answers1

28

Following the link in Duopixel's comment, the problem can be solved using a mask:

<svg width="50%" height="50%" viewbox="0 0 985 740" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <rect id="sa11" x="763.0" y="176.5" width="70.0" height="25.0" rx="50" ry="50" />
    <rect id="sa12" x="516.0" y="127.5" width="70.0" height="25.0" rx="50" ry="50" />
  </defs>
  <mask id="re8-clip">
    <rect id="bg" x="0" y="0" width="100%" height="100%" fill="white"/>
    <use xlink:href="#sa11" fill="Black" />
    <use xlink:href="#sa12" fill="Black" />
  </mask>
  <use xlink:href="#sa11" fill="ForestGreen" />
  <use xlink:href="#sa12" fill="ForestGreen" />
  <path stroke="Black" stroke-width="1.5" fill="none" d="M 798.0 189.0 551.0 140.0" mask="url(#re8-clip)"/>
</svg>

As a minor aside, does anybody know if it is possible for a mask to default to white, so the 'bg' rectangle is not necessary?

Ruskin
  • 5,721
  • 4
  • 45
  • 62
kai
  • 1,970
  • 2
  • 22
  • 30
  • 5
    about the minor aside, least amount of chars one can get the fill white is with something like: `` inside the mask. – Ciantic Jun 04 '13 at 18:53
  • You can reuse the tags, replace the two rects in `` with this: `` – fregante Dec 07 '14 at 10:46
  • 1
    True, but they have to be defined separately since the `use` tag won't override a `fill` attribute. Answer updated, including Ciantic's comment. – kai Dec 08 '14 at 14:23
  • I was using this technique with some objects which are positioned by the user with drag and drop. I found that the objects I was masking were mysteriously disappearing if they moved them too far. I was able to fix this using the width, height, x, y and maskUnits properties on the element itself. – GlennS Mar 30 '15 at 16:18
  • you're a genius RuskiN! – Tom Roggero Mar 06 '18 at 22:15
  • 1
    Can we have a text description of what you're doing here? – posfan12 May 04 '21 at 00:37