Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Staggering Angular2 animations within *ngFor

I've been digging around the Angular2 documentation and there doesn't seem to be a simple way to add delays to animations. For reference, here is what I'm aiming to achieve: plunkr using jQuery

I want to use Angular2's animation features though since these "bars" are being generated within a loop. They animate fine, but all at once. I want to stagger them by 1s increments. Here's my main component file:

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


export class Skill {
  skill: string;
  level: number;
}

const SKILLS: Skill[] = [
    { skill: 'x', level: 70 },
    { skill: 'y', level: 100 },
    { skill: 'z', level: 80 }
]

@Component({
  selector: 'app-wrap',
  template: `
    <div *ngFor="let skill of skills; let i = index" class="skill">
      <span class="bar" [style.width.%]="skill.level" [@expandSkill]>&nbsp;</span>
    </div>
  `,
  animations: [
    trigger('expandSkill', [
      state('in', style({ width: 'auto' })),
      transition('void => *', [
        style({ width: '0' }),
        animate('1000ms ease-in-out')
      ])
    ]
  ]
})

export class AppComponent {
  skills = SKILLS;
}

I came across this other SO question that seems similar, but it was asked several months ago, before the final release.

like image 390
itsclarke Avatar asked Sep 26 '16 12:09

itsclarke


1 Answers

After hammering my head against the animation DSL to make staggering animations a thing. I found an alternative way of doing animations which allows staggering!

The trick is to have a directive responsible of the animation using the Renderer and Service to hold your animation store!

Directive important code

this.animation = this.renderer.animate(
  this.element.nativeElement.firstElementChild || this.element.nativeElement,
  this.animService.getAnimation(animationName).startingStyles,
  this.animService.getAnimation(animationName).keyframes,
  this.duration,
  this.delay,
  this.easing
);
this.animation.pause();
this.animation.play();

How to use it in template

<div *ngFor="let str of ['foo','bar','baz']; let i = index"
  anim-aes
  [anim-aes-delay]="i*200"
  [anim-aes-duration]="500"
  [anim-aes-animation]="'fadeIn'"
  [anim-aes-animation-leave]="'fadeOut'"
  [anim-aes-play]="show">
  click {{str}}
</div>

I made a working plunkr with everything you need!

plunkr

like image 142
Aesdotjs Avatar answered Sep 28 '22 16:09

Aesdotjs