5 Angular Animations Examples - Learn BrowserAnimationsModule in Angular
5 Angular Animations Examples - Learn BrowserAnimationsModule in Angular

In this post you will learn everything that you need to know about Angular animations.

Don't do it

And before we start I must mention something super important. If you do animations but you don't do anything with Javascript, you don't work with Javascript properties, then please never ever use Angular animations. It doesn't make any sense. CSS is much faster than Javascript.

If you can implement your feature with just CSS animations - go for it.

You must use Angular animations only when you are dependent on some properties inside Angular component.

Prepared project

Here I already generated a basic Angular component. We just have a button which we can toggle to show the text.

Initial project

This is just a button with click event

<button (click)="fadeInOut()">Fade in / out</button>

<div *ngIf="isShown">This is a block with fade in / out</div>
export class AppComponent {
  isShown = false;

  fadeInOut(): void {
    this.isShown = !this.isShown;
  }
}

Basic animations

And the first step to start using Angular animations is to inject a module inside app.module.ts

@NgModule({
  ...
  imports: [
    ...
    BrowserAnimationsModule,
  ],
})
export class AppModule {}

And if you are curious what package is it there is a @angular/animations package installed already inside package.json.

Now let's add fade in and fade out effect on our text.

const fadeIn = trigger('fadeIn', [enterTransition]);

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  animations: [fadeIn],
})

We define our animations inside component decorator and it is an array of triggers. This is why on the top we created trigger fadeIn which has a name and a list of transitions. Now we must create our enterTransition.

const enterTransition = transition(':enter', [
  style({
    opacity: 0,
  }),
  animate('1s ease-in', style({ opacity: 1 })),
]);

Inside transition we define when it will happen and :enter is a predefined state. In the second parameter we provide a list of animations like a list of steps. We said that by default our element has opacity: 0 and we start our ease-in animation which will bring the element to opacity: 1.

Now we must apply this animation on our html element

<div @fadeInOut *ngIf="isShown">This is a block with fade in / out</div>

So we use @faceInOut to apply our animation.

As you can see in browser our text appears with smooth animation.

Actually a lot of people don't split code to variables but just write everything inside animations property. You can do that but it is more difficult to understand it especially for beginners.

Now we need to do exactly the same but it will be exit transition when we go from 100% opacity to 0%.

const exitTransition = transition(':leave', [
  style({
    opacity: 1,
  }),
  animate('1s ease-out', style({ opacity: 0 })),
]);
const fadeOut = trigger('fadeOut', [exitTransition]);

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  animations: [fadeIn, fadeOut],
})

Here we define the change from opacity 1 to opacity 0 with ease-out animation.

As you can see in browser it is working correctly.

States in animations

This was the basics of Angular animations but now I want to show you how you can apply states inside it. I want to implement the same fade in fade out with a single animation by using states.

const fadeInOut = trigger('fadeInOut', [
  state(
    'open',
    style({
      opacity: 1,
    })
  ),
  state(
    'close',
    style({
      opacity: 0,
    })
  ),
  transition('open => close', [animate('1s ease-out')]),
  transition('close => open', [animate('1s ease-in')]),
]);

Here in our new trigger we defined not only transitions but first of all states.

States are predefined styles which we can reuse later.

Here we defined open and close state which do nothing on their own. But after we defined 2 transitions.

And we have this strange notation open => close. It means that when we change state from open to close we want to apply ease-out transition. close => open means then when we change from close state to open state we want to apply ease-in transition.

States allow us more easily to declare our animations.

<div
  [@fadeInOut]="isShown ? 'open' : 'close'"
>
  This is a block with fade in / out
</div>

As you can see I also changed usage of our animation. I provided inside a state. It is either open or close depending on isShown property.

As you can see in browser it works in exactly the same way.

Wild cards

Any useful feature inside Angular animations is wild cards. Instead of creating own state we can say that we want a change from any state.

transition('open => *', [animate('1s ease-out')]),
transition('* => open', [animate('1s ease-in')]),

So here we removed close state and instead wrote star symbol. It means that if we change from open state to any other state then we want to do ease out. If we change from any other state to open then we want to do ease in.

Animation callbacks

We also sometimes want to do something after finishing or starting of our animation. And for this we have 2 callbacks inside animations.

<div
  [@fadeInOut]="isShown ? 'open' : 'close'"
  (@fadeInOut.start)="onAnimationStart($event)"
  (@fadeInOut.done)="onAnimationDone($event)"
>
  This is a block with fade in / out
</div>
onAnimationStart(event: any) {
  console.log('onAnimationStart', event);
}

onAnimationDone(event: any) {
  console.log('onAnimationDone', event);
}

We use the name of our animation dot start and dot end where inside we provide our callback.

Void state

And the last thing that I want to show you is void and in states.

const fadeInOut = trigger('fadeInOut', [
  state(
    'in',
    style({
      opacity: 1,
    })
  ),
  transition('void => *', [style({ opacity: 0 }), animate('1s ease-out')]),
  transition('* => void', [animate('1s ease-out'), style({ opacity: 0 })]),
]);

Here we used void state which is the same as :enter and :leave that we used in a first example. It means that when our element appears we apply this styles and this animation. Same is with disappearing. Also as you can see we didn't write in state anywhere because it is a predefined state of just normal state.

As you can see it works in the same way.

Also if you are interested about how to speed up your Angular application by using detect changes make sure to check this post also.

📚 Source code of what we've done