Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I draw a pattern along a stroke or a path in svg?

I need to draw pattern along SVG path. I tried using SVG markers but there is a problem with their orientation along the path. Is there any alternative way to accomplish this? If yes, what should be my approach? The expected result is something like this- enter image description here

like image 719
abhishek khandait Avatar asked Dec 15 '17 08:12

abhishek khandait


3 Answers

The idea to use unicodes for drawing chain links came at once, as I read the question.

I searched for a suitable unicode character for a long time. Could not use the unicode character of the chain. The unicode character of the U+26D3 ⛓ "chain" is very poorly supported.

enter image description here

I decided on the variant of using the Unicode character - "Latin small letter on the side" U+1D11 ᴑ and a hyphen to connect adjacent chain links - -

Powered by: Firefox, Chrome, Opera, IE11
I did not check the Safari browser.

<svg width="600" height="400" viewBox="80 100 400 300">

 <path id="pathChain" d="M100,200 C100,100 250,100 250,200 S 400,300 400,200" stroke="grey" fill="none"/>


<text font-size="36" x="0" y="0" font-family="Times New Roman" fill="grey" >
<textPath id="result"    xlink:href="#pathChain">
<tspan dx="0" > &#7441; </tspan> <tspan dx="-15">   &#45; </tspan><tspan dx="-15"> &#7441;</tspan><tspan dx="-15">   &#45;</tspan><tspan dx="-15">   &#7441; </tspan><tspan dx="-15">   &#45; </tspan><tspan dx="-15"> &#7441;</tspan><tspan dx="-15">   &#45;</tspan><tspan dx="-15">   &#7441; </tspan><tspan dx="-15">   &#45; </tspan><tspan dx="-15"> &#7441;</tspan><tspan dx="-15">   &#45;</tspan><tspan dx="-15">   &#7441; </tspan><tspan dx="-15">   &#45; </tspan><tspan dx="-15"> &#7441;</tspan><tspan dx="-15">   &#45;</tspan><tspan dx="-15">   &#7441; </tspan><tspan dx="-15">   &#45; </tspan><tspan dx="-15"> &#7441;</tspan><tspan dx="-15">   &#45;</tspan><tspan dx="-15">   &#7441; </tspan>
  </textPath>
</text>				
			
</svg>   

In addition to the statics of the chain, an example of animation.

The command that implements animation:

<animate dur="10s" repeatCount="2" attributeName="startOffset" values="1%;55%;1"/>

<svg width="600" height="400" viewBox="100 100 400 300">

 <path id="pathChain" d="M100,200 C100,100 250,100 250,200 S 400,300 400,200" stroke="grey" fill="none"/>

<text font-size="36"  font-family="Times New Roman" fill="grey" >
<textPath id="result"    xlink:href="#pathChain">
<tspan dx="0" > &#7441; </tspan> <tspan dx="-15">   &#45; </tspan><tspan dx="-15"> &#7441;</tspan><tspan dx="-15">   &#45;</tspan><tspan dx="-15">   &#7441; </tspan><tspan dx="-15">   &#45; </tspan><tspan dx="-15"> &#7441;</tspan><tspan dx="-15">   &#45;</tspan><tspan dx="-15">   &#7441; </tspan><tspan dx="-15">   &#45; </tspan><tspan dx="-15"> &#7441;</tspan><tspan dx="-15">   &#45;</tspan><tspan dx="-15">   &#7441; </tspan><tspan dx="-15">   &#45; </tspan><tspan dx="-15"> &#7441;</tspan><tspan dx="-15">   &#45;</tspan><tspan dx="-15">   &#7441; </tspan><tspan dx="-15">   &#45; </tspan><tspan dx="-15"> &#7441;</tspan><tspan dx="-15">   &#45;</tspan><tspan dx="-15">   &#7441; </tspan>
<animate  dur="10s" repeatCount="2" attributeName="startOffset" values="1%;55%;1%"/> 
</textPath>
</text>				
			
</svg>   
like image 104
Alexandr_TT Avatar answered Nov 13 '22 01:11

Alexandr_TT


In case anyone would search it and wouldn't want to use textPath mentioned in other answers, here's how this paricular chain pattern can be created using dashed lines. Many other patterns can be created in a similar way, especially if you incorporate filters (Edit: I created more examples here).

Here I use three dashed lines along the same path - two of them alternately create chain segments and the third one creates holes using mask.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 200">

<defs>
  <path id="chain-path" d="M 50,50 C 50,150 250,150 250,50" fill="none" stroke-linecap="round"/>

  <mask id="holes">
    <!-- white everywhere = keep everything... -->
    <rect x="0%" y="0%" width="100%" height="100%" fill="white"/>

    <!-- ...except holes -->
    <use href="#chain-path" stroke-width="4" stroke-dasharray="6 14" stroke-dashoffset="7" stroke="black"/>
  </mask>
</defs>

<!-- segments whose hole is visible, with holes cut out using mask-->
<use href="#chain-path" stroke-width="8" stroke-dasharray="6 14" stroke-dashoffset="7" stroke="black" stroke-opacity=".8" mask="url(#holes)"/>

<!-- segments whose hole isn't visible -->
<use href="#chain-path" stroke-width="2" stroke-dasharray="12 8" stroke="black" stroke-opacity=".8"/>

</svg>

A slight disadvantege against textPath is that the individual segments bend along the line which is visible if the path is too curved.

like image 20
Watous Avatar answered Nov 13 '22 02:11

Watous


Well you can use textPath to accomplish something like this. Firefox is the only big browser that supports the textLength and lengthAdjust attributes that you need to get the glyphs overlapping, but the result in other browsers is not terrible. If you can find the right webfont it might actually look good.

<svg width="590" height="560" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
  <defs>
  <path id="MyPath" d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="black" fill="transparent"/>
  </defs>
  
    <text font-family="Verdana" font-size="10" textLength="400" lengthAdjust="spacing">
    <textPath xlink:href="#MyPath">
      O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-O-
    </textPath>
  </text>
</svg>
like image 2
Michael Mullany Avatar answered Nov 13 '22 00:11

Michael Mullany