Write a post

Basic Component Animation with Angular 2

Published Dec 08, 2016Last updated Jan 18, 2017
Basic Component Animation with Angular 2

Animation in Angular 2 is not as straightforward or intuitive as you might have assumed. Nonetheless, it is very simple to achieve.

To illustrate how behavioral component animations work in Angular 2, we are going to implement the jQuery slideToggle feature in an Angular application without bringing jQuery to the field.

The Host Component

Before adding animations, it is ideal to create a component that is going to host your animations:

// ./app/toggle/toggle.component.ts
import { 
    Component
} from '@angular/core';

@Component({
    selector: 'toggle',
    template: `
     <div class="modal">
        <ng-content></ng-content>
    </div>
    `,
    styles: [
  `
  .modal {
    background-color:#ffffff;
    border:1px solid lightgray;
    box-shadow:0 0 7px rgba(0,0,0,.2);
    width:40%;
    text-align:center;
    padding:30px;
    border-radius:6px;
    font-weight:400;
    margin:40px auto;
    overflow-y: hidden;
  }
  `
  ],
})
export class ToggleComponent {}

There you go! Just a basic Angular component with template and styles.

Creating Animation

To add animation to our existing component, we need to import some members from @angular/core. These members are solely for animation purposes as we will soon see:

// ./app/toggle/toggle.component.ts
import { 
    Component,
    // Animation members
    trigger, state, animate, transition, style 
} from '@angular/core';

We will discuss the purpose for each while we make use of them.

Animations

The Component meta-data does not end with just selectors, templates, and styles. There is one more called animations. animations is an array of declarative animations that we intend to apply to our component:

// ./app/toggle/toggle.component.ts
@Component({
    ...
    animations: [
    // Each animation created with 'trigger'
    trigger('toggleState', [
      // Declare behavior for each state
  ],
})

The animations array can take as much as you consider useful. Each item in the array is the trigger method called with what triggers it and another array of configuration defining how the animation should behave.

It is reasonable to wonder where toggleState came from. It is going to be a property on the component template that the animation will act on. Its values are used to determine what happens during the animation process. In our case, we expect the values to be a boolean so let's tell Angular what to do when the value is either true or false:

// ./app/toggle/toggle.component.ts
@Component({
    ...
    animations: [
    trigger('toggleState', [
    // What happens when toggleState is true
      state('true' , style({ maxHeight: '200px' })),
      // What happens when toggleState is false
      state('false', style({ maxHeight: 0, padding: 0, display: 'none' }))
    ])
  ],
})

What we are trying to do is to slide in when toggleState value is true and slide out when the value is false. We now have animation points, how about transitioning:

Transitioning

// ./app/toggle/toggle.component.ts
@Component({
    ...
    animations: [
    trigger('toggleState', [
      state('true' , style({  })),
      state('false', style({ maxHeight: 0, padding: 0, display: 'none' })),
      // transition
      transition('* => *', animate('300ms')),
    ])
  ],
})

transition method takes a flow string which determines how the animation will be executed. The wildcard sign (*) means that from any given state to another given state, it should perform the animation for 300ms. To break it down, if the transition is from true to false or false to true, it would use a duration of 300ms to complete it

The illustration might not be the desired behavior sometimes. You might want one transition to be faster than the other. To do that, you can call the transition method multiple times:

transition('0 => 1', animate('300ms')),
transition('1 => 0', animate('500ms'))

Triggering Animation

Now that we have successfully set up a slide animation, what is left is to mount is the animation as a property to the element we want to animate. In this case, the div in our ToggleComponent template;

// ./app/toggle/toggle.component.ts
@Component({
    selector: 'toggle',
    template: `
     <div class="modal" [@toggleState]="shouldToggle">
        <ng-content></ng-content>
    </div>
    `,
    ...
})

The toggleState trigger, which we defined earlier, is now added to our component's template and passed in a value. The value must be a boolean and can be setup by any event of your choice, in my case a click event:

// ./app/toggle/toggle.component.ts
import { 
    Component, Input,
    trigger, state, animate, transition, style 
} from '@angular/core';

....

export class ToggleComponent {
    @Input() shouldToggle = false;
}

Because we are receiving the value from a parent component using Input, let's have a look at how the parent component implements the event:

// ./app/app.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'app',
    templateUrl: `
    <div id="fab" (click)="handleClick()">
      <div id="icon">
      +
      </div>
    </div>
    
    <toggle [shouldToggle]="toggle">Hello</toggle>
  `,
    styleUrls: ['
    ...
  ']
})
export class AppComponent{
    toggle = false;
    handleClick(){
        this.toggle = !this.toggle
    }
}

The event is triggered when the fab is clicked. The event handler toggles a toggle property with false or true value. This value is then passed to the toggle element's [shouldToggle] property.

Wrapping Up

To find the completed demo of this tutorial, you can check it out here

Animation features in Angular 2 is new and lots of other cool stuff are on the way. Similarly, you can also find Angular 2 framework highlights here.

Nothing stops you from using your usual CSS3 animations in Angular 2 but when it comes to handling heavy interaction in your app's components, Angular's got you as well.

Discover and read more posts from Christian Nwamba
get started
Enjoy this post?

Leave a like and comment for Christian

1
3
Extracting Information from a Link with Node.js & AngularJS
Why You Should Use AngularJS's "Controller as" Syntax
Android UI Tutorial: Layouts and Animations