A journey into Angular Animation

Leverage the AnimationPlayer’s power

In this article will see how to take fully control of the Angular Animation library, through a simple fading animation.

For a detailed view of all the animation functions that angular provide I would recommand this great article of Year Of Moo. In this article we’ll focus on some limits and how to workaround.

Let’s build a simple fading animation on a list of movies :

Simple Animation

In this case the animation will apply only on the ul element. Here is how you can apply this animation on each element with delay between each li (stagger) :

Animate Children

Ok, it looks cool. But as a developer I want to be able to reuse my animations. For that I’ll create an AnimationReferenceMetadata and use it for this transition:

Reusable Animation

Great ! But, now I need to customize the properties of my animation depending on the component I’m on. No problem :

Reusable Animation with Params

Ok, ok, but I don’t always want to apply this animation on li elements. Why not use a params for that ?

Limitation

Unfortunately, Angular Animation doesn’t support params for query or stagger value :

NOT WORKING

Ok, not a big deal. Let’s use a function to create our animation :

NOT WORKING IN PROD MODE

This work in dev mode, but it will produce an error at compile time in production mode : “Function expressions are not supported in decorators in ‘fade’”

Here we see that the only parameters we can change are in the style or in animate. And even here, it works only with pre-compiled values. We cannot change parameters based on the element current position for example.

Animation Player

To workaround these limitations, Angular Animtation provides an AnimationBuilder service that can build animation players at runtime.

Animation Player
Here we create a ViewChild to reference our movie list. And on init, we create a player that run the animation once. We use the previous animation function in build and add the params in create.

Looks cool, but we have a problem of interroperability between the two methods (compiletime and runtime). Let’s refactor the animation:

Let’s update a little bit our template, to see the two methods in action side-by-side :

Here we animate the list of li on init with the Animation Player, and when we click on “Add” this will trigger the :enter transition of the new li element.

Limitation

Animation Player is powerful, but it doesn’t manage state transitions. Here we leverage the components hooks ngOnInit to mimic :enter. We could also have used ngOnDestroy for :leave, but for more complexe state management we’ll need to implement it ourself.

Further researches

Now that we have the foundations, we can create a library of reusable animations for Angular. And improve the Animation Player experience by wrapping it up inside a directive.