user2227359
user2227359

Reputation: 317

Creating an SVG animated dashed line with a transparent background

I have been playing around with this for hours and trying to think up a solution.

In this... https://jsfiddle.net/WebFlair/nc0zyjdq/78/

<div class="bg">

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
 preserveAspectRatio="xMidYMid meet">
<path class="path" fill="none" stroke="#b0225e" stroke-linejoin="round" stroke-width="5" stroke-miterlimit="10" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>

<path class="dashed" fill="none" stroke="white"  stroke-width="7" stroke-linejoin="round" stroke-miterlimit="16" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>
</svg>
</div>
<style>
.bg {background:#eee;}
.dashed{
  stroke-dasharray: 14;
}
.path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: dash 5s linear alternate forwards;
}

@keyframes dash {
  from {
    stroke-dashoffset: 1000;
  }
  to {
    stroke-dashoffset: 0;
  }
}
</style>

You will see a grey background and an animated white and pink dashed line.

Now I know this wont work in my example, but what I am trying to do is make the white part transparent so that it can be used on any background, keep the animation and the pink dashed line.

Can anyone think of a way to make that happen? I have gone over everything I can think of and always need the white part in order to keep the animation.

Upvotes: 3

Views: 395

Answers (2)

Alexandr_TT
Alexandr_TT

Reputation: 14585

but what I am trying to do is make the white part transparent so that it can be used on any background, keep the animation and the pink dashed line.

The idea is as follows: use three layers

  1. The first bottom layer will have a white path
  2. The middle layer will have exactly the same pink path
  3. There will be a masking path on the top layer, which will gradually reveal the pink path

This uses the property of the mask when "stroke: white" shows the section of the pink path that is under it

And since the length of the masking path changes from zero to the maximum value (stroke-dashoffset decreases from the maximum 917 to zero), the growth of the pink path becomes visible

@keyframes dash {
  from {
    stroke-dashoffset: 917;
  }
  to {
    stroke-dashoffset: 0;
  }

Clarification the maximum path length is 917px

1. The first bottom layer will have a white path

.bg {background:#eee;}
#dashed  {
  stroke-dasharray: 14;
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-linejoin:round; 
 
}
<div class="bg">

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
 preserveAspectRatio="xMidYMid meet">

   <!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>  
    
    
</svg>
</div>
<script>
  console.log(dashed.getTotalLength());
</script>

2. The middle layer will have exactly the same pink path

 <style>
.bg {background:#eee;}
#dashed  {
  stroke-dasharray: 14;
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-linejoin:round; 
 
} 

#pink {
stroke-dasharray: 14;
  fill:none;
  stroke:#b0225e;
  stroke-width:7;
  stroke-linejoin:round; 
  mask:url(#msk);
} 
<div class="bg">

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
 preserveAspectRatio="xMidYMid meet">


   <!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>  
      <!-- Middle layer dashed pink line -->
     <path id="pink" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>

</svg>
</div>

3. There will be a masking path on the top layer, which will gradually reveal the pink path

.bg {background:#eee;}
#dashed  {
  stroke-dasharray: 14;
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-linejoin:round; 
 
} 

#pink {
stroke-dasharray: 14;
  fill:none;
  stroke:#b0225e;
  stroke-width:7;
  stroke-linejoin:round; 
  mask:url(#msk);
} 

#maskLine {
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-dasharray: 917;
  stroke-dashoffset: 917;
  animation: dash 5s linear alternate forwards;
}

@keyframes dash {
  from {
    stroke-dashoffset: 917;
  }
  to {
    stroke-dashoffset: 0;
  }
}
<div class="bg">

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
 preserveAspectRatio="xMidYMid meet">
<defs>
  <mask id="msk">  
       <!-- A mask layer that reveals a dashed pink line -->
    <path id="maskLine"  d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>  
  </mask>
</defs>

   <!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>  
      <!-- Middle layer dashed pink line -->
     <path id="pink" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>
    
</svg>
</div>

UPDATE

Filling, clearing the path on repeated clicks on the button "Play"

var dash = true;

function play() {
  var path = document.getElementById('maskLine');
  path.style.strokeDashoffset = (dash) ? '0' : '917.00';
  dash = !dash;
} 
.bg {background:#eee;}
#dashed  {
  stroke-dasharray: 14;
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-linejoin:round; 
 
} 

#pink {
stroke-dasharray: 14;
  fill:none;
  stroke:#b0225e;
  stroke-width:7;
  stroke-linejoin:round; 
  mask:url(#msk);
} 

#maskLine {
  fill:none;
  stroke:white;
  stroke-width:7;
  stroke-dasharray: 917;
  stroke-dashoffset: 917;
  transition: stroke-dashoffset 5s linear;
}
<button onclick="play();">Play</button>
<div class="bg">

<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
 width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
 preserveAspectRatio="xMidYMid meet">
<defs>
  <mask id="msk">  
       <!-- A mask layer that reveals a dashed pink line -->
    <path id="maskLine"  d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591">
     </path>
        
     </path>    
  </mask>
</defs>

   <!-- Bottom layer dashed white line -->
<path id="dashed" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>  
      <!-- Middle layer dashed pink line -->
     <path id="pink" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>

</svg>
</div>

Upvotes: 3

Robby Cornelissen
Robby Cornelissen

Reputation: 97381

You can do it using a mask:

.bg {
  background: #eee;
}

.dashed {
  stroke-dasharray: 14;
}

.path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: dash 5s linear alternate forwards;
}

@keyframes dash {
  from {
    stroke-dashoffset: 1000;
  }
  to {
    stroke-dashoffset: 0;
  }
}
<div class="bg">
  <svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000" preserveAspectRatio="xMidYMid meet">
  <defs>
    <path id="dashed" class="dashed" fill="none" stroke="white" stroke-width="7" stroke-linejoin="round" stroke-dasharray="14" stroke-miterlimit="16" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>
    <mask id="mask">
      <use xlink:href="#dashed"/>
    </mask>
  </defs>
  <path class="path" fill="none" stroke="#b0225e" stroke-linejoin="round" stroke-width="5" stroke-miterlimit="10" mask="url(#mask)" d="M23.742,10.709
    c-2.305,23.611-8.81,46.563-9.021,70.829c-0.252,28.966,22.237,43.666,47.06,55.482c23.642,11.255,42.368,15.766,68.461,16.631
    c19.993,0.663,40.08,2.97,59.853-1.723c23.301-5.531,45.542-17.598,66.978-27.933c19.248-9.281,38.831-21.86,41.946-45.201
    c5.539-41.51-54.993-47.073-81.885-42.17C159.05,47.212,89.37,104.633,77.387,164.629c-5.896,29.522-4.312,60.884,12.703,86.354
    c19.17,28.697,49.512,49.927,78.596,67.591"/>
  </svg>
</div>

You can also eliminate the duplicate path declaration by reusing the path defined in defs, but this would require additional changes, so, in order to not obfuscate things, I decided to not put that in my answer.

Upvotes: 2

Related Questions