1

the question might sound like an oxymoron, but I have groups of svg objects connected by lines. Here's the barebone version:

<svg width="200" height="200">
<defs>
  <clipPath id='clipLine'>
    <circle cx='0' cy='0' r="30"/>
  </clipPath>
</defs>
<rect x='0' y='0' width='200' height='200' fill='rgb(255,128,255)' /> 
  <line x1="50" y1="50" x2="150" y2="75" stroke='red' stroke-width='2' />
<g>
  <circle cx="50" cy="50" r="20" stroke="green" stroke-width="4" fill="yellow" />
  <circle cx="50" cy="50" r="30" stroke="green" stroke-width="4" fill-opacity='0.0' clip-path="url(#clipLine)"/>
</g>
<g>
  <circle cx="150" cy="75" r="20" stroke="green" stroke-width="4" fill="yellow" />
  <circle cx="150" cy="75" r="30" stroke="green" stroke-width="4" fill-opacity='0.0' clip-path="url(#clipLine)"/>
</g>
</svg>

I have an inner circle and an outer circle. the outer circle is transparent, with a visible perimeter, and the line is connecting the two nodes, by the cx,cy coordinates. I'd like the line to only reach the perimeter of the outer circle.

I could calculate the positions with vector math,but i don't know it will affect performance when i'll be dragging around a bunch of these. Can I use clipping and masking to reach the same effect? So far i could only hide the circles and the entire line when i tried to append clipping on them.

val
  • 729
  • 6
  • 19

1 Answers1

2

Inverting shape with mask

I am not sure what your problem is so im going to take a guess that this is your issue: The line is at the center and you only want it to go to the perimeter of the shape:

<svg width="200" height="200">
  <defs>
    <clipPath id='clipLine'>
      <circle cx='0' cy='0' r="30" />
    </clipPath>
  </defs>
  <rect x='0' y='0' width='200' height='200' fill='rgb(255,128,255)' />
  <line x1="50" y1="50" x2="150" y2="75" stroke='red' stroke-width='2' />
  <g>
    <circle cx="50" cy="50" r="20" stroke="green" stroke-width="4" fill="none" />
    <circle cx="50" cy="50" r="30" stroke="green" stroke-width="4" fill-opacity='0.0' clip-path="url(#clipLine)" />
  </g>
  <g>
    <circle cx="150" cy="75" r="20" stroke="green" stroke-width="4" fill="none" />
    <circle cx="150" cy="75" r="30" stroke="green" stroke-width="4" fill-opacity='0.0' clip-path="url(#clipLine)" />
  </g>
</svg>

Mask

I learned how to invert a svg exclusing using this answer Invert-svg
Setting a rect to cover the entire svg and setting the shape you are using as the darkest part of that mask to exclude it.

<svg width="200" height="200" xmlns:xlink="http://www.w3.org/1999/xlink">
  <mask id='clipLine'>
    <rect height="100%" width="100%" fill="white" />
    <circle id="circle1" cx="50" cy="50" r="28" fill="black" />
    <circle cx="150" cy="75" r="28" stroke="green" stroke-width="4" fill="black" />
  </mask>

  <rect x='0' y='0' width='200' height='200' fill='rgb(255,128,255)' />
  <line x1="50" y1="50" x2="150" y2="75" stroke='red' stroke-width='2' mask="url(#clipLine)" />
  <g>
    <!--use xlink:href="#circle1"/> OUr actual circle-->
    <circle cx="50" cy="50" r="30" stroke="green" stroke-width="4" fill-opacity='0.0' />
  </g>
  <g>
    <circle cx="150" cy="75" r="30" stroke="green" stroke-width="4" fill-opacity='0.0' />
  </g>
</svg>
Community
  • 1
  • 1
Persijn
  • 14,624
  • 3
  • 43
  • 72