1

I have this SVG arrow that is consist of a path and a polygon. I want to animate the path and the polygon along the path.

<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 242.66 397" width="242.66" height="397">
<style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:bevel;stroke-width:4px;}</style>
  <path class="cls-1" d="M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85"/>
  <polygon points="0 384.74 2.04 381.29 19 391.37 27.81 373.72 31.39 375.51 20.65 397 0 384.74"/>
</svg>

I have tried this css, and it animates the path.

path {
  stroke: #000000;
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: dash 4s linear forwards;
}

@keyframes dash {
  to {
    stroke-dashoffset: 0;
  }
}
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 242.66 397" width="242.66" height="397">
<style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:bevel;stroke-width:4px;}</style>
  <path class="cls-1" d="M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85"/>
  <polygon points="0 384.74 2.04 381.29 19 391.37 27.81 373.72 31.39 375.51 20.65 397 0 384.74"/>
</svg>

However, I can not figure how to move the polygon along the path with the same pace. I have used this code that does not work.

polygon {
  offset-distance: 0%;
  offset-path: path('M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85');
  animation: move 2.1s linear forwards infinite;
}

@keyframes move {
  100% {
    offset-distance: 100%;
  }
}

How to animate the polygon along the same path?

mahan
  • 12,366
  • 5
  • 48
  • 83
  • Does this answer your question? [Add arrow to SVG stroke animation](https://stackoverflow.com/questions/54993441/add-arrow-to-svg-stroke-animation) – r3mainer Jun 08 '22 at 09:43

1 Answers1

2

The arrow will get rotated and positioned according to the offset-path.

css offset-path or svg SMIL <mpath> expect your animated element to point at the x/y origin of your svg like so:

Arrow

Your arrow element is already placed on the path – the browser will add the current x/y values to the coordinates on your motion path.
In this case: your arrow disappears due to huge offsets. (see left example.)

.wrp {
  padding: 1em;
  //border: 1px solid #ccc;
  display: inline-block;
}

svg {
  display: inline-block;
  width: 10em;
  overflow: visible;
  border: 1px solid #ccc;
}

.motionPath {
  stroke: #000;
  stroke-dasharray: 0 100;
  animation: dash 2s linear forwards infinite;
}

.arrow {
  offset-distance: 0%;
  offset-path: path('M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85');
  animation: move 2s linear forwards infinite;
}

polygon {
  offset-distance: 0%;
  offset-path: path('M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85');
  animation: move 2s linear forwards infinite;
}

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

@keyframes move {
  100% {
    offset-distance: 100%;
  }
}
<div class="wrp">
  <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 242.66 397">
  <style>
    .cls-1 {
      fill: none;
      stroke: #000;
      stroke-linecap: round;
      stroke-linejoin: bevel;
      stroke-width: 4px;
    }
  </style>
  <path class="cls-1 motionPath" d="M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85" pathLength="100" />
  <path class="arrow" stroke="red" fill="none" stroke-width="4" d="M-12.5 -12.5 l 12.5 12.5 l-12.5 12.5"></path>
</svg>

</div>


<div class="wrp">
  <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 242.66 397">
<style>.cls-1{fill:none;stroke:#000;stroke-linecap:round;stroke-linejoin:bevel;stroke-width:4px;}</style>
  <path class="cls-1 motionPath" d="M240.66,2C11.72,114.98-26.67,239.75,19.39,392.85" pathLength="100"/>
  <polygon fill="red" style="transform:translate(-25px, -300px)" points="0 384.74 2.04 381.29 19 391.37 27.81 373.72 31.39 375.51 20.65 397 0 384.74"/>
</svg>
</div>

I have replaced your arrow with another <path> element but you can reposition your original arrow polygon in an editor like inkscape to get the right coordinates and rotation.

You will also need to set a pathLength or calculate the exact pathLength with js like path.getTotalLength()

Otherwise you can't synchronize your stroke animation with the arrow movement.

herrstrietzel
  • 11,541
  • 2
  • 12
  • 34