A reusable cascade animation with Angular Animation

Renan Ferro - Aug 23 '22 - - Dev Community

Hi guys, how is everything??

Have you ever thought about how to make the user experience better when we have a list of cards!?

Today, I gonna show how we can do it with a card "cascade" animation and have a nice card page using the power of Angular Animations!

So, first let's talk a little bit about Angular Animations!

Angular Animations

The Angular animations is build on CSS functionality, so we can animate whatever properties the browser accepts and we can do a reusable animations and use it in whatever our components!

Let's Do It!

  • First

We need to make resources available for our app, so we need import the BrowserAnimationsModule in our Angular root application module!


 typescript
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({ 
   imports: [
     BrowserAnimationsModule 
   ]
   ...
})


Enter fullscreen mode Exit fullscreen mode
  • Second

We are going to make a reusable animation, so inside of our app folder let's create an animations folder and inside it we are going to create an animations.ts file! And we have a result like in the image below:

Image description

Now, let's make our animation!

Inside of the animations.ts we will import the functions like bellow:



import {
  animate, keyframes, query, stagger,
  state,
  style,
  transition,
  trigger,
} from '@angular/animations';


Enter fullscreen mode Exit fullscreen mode

Let's start creating a const and add the trigger function:



...

export const animatedListCards = 
   trigger('listCardAnimation', [
      ...     
   ]);


Enter fullscreen mode Exit fullscreen mode
  • Trigger: The trigger is responsible to get the state, the transitions and give a name for the our animation!

Now, we need to configure the transition, we will to use the * => * to get any state.



...

export const animatedListCards = 
   trigger('listCardAnimation', [
      transition('* => *'. [
         ...
      ])   
   ]);


Enter fullscreen mode Exit fullscreen mode
  • Transition: We need to define an animation transition because we need to specify when the animation will be applied!

After that we need to configure the rest of our animation!



...

export const animatedListCards = 
   trigger('listCardAnimation', [
      transition('* => *'. [
        query(':enter', style({
          opacity: 0,
        }), {optional: true}),
        query(':enter', stagger('300ms', [
          animate('.8s ease-in', keyframes([
            style({opacity: 0, transform: 'translateY(-30px)', offset: 0}),
            style({opacity: .5, transform: 'translateY(20px)', offset: 0.3}),
            style({opacity: 1, transform: 'translateY(0)', offset: 1}),
          ]))
        ]),{optional: true})
      ])   
   ]);


Enter fullscreen mode Exit fullscreen mode

What did we do above!?

In the query(:enter) we specify the "enter" state of our component and and apply the style to hide the cards.

After that, we select query(':enter') again to apply the other styles, with the stagger function we specify the time for the animation to start. And in animation('.8s ease-in') we specify the transition style of the animation! Inside of the keyframes() we specify the css properties to make our animation!

Now we have our animation organized and we can use it in our components!

Now we need to set the animation in the animations property inside the @Component() decorator. As below:



import { animatedListCards } from './animations/animations';

@Component({ 
 ...
 animations: [
   animatedListCards // the animation trigger
 ]
})


Enter fullscreen mode Exit fullscreen mode

And after that, we trigger the animation with the length of our data, for example an array of courses:



<div [@listAnimation]="courses.length">
  <ng-container *ngFor="let course of courses">
    <div class="card">
      <h1>
        {{ this.course.name }}
      </h1>
    </div>
  </ng-container>
</div>


Enter fullscreen mode Exit fullscreen mode

And finally we have the our animation making the page and user experience more pleasant!

Here, we have an example application available as a live example:

Thanks for reading!!!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .