Arrange Text Freely with SVG textPath! Animations Along Lines, Arcs, and Curves Using JavaScript
By combining SVG and JavaScript, you can create animations that are difficult or impossible to achieve with CSS alone.
SVG allows you to place text along straight lines, arcs, and Bézier curves, so simply animating the path with JavaScript makes the text itself animate along the shape.
If you hide the path (stroke:none;), it appears as though only the text is moving.
<div>
<!-- Quadratic Bézier Curve (Q) Animation -->
<svg style="width:100%;max-width:800px;height:auto;" viewBox="0 0 120 60">
<path id="path_animationQ2" d="M10,40 Q60,0 110,40" style="fill:none;stroke:none;stroke-width:1px;" />
<text style="font-size:10px;letter-spacing:0.3em;stroke:#333333;fill:#333333;opacity:1.0;" dy="10" text-anchor="middle">
<textpath xlink:href="#path_animationQ2" startOffset="50%">SVG Animation</textpath>
</text>
</svg>
</div>
<script>
let xyq2=0,vq2=1;
window.addEventListener("load",function(){
setInterval(function(){
xyq2+=vq2;
console.log(xyq2);
if(xyq2>=50||xyq2<=-40){vq2=-vq2;}
let elm=document.getElementById("path_animationQ2");
elm.setAttribute("d","M10,40 Q60,"+xyq2+" 110,40");
},33);
});
</script>
Straight‑Line Animation
<div>
<!-- standard">Straight‑Line Animation -->
<svg style="width:100%;max-width:800px;" viewBox="0 0 240 60">
<path id="path_animationL" d="M10,50 l50,-10 m10,0 l50,-10 m10,0 l50,-10" style="fill:none;stroke:#f00;stroke-width:2px;" />
<text style="font-size:10px;letter-spacing:0.3em;stroke:#0ff;opacity:0.8;" dy="-4" text-anchor="middle">
<textpath xlink:href="#path_animationL" startOffset="50%">Animating text</textpath>
</text>
</svg>
</div>
<script>
var xyl=10,vl=-1;
window.addEventListener("load",function(){
setInterval(function(){
xyl+=vl;
if(xyl>20||xyl<0){vl=-vl;xyl+=vl;}
let elm=document.getElementById("path_animationL");
elm.setAttribute("d","M"+xyl+",50 l50,-10 m"+xyl+",0 l50,-10 m"+xyl+",0 l50,-10");
},33);
});
</script>
Arc Animation
<div>
<!-- Arc Animation >
<svg style="width:100%;max-width:400px;" viewBox="0 0 120 120">
<path id="path_animationA" d="M10,110 a100,100 45,0,1 100,-100" style="fill:none;stroke:#f00;stroke-width:2px;" />
<text style="font-size:10px;letter-spacing:0.3em;stroke:#0ff;" dy="10">
<textpath xlink:href="#path_animationA">Animating text</textpath>
</text>
</svg>
</div>
<script>
var xya=100,va=-4;
window.addEventListener("load",function(){
setInterval(function(){
xya+=va;
if(xya>160||xya<80){va=-va;xya+=va;}
let elm=document.getElementById("path_animationA");
elm.setAttribute("d","M10,110 a"+xya+","+xya+" "+(-Math.atan(100/-100)*180/Math.PI)+",0,1 100,-100");
},33);
});
</script>
Quadratic Bézier Curve Animation
<div>
<!-- Quadratic Bézier Curve Animation -->
<svg style="width:100%;max-width:400px;" viewBox="0 0 120 120">
<path id="path_animationQ" d="M10,60 q50,-80 100,0" style="fill:none;stroke:#f00;stroke-width:2px;" />
<text style="font-size:10px;letter-spacing:0.3em;stroke:#0ff;opacity:0.5;" dy="10" text-anchor="middle">
<textpath xlink:href="#path_animationQ" startOffset="50%">Animating text</textpath>
</text>
</svg>
</div>
<script>
var xyq=-80,vq=-4;
window.addEventListener("load",function(){
setInterval(function(){
xyq+=vq;
if(xyq>80||xyq<-80){vq=-vq;xyq+=vq;}
let elm=document.getElementById("path_animationQ");
elm.setAttribute("d","M10,60 q50,"+xyq+" 100,0");
},33);
});
</script>
