Search code examples
angularsvgangular-animationssvg-animate

How to do stop/pause/resume SVG animations with Angular 9?


The spec of SVGSVGElement contains methods like pauseAnimations() or unpauseAnimations(). But how can I get access these methods in Angular 9? Or how can I pause/resume a SVG path animations?

<svg id="rootSVG" width="500" viewBox="50 0 700 400" xmlns="http://www.w3.org/2000/svg">
    <svg:circle r="10" fill="white" id="white">
        <svg:animateMotion
            id="innerTrack" 
            [attr.dur]="durationInner" 
            begin="indefinite" 
            repeatCount="0" 
            calcMode="linear"
            [attr.path]="innerPath"
            (begin)="status()"
        />
    </svg:circle>
</svg>

In pure JS I would do domething like:

var pause = document.getElementById('innerTrack');
    pause.pauseAnimations(); 

But when I do it with Angular 9 I get a compilation error:

error TS2551: Property 'pauseAnimations' does not exist on type 'HTMLElement'. Did you mean 'getAnimations'?

So the question is: how to do?


Solution

  • So here you need to access the methods on your #rootSVG: SVGSVGElement.

    To do so in Angular you can leverage ViewChild and access nativeElement and its methods:

    <svg #rootSVG viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
      <svg:path fill="none" stroke="lightgrey"
        d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
    
      <svg:circle r="5" fill="red">
        <svg:animateMotion dur="3s" repeatCount="indefinite"
          path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
      </svg:circle>
    </svg>
    

    now in your ts file you need to get the ViewChild inside ngAfterViewInit hook, and after that you can start calling the methods in question:

    import { Component, ViewChild } from '@angular/core';
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
    
      @ViewChild('rootSVG') rootSVG;
    
      name = 'Angular';
    
      ngAfterViewInit() {
    
        setInterval(()=>{
          this.rootSVG.nativeElement.pauseAnimations();
        }, 500)
    
        setInterval(()=>{
          this.rootSVG.nativeElement.unpauseAnimations();
        }, 1500)
      }
    }
    

    Here is working demo: https://stackblitz.com/edit/angular-yngun9