Introduction to Animations in Angular

Angular 2 comes with its own powerful animation engine and DSL based on the Web Animations API. The following is a high-level overview of animations in Angular 2, and more posts will be need to explore animations in details. Here's a simple demo app, hit enter to add items and click on an item to remove it. Notice the different animations when a new item is added or removed:

1. Web Animations Polyfill

Since the Web Animations API is not supported in all browsers, we need to add a polyfill to the index.html page right before the closing </body> tag:

<script src="/assets/vendors/web-animations.min.js">
</script>

You can get the Web Animations polyfill from this Github project. Here I placed the web-animations.min.js file in the /assets/vendors/ folder of my project.

2. Imports in the components

Angular 2

For our example, we need trigger, style, transition, animate and group from @angular/core, so let’s import them in our component:

import { trigger, style, transition, animate, group }
    from '@angular/core';

Angular 4+

Starting with Angular 4, animations are in their own package instead of with @angular/core so your import statement will look like this instead:

import { trigger, style, transition, animate, group }
    from '@angular/animations';

And you’ll also need to import the BrowserAnimationsModule module in your app module:

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

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

3. Defining our Animations

We place our animation declarations in the component metadata like so:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  animations: [
  trigger('itemAnim', [
    transition(':enter', [
      style({transform: 'translateX(-100%)'}),
      animate(350)
    ]),
    transition(':leave', [
      group([
        animate('0.2s ease', style({
          transform: 'translate(150px,25px)'
        })),
        animate('0.5s 0.2s ease', style({
          opacity: 0
        }))
      ])
    ])
  ])
]
})

The syntax can seem daunting at first, but once broken down it makes sense instantly and it offers a lot of flexibility and power.

The trigger defines a name to use in the template to trigger the animation. Transition defines the states in which the animation should run, the style for each state and the animation duration, delay and easing with animate. Group allows to define multiple animations for a single state.

In more complex scenarios, we would also import state from @angular/core and define named and specific animation states.

Here though we used the :enter and :leave keywords, introduced in Angular 2.1. :enter is a shorthand for void => * and :leave is a shorthand for * => void. * is a wildcard to represent any state, and void is a special state for when the targeted element is not in the view. That’s why void => * instructs Angular that the animation should happen whenever the element enters the view.

Animate can take a integer value for the amount of milliseconds, or a string with the duration, optional delay and optional easing. For example: ‘0.9s 1s ease-in-out’ or ‘200ms ease’.

4. Template

Our template looks like the following. It’s normal Angular 2 template code, with the addition of the itemAnim trigger placed in brackets and prepended with an @ sign, highlighted below:

<input #itemInput
  (keyup.enter)="addItem(itemInput.value); itemInput.value=''">

<button
  (click)="addItem(itemInput.value); itemInput.value=''">
  Add
</button>

<ul *ngIf="items">
  <li *ngFor="let item of items"
      (click)="removeItem(item)"
      [@itemAnim]>{{ item }}</li>
</ul>
✖ Clear

🕵 Search Results

🔎 Searching...