Animate dashed SVG line
I would like to animate a dashed line in a SVG-file. The line should »grow« from 0 length to full length. All the methods I found are not suitable for me.
Does anyone have an idea, how to solve this?
That's the path in my svg file:
<path class="path" fill="none" stroke="#FFFFFF" stroke-miterlimit="10" d="M234.3,119
c-31-0.7-95,9-128.7,50.8"/>
To animate the line as straight line i did:
.path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear forwards;
}
@keyframes dash {
to {
stroke-dashoffset: 0;
}
}
Of course, this is not working, when I want the line to be dashed. Is there anybody who has an idea how to solve this?
That's my codepen: http://codepen.io/anon/pen/WpZNJY
PS: I can't use two paths over each other to hide the path underneath because I'm having a coloured background.
Solution 1:
You can also do this just using masks as so:
.paths {
fill: none;
stroke: black;
stroke-dasharray: 5;
}
.mask {
fill: none;
stroke: white;
stroke-width: 10;
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear forwards;
}
@keyframes dash {
to {
stroke-dashoffset: 0;
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 830 500" >
<defs>
<path id="first" d="M234.3,119c-31-0.7-95,9-128.7,50.8"/>
<path id="vienna" d="M382.8,243.8c2.9-36.1,15.8-110.3,110.1-145.4"/>
<path id="budapest" d="M550.6,319.4c34-2.7,109-2.1,174.8,50.5"/>
<path id="salzburg" d="M265,323c21.5,12.1,57.2,39.5,60.7,85.1"/>
<path id="tyrol" d="M147.8,319.5c-27.1,7-79.7,31.3-92.8,74.2"/>
<mask id="first-mask"><use class="mask" xlink:href="#first" /></mask>
<mask id="vienna-mask"><use class="mask" xlink:href="#vienna" /></mask>
<mask id="budapest-mask"><use class="mask" xlink:href="#budapest" /></mask>
<mask id="salzburg-mask"><use class="mask" xlink:href="#salzburg" /></mask>
<mask id="tyrol-mask"><use class="mask" xlink:href="#tyrol" /></mask>
</defs>
<g class="paths">
<use xlink:href="#first" mask="url(#first-mask)" />
<use xlink:href="#vienna" mask="url(#vienna-mask)" />
<use xlink:href="#budapest" mask="url(#budapest-mask)" />
<use xlink:href="#salzburg" mask="url(#salzburg-mask)" />
<use xlink:href="#tyrol" mask="url(#tyrol-mask)" />
</g>
</svg>
This is also available as:
- codepen of single dotted path
- codepen of these plane tracks
Enjoy!
But note ... make sure you test your code cross-browser and fall back to animate tags or javascript if you have issues.
Solution 2:
One of the ways to do this is with Javascript. It duplicates a path by creating a polyline. Try the example below:
<!DOCTYPE HTML>
<html>
<head>
<style>
polyline{
stroke-dasharray:8;
stroke:black;
fill:none;
stroke-width:1;
}
</style>
</head>
<body >
This builds a smooth/dashed polylines that replicates your paths.<br>
<button onClick=animateDashPaths()>Animate Paths</button><br>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 830 500" enable-background="new 0 0 830 500" xml:space="preserve">
<path class="path" fill="none" stroke="#000000" stroke-miterlimit="10" d="M234.3,119
c-31-0.7-95,9-128.7,50.8"/>
<!-- Vienna Dash -->
<path id="pathVienna" display="none" stroke-miterlimit="10" d="M382.8,243.8
c2.9-36.1,15.8-110.3,110.1-145.4"/>
<!-- Budapest Dash -->
<path id="pathBudapest" display="none" stroke-miterlimit="10" d="M550.6,319.4
c34-2.7,109-2.1,174.8,50.5"/>
<!-- Salzburg Dash -->
<path id="pathSalzburg" display="none" stroke-miterlimit="10" d="M265,323
c21.5,12.1,57.2,39.5,60.7,85.1"/>
<!-- Tyrol Dash -->
<path id="pathTyrol" display="none" stroke-miterlimit="10" d="M147.8,319.5
c-27.1,7-79.7,31.3-92.8,74.2"/>
</svg>
<script>
//---button---
function animateDashPaths()
{
var NS="http://www.w3.org/2000/svg"
//----Vienna----------------
var endLengthVienna=pathVienna.getTotalLength()
var lengthDeltaVienna=endLengthVienna/200
var polylineVienna=document.createElementNS(NS,"polyline")
Layer_1.appendChild(polylineVienna)
var pntListVienna=polylineVienna.points
var iTVienna=setInterval(drawPathVienna,5)
var cntVienna=0
function drawPathVienna()
{
var len=lengthDeltaVienna*cntVienna++
if(len<endLengthVienna)
{
var pnt=pathVienna.getPointAtLength(len)
pntListVienna.appendItem(pnt)
}
else
clearInterval(iTVienna)
}
//----Budapest----------------
var endLengthBudapest=pathBudapest.getTotalLength()
var lengthDeltaBudapest=endLengthBudapest/200
var polylineBudapest=document.createElementNS(NS,"polyline")
Layer_1.appendChild(polylineBudapest)
var pntListBudapest=polylineBudapest.points
var iTBudapest=setInterval(drawPathBudapest,5)
var cntBudapest=0
function drawPathBudapest()
{
var len=lengthDeltaBudapest*cntBudapest++
if(len<endLengthBudapest)
{
var pnt=pathBudapest.getPointAtLength(len)
pntListBudapest.appendItem(pnt)
}
else
clearInterval(iTBudapest)
}
//----Salzburg----------------
var endLengthSalzburg=pathSalzburg.getTotalLength()
var lengthDeltaSalzburg=endLengthSalzburg/200
var polylineSalzburg=document.createElementNS(NS,"polyline")
Layer_1.appendChild(polylineSalzburg)
var pntListSalzburg=polylineSalzburg.points
var iTSalzburg=setInterval(drawPathSalzburg,5)
var cntSalzburg=0
function drawPathSalzburg()
{
var len=lengthDeltaSalzburg*cntSalzburg++
if(len<endLengthSalzburg)
{
var pnt=pathSalzburg.getPointAtLength(len)
pntListSalzburg.appendItem(pnt)
}
else
clearInterval(iTSalzburg)
}
//----Tyrol----------------
var endLengthTyrol=pathTyrol.getTotalLength()
var lengthDeltaTyrol=endLengthTyrol/200
var polylineTyrol=document.createElementNS(NS,"polyline")
Layer_1.appendChild(polylineTyrol)
var pntListTyrol=polylineTyrol.points
var iTTyrol=setInterval(drawPathTyrol,5)
var cntTyrol=0
function drawPathTyrol()
{
var len=lengthDeltaTyrol*cntTyrol++
if(len<endLengthTyrol)
{
var pnt=pathTyrol.getPointAtLength(len)
pntListTyrol.appendItem(pnt)
}
else
clearInterval(iTTyrol)
}
}
</script>
</body>
</html>