Pause Angular Animations

£可爱£侵袭症+ 提交于 2019-12-11 02:19:56

问题


Is it possible to pause animations in Angular 2+? I would like to pause an animation upon mousing over an element and resume the animation from where it left off when mousing out.

I have created a simple script to demonstrate: https://stackblitz.com/edit/scrolling-text

Here's my component:

import { Component, ElementRef, ViewChild } from '@angular/core';
import { trigger, state, style, animate, transition } from '@angular/animations';

@Component({
  selector: 'my-app',
  template: `
    <div class="container">
      <div class="scrolling-text" [@scroll]="state" (@scroll.done)="scrollDone()">Hover to pause!</div>
    </div>
  `,
  styles: [`
    .container {
      height: 30px;
      overflow: hidden;
      position: relative;
      width: 100%;
    }

    .scrolling-text {
      position: absolute;
      white-space: nowrap;
    }

    /* Below doesn't work to pause */

    .scrolling-text:hover, .container:hover {
      -moz-animation-play-state: paused;
      -webkit-animation-play-state: paused;
      animation-play-state: paused;
    }
  `],
  animations: [
    trigger('scroll', [
      state('on', style({left: '-100px'})),
      transition('* => *', [
        style({left: '-100px'}),
        animate(10000, style({left: '100%'}))
      ])
    ])
  ]
})
export class AppComponent  {
  state = 0;

  scrollDone() {
    this.state++;
  }

}

I tried animation-play-state: paused; without luck:

.scrolling-text:hover, .container:hover {
  -moz-animation-play-state: paused;
  -webkit-animation-play-state: paused;
  animation-play-state: paused;
}

Is there any way to get this to work?


回答1:


I found a way to do it with AnimationBuilder.

import { Component, ElementRef, ViewChild } from '@angular/core';
import { style, animate, AnimationBuilder, AnimationPlayer } from '@angular/animations';

@Component({
selector: 'my-app',
template: `
  <div class="container" (mouseover)="player.pause()" (mouseout)="player.play()">
    <div #el class="scrolling-text">Hover to pause!</div>
  </div>
`,
styles: [`
  .container {
    height: 30px;
    overflow: hidden;
    position: relative;
    width: 100%;
  }

  .scrolling-text {
    position: absolute;
    white-space: nowrap;
  }
`]
})
export class AppComponent  {

  @ViewChild('el') el: ElementRef;

  private factory = this.builder.build([
    style({left: '-100px'}),
    animate(10000, style({left: '100%'}))
  ]);
  private player;

  constructor(private builder: AnimationBuilder) { }

  ngOnInit() {
    this.player = this.factory.create(this.el.nativeElement, {});
    this.animate();
  }

  private animate() {
    this.player.reset();

    this.player.onDone(() => {
      this.animate();
    });

    this.player.play();
  }

}

Live Demo




回答2:


Not the best solution though. Since

this.player = this.factory.create(this.el.nativeElement, {}); 

creates another instance of WebAnimationsPlayer inside RendererAnimationPlayer

You can check it yourself by:

 console.log(this.player._renderer.engine.players.length);

Of course in your case it is not critical but still. This comes into play when you try to reuse animation in something like mousemove event. Then Angular can create up to 1000 players. And overflow the memory.

If you want to reuse animation more memory efficient you should reuse the existing player.

Or call

 if (this.player) {
      this.player.destroy();
 }

before

this.player = this.factory.create(this.el.nativeElement, {}); 


来源:https://stackoverflow.com/questions/48713488/pause-angular-animations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!