SumNeuron
SumNeuron

Reputation: 5188

SVG Path - render only a percent of the specified path

NOTE: I have a feeling that the answers to this question will rely on the dashed stroke trick often used to answer questions about animating svg path ( e.g. Animate svg path, and the countless other similar questions). If possible, I am looking for an answer that does not rely on dashed lines.

Suppose you have an SVG with a path between some number of objects. You know where the objects are centered and their width. In principal you could calculate a path that only goes from the the edges of each object. However, this can be tedious. So how can you specify a path form object 1 to object 2, but offset the drawn part so it is only shown from the edges?

In the code below, the first path between two points uses their center. This is how I want to specify my path. The second path is how I would like the path to be rendered. e.g. I am looking for some attribute like offset-from-start=10 and offset-from-end=10 to do this. If the path is compound or if the object has an irregular shape, calculating the angle of the shorter path is tedious (but straightforward). In addition, using a shorter path, changes curves, where hopefully this offset does not.

<svg style="width:200px;height:200px">
  <circle r="10" cx="10" cy="10" fill="red"></circle>
  <circle r="10" cx="190" cy="10" fill="red" style="opacity:0.5"></circle>
  <path d="M10 10 L 190 10" stroke-width="4" stroke="black"></path>


  <circle r="10" cx="10" cy="50" fill="red"></circle>
  <circle r="10" cx="190" cy="50" fill="red" style="opacity:0.5"></circle>
  <path d="M20 50 L 180 50" stroke-width="4" stroke="black"></path>

</svg>

Upvotes: 1

Views: 591

Answers (1)

ccprog
ccprog

Reputation: 21811

If you want to avoid using the stroke-dasharray property, how about simply hiding the part of the path that intersects your object? The straightforward way to do this is avoiding partial transparency and drawing the path below:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     style="width:200px;height:50px">
  <path d="M10 10 L 190 10" stroke-width="4" stroke="black"></path>
  <circle r="10" cx="10" cy="10" fill="red"></circle>
  <circle r="10" cx="190" cy="10" fill="#ff8080"></circle>
</svg>

A bit more sophisticated would be to define a mask. For that, you need to first define any object inside the mask without styling (implicit black) on a white background, and then reuse them with the visual styles:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     style="width:200px;height:50px">
  <mask id="mask" maskUnits="userSpaceOnUse">
    <rect width="100%" height="100%" fill="white" />
    <circle id="obj1" r="10" cx="10" cy="10" />
    <circle id="obj2" r="10" cx="190" cy="10" />
  </mask>
  <use xlink:href="#obj1" fill="red" />
  <use xlink:href="#obj2" fill="red" opacity="0.5" />
  <path d="M10 10 L 190 10" stroke-width="4" stroke="black" mask="url(#mask)" />
</svg>

Upvotes: 1

Related Questions