JSFiddle - React, Tailwind, and code Playground

by talkhabi

HTML

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 500" height="300">
  <path id="path" d="M480,200C580,200,480,450,580,400S580,150,680,100S1030,200,780,300S430,400,180,300S180,50,280,100S280,350,380,400S380,200,480,200" />
  <path id="arrow" d="M-10 -10 L10 0L-10 10z" />
</svg>

CSS

path {
  fill: none;
  stroke: #ccc;
  stroke-width: 2px;
  stroke-dasharray: 20 7;
}

#arrow {
  fill: red;
  stroke-width: 0;
}

JavaScript

var path = document.getElementById("path")
var arrow = document.getElementById("arrow")
var l = 0
var tl = path.getTotalLength()

function getPoint(path, length) {
  var p1 = path.getPointAtLength(length)
  var p2 = path.getPointAtLength(length + 3)
  var deg = Math.atan2(p1.y - p2.y, p1.x - p2.x) * (180 / Math.PI);
  return {
    x: p1.x,
    y: p1.y,
    angle: deg
  }
}

function updatePosition() {
  l += 2
  if (l > tl) l = 0;
  var p = getPoint(path, l)
  arrow.setAttribute("transform", "translate(" + p.x + "," + p.y + ") rotate(" + (p.angle + 180) + ")")
  requestAnimationFrame(updatePosition)
}

updatePosition()