infodev
infodev

Reputation: 5235

Draw arrow on svg path without using textPath

I would position arrows on a different areas of a path. Actually I'm using textPath.

The problem of textPath is that it is linked with the path and I can't place elements between them ( for example a circle above path but under arrow ). Also I'm limited to text characters to draw the arrow.

Is it a way to do the same thing without textPath I would use an arrow that I draw myself and place it on the line by respecting its direction?.

<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/textPath -->

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

  <!-- to hide the path, it is usually wrapped in a <defs> element -->
  <!-- <defs> -->
<circle cx="75" cy="45" r="5" fill="blue"/>
  <path id="MyPath" fill="none" stroke="red"
        d="M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40 Q10,70 45,70 Q70,70 75,50"  />
  <!-- </defs> -->

  <text dominant-baseline ='central'>
    <textPath href="#MyPath" startOffset='100%' text-anchor='middle'>⯈</textPath>
  </text>

</svg>

Upvotes: 2

Views: 1491

Answers (2)

Alexandr_TT
Alexandr_TT

Reputation: 14585

The textPath method allows you to use a path for text characters
Can use unicode triangle symbol: &#9205;

  • An example of an animation of the movement of one triangle along a path

<svg width="50%" height="50%" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
  
 <circle cx="75" cy="45" r="5" fill="blue"/>
  <path id="MyPath" fill="none" stroke="red"
        d="M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40 Q10,70 45,70 Q70,70 75,50"  />

<text font-size="20"  font-family="Times New Roman" fill="black" >
    <textPath xlink:href="#MyPath" startOffset='0%' >
	<tspan dx="0" dy="6">  &#9205; </tspan>
		<animate
		  dur="10s"repeatCount="1"
		  attributeName="startOffset"
		  values="0%;95.6%"
		  fill="freeze"/> 
	
	</textPath>
  </text>			
			
</svg>

  • An example of animating the movement of several triangles

<svg width="50%" height="50%" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">

 <circle cx="75" cy="45" r="5" fill="blue"/>
  <path id="MyPath" fill="none" stroke="red"
        d="M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40 Q10,70 45,70 Q70,70 75,50"  />

<text font-size="20"  font-family="Times New Roman" fill="black" >
 <textPath xlink:href="#MyPath" startOffset='0%' >
	<tspan dx="0" dy="6">  &#9205; </tspan>
	<tspan dx="-19" fill="red">  &#9205;  </tspan>
	<tspan dx="-19" fill="gold" >  &#9205; </tspan>
	<tspan dx="-19" fill="green" >  &#9205; </tspan>
	<animate  dur="10s" repeatCount="1" attributeName="startOffset" values="0%;89%" fill="freeze"/> 
	
</textPath>
  </text>			
			
</svg>

  • An example of using other Unicode characters

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

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

<text font-size="32"  font-family="Times New Roman" fill="black" >
<textPath id="result"    xlink:href="#pathTrain">
<tspan dx="0" > &#128645; </tspan>
 <tspan dx="-15">  &#128643; </tspan>
  <tspan dx="-15"> &#128643;</tspan>
  <tspan dx="-15"> &#128643;</tspan>
  <tspan dx="-15">&#128643;</tspan>
  <tspan dx="-15" > &#128645; </tspan>
<animate  dur="7s" repeatCount="indefinite" attributeName="startOffset" values="55%;0%;55%"/> 
</textPath>
</text>				
			
</svg>   

Upvotes: 2

Stranger in the Q
Stranger in the Q

Reputation: 3898

Here is js solution:

let len = MyPath.getTotalLength()
requestAnimationFrame(draw);

function draw(t){
  requestAnimationFrame(draw);
  let p1 = MyPath.getPointAtLength((t/33)%len);
  let p2 = MyPath.getPointAtLength((t/33)%len + 10);
  let a = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI
  triangle.setAttribute('transform', `translate(${p1.x},${p1.y})rotate(${a})`)
}
<body style="overflow:hidden;margin:0">
<svg viewBox="0 0 100 100" width=100vw height=100vh>
  <path id="MyPath" fill="none" stroke="red"
        d="M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40 Q10,70 45,70 Q70,70 75,50"  />
  <circle cx="75" cy="45" r="5" fill="blue"/>
  <path id=triangle d="m0,0 v-5l10,5l-10,5z"/>
</svg>
</body>

Upvotes: 5

Related Questions