javascripttypescriptsvgpolylinesvg-animate

Continous svg animation of a polyline


I have the following code (in TypeScript) that creates a polyline (based on 4 differents points x1y1, xCy1, xCy1, x2y2, where Xc is the half distance between x1 and x2 on a plane), so it is not a circular shape.

private createPolyline(points: Array<[number, number]>): SVGPolylineElement {
    let polyline: SVGPolylineElement = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');
    let pointsAttr: string = points.map(point => point.join(',')).join(' ');

    polyline.setAttribute('points', pointsAttr);
    polyline.setAttribute('stroke', 'green');
    polyline.setAttribute('stroke-width', '2');
    polyline.setAttribute('fill', 'none');

    polyline.setAttribute('stroke-dasharray', '25');
    polyline.setAttribute('stroke-dashoffset', '40');
    polyline.style.animation = 'dash 5s linear infinite';

    return polyline;
}

What I want is basically to have the appearance of a continously flowing dashed line. The above method achieves that, but after 5 seconds it will reset to the original position of the dashes and restarts the animation.

Is there a way I can make this infinitely continous?


Solution

  • There are 2 options.

    1. Select high enough animation delay and stroke-dashoffset. For example, 3000 seconds and 24000. Simple. Example below.

    2. Use requestAnimationFrame yourself, ever increasing the stroke-dashoffset. See Creating a infinite forward SVG animation with CSS and JavaScript for that.

    function createPolyline(points) {
      let polyline = document.createElementNS('http://www.w3.org/2000/svg', 'polyline');
      let pointsAttr = points.map(point => point.join(',')).join(' ');
    
      polyline.setAttribute('points', pointsAttr);
      polyline.setAttribute('stroke', 'lightgreen');
      polyline.setAttribute('stroke-width', '2');
      polyline.setAttribute('fill', 'none');
    
      polyline.setAttribute('stroke-dasharray', '25');
      polyline.setAttribute('stroke-dashoffset', '24000');
      polyline.style.animation = 'dash 3000s linear infinite';
    
      return polyline;
    }
    
    var poly = createPolyline([
      [50, 0],
      [21, 90],
      [98, 35],
      [2, 35],
      [79, 90],
      [50, 0]
    ])
    document.querySelector("#mySomething").append(poly)
    body {
      background: black;
    }
    
    @keyframes dash {
      to {
        stroke-dashoffset: 0;
      }
    }
    <svg id="mySomething" viewBox="-10 -10 240 240" xmlns="http://www.w3.org/2000/svg">