By Gary simon - Nov 07, 2016
Angular 2 allows you to integrate animations in your apps easily, along with a lot of flexibility. Below, I'll walk you through how animation works along with some examples.
Be sure to check out the Coursetro Youtube Channel and subscribe if you enjoy this tutorial.
In your component, there are several members that you will need to import from the @angular/core library.
import {
Component,
trigger,
state,
style,
transition,
animate,
keyframes
} from '@angular/core';
As you can see, we'll need trigger, state, style, transition, animate and keyframes (if you wish to create multi-step animations).
In the @Comopnent metadata, we'll write some HTML and CSS for our example. As you can see from the HTML, we have a button, and a #content that we'll aim to animate once the button is clicked.
@Component({
selector: 'my-app',
template: `
<div class="row">
<div class="columns">
<button>Press me for animation</button>
</div>
<div class="columns">
<div id="content">Look at me animate</div>
</div>
</div>
`,
styles: [`
button { font-size:1.8em; }
#content { padding:30px; background:#eeeeee; }
`]
})
Note: From the video above, I integrate the Foundation frontend framework, which is why we're using .row and .columns to structure a simple 2 column layout. As a part of this series, you can learn how to integrate foundation with our written tutorial here.
From our code above, let's modify the <button> html to include our event binding to a method called toggleMove(). Are you unfamiliar with event binding? Read or watch our Angular 2 event binding tutorial.
<button (click)="toggleMove()">Press me for animation</button>
This will allow us to detect when the button is clicked, and execute logic within a method called toggleMove().
Before we define the logic in our toggleMove() method, we need to declare animations in our component metadata. The beginning comma goes right after the closing bracket of styles: [ ]
,
animations: [
trigger('focusPanel', [
state('inactive', style({
transform: 'scale(1)',
backgroundColor: '#eee'
})),
state('active', style({
transform: 'scale(1.1)',
backgroundColor: '#cfd8dc'
})),
transition('inactive => active', animate('100ms ease-in')),
transition('active => inactive', animate('100ms ease-out'))
]),
]
Each unique animation requires its own trigger. The first argument of the trigger function is the name. We'll name ours focusPanel. The next argument accepts state & transition functions.
state declares an animation state within the trigger.
transition allows you to define animation between states.
In the example above, we're applying 2 different states with different background colors and sizes (through scale). We also define a transition for each state, going from inactive to active and vice versa, with a 100ms duration.
Now that we defined a trigger called 'focusPanel', we'll use property binding on the #content div:
<div id="content" [@focusPanel]='state'>Look at me animate</div>
Notice we're pointing to a property called 'state', we'll define that in the next step. On any element that we place [@focusPanel], the animation that's defined within that trigger will apply to that element.
In the component class, let's define toggleMove():
export class AppComponent {
state: string = 'inactive';
toggleMove() {
this.state = (this.state === 'inactive' ? 'active' : 'inactive');
}
}
First we declare a property with the name of state, and the type of string. By default, let's set the value to 'inactive' once the component loads.
Then in toggleMove(), we declare this.state as being active if its present value is inactive, and the opposite if the value is active.
Now if you load the app and click on the button, the size and background color of the #content div will change, and toggle between our 2 states.
Below is all of the code from above, plus I added in one more animation trigger along with a property binding on #content div. Try it out!
import {
Component,
trigger,
state,
style,
transition,
animate,
keyframes
} from '@angular/core';
@Component({
selector: 'my-app',
template: `
<div class="row">
<div class="columns">
<button (click)="toggleMove()">Press me for animation</button>
</div>
<div class="columns">
<div id="content" [@focusPanel]='state' [@movePanel]='state'>Look at me animate</div>
</div>
</div>
`,
styles: [`
button { font-size:1.8em; }
#content { padding:30px; background:#eeeeee; }
`],
animations: [
trigger('focusPanel', [
state('inactive', style({
transform: 'scale(1)',
backgroundColor: '#eee'
})),
state('active', style({
transform: 'scale(1.1)',
backgroundColor: '#cfd8dc'
})),
transition('inactive => active', animate('100ms ease-in')),
transition('active => inactive', animate('100ms ease-out'))
]),
trigger('movePanel', [
transition('void => *', [
animate(600, keyframes([
style({opacity: 0, transform: 'translateY(-200px)', offset: 0}),
style({opacity: 1, transform: 'translateY(25px)', offset: .75}),
style({opacity: 1, transform: 'translateY(0)', offset: 1}),
]))
])
])
]
})
export class AppComponent {
state: string = 'inactive';
toggleMove() {
this.state = (this.state === 'inactive' ? 'active' : 'inactive');
}
}