thekingsrook
thekingsrook

Reputation: 193

Change direction of SVG animation

I saw this SVG animation and I'm wondering how to alter the direction that the line is erased in; currently the line retracts from the last point it is drawn, however I want the reverse; for the line to erase itself from the point where it first started to draw (so that it looks more like a loading animation).

I see that the animation property on .path has a value of infinite, but I'm not sure how the direction is specified.

The HTML is

<div class="bg">  
<svg xmlns="http://www.w3.org/2000/svg" width="670" height="236" viewBox="0 0 670 236">

  <path class="path" stroke="#4CADC1" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="300" stroke-dashoffset="300" fill="none" d="M343.6 75.9v20.3l23.1 21.8-23.1 21.8v20.3l44.6-42.1zM326.4 139.8l-23.1-21.8 23.1-21.8v-20.3l-44.6 42.1 44.6 42.1z"/>

  <path class="path" stroke="#4CADC1" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="500" stroke-dashoffset="500" fill="none" d="M335 38.9c-43.7 0-79.1 35.4-79.1 79.1s35.4 79.1 79.1 79.1 79.1-35.4 79.1-79.1-35.4-79.1-79.1-79.1zM335 182.9c-35.8 0-64.9-29.1-64.9-64.9s29.1-64.9 64.9-64.9 64.9 29.1 64.9 64.9-29.1 64.9-64.9 64.9z"/>

  </svg>
</div>

And the CSS is

body {
  background-color: #fff;
}

.bg  {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.path {
  animation: draw 3.5s infinite;
}

 @keyframes draw {
  50% {
    stroke-dashoffset: 0;
  }
}

Upvotes: 9

Views: 11289

Answers (4)

Cybernetic
Cybernetic

Reputation: 13334

Changing SVG Line Animation Direction

Add KeyFrames and Classes for Both Directions:

.dash {
    stroke-dasharray : 10 5;
    animation : dash 4s linear infinite;
}

.dash_reverse {
    stroke-dasharray : 10 5;
    animation : dash_reverse 4s linear infinite;
}

@keyframes dash {
    to {
      stroke-dashoffset: 100;
    }
}

@keyframes dash_reverse {
    to {
      stroke-dashoffset: -100;
    }
}

Use JavaScript to Toggle Animation:

function animate_line_forward(id) {
    $("#" + id).removeClass("dash_reverse");
    $("#" + id).addClass("dash");
}

function animate_line_reverse(id) {
    $("#" + id).removeClass("dash");
    $("#" + id).addClass("dash_reverse");
}

Call functions as needed (pass the SVG line id into the above functions:

Calling animate_line_forward:

enter image description here

Calling animate_line_reverse:

enter image description here

Upvotes: 1

jarodtaylor
jarodtaylor

Reputation: 571

I used the negative value for stroke-dashoffset that Persijn recommended. This worked great in Chrome and FF, but it didn't work properly in Safari.

I've found that if you open the SVG in Illustrator, you can reverse the direction of the path, by opening the Attributes panel (you might have to click the "show more" in the top right) and literally clicking the "reverse path" button.

Upvotes: 3

Persijn
Persijn

Reputation: 14990

I like your idea of making this an loading animation:

CODEPEN

Now what i did:

changed the animation start stop point

@keyframes draw {
  100% {
    stroke-dashoffset: -500;
  }
}

Why -500?
Because this is the value of the dash-array.
This is defined in the <svg>: dasharray="500"

Changed this value in the inner most path. It was only 300

I added a linear animation

animation: draw 5s infinite linear;

The default is ease. I found the animation has better consistency with a linear animation.

NOTE

dashoffset=500 <- makes the animation start without the dash/stroke

Upvotes: 7

airnan
airnan

Reputation: 635

stroke-dasharray can be a list of white space separated dashes and gaps, so you could do something like this:

var svgPath = document.getElementById('svgPath');
var pathLength = svgPath.getTotalLength();
var offset = 0;

function offsetPath() {
  requestAnimationFrame(offsetPath);
  offset += 0.1;
  var dasharray = 0 + ' ' + offset + ' ' + (pathLength - offset);
  svgPath.setAttribute('stroke-dasharray', dasharray);
}
requestAnimationFrame(offsetPath);
<svg xmlns="http://www.w3.org/2000/svg" width="670" height="236" viewBox="0 0 670 236">

  <path id="svgPath" class="path" stroke="#4CADC1" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="100 100 100" fill="none" d="M343.6 75.9v20.3l23.1 21.8-23.1 21.8v20.3l44.6-42.1zM326.4 139.8l-23.1-21.8 23.1-21.8v-20.3l-44.6 42.1 44.6 42.1z"
  />

</svg>

Upvotes: 2

Related Questions