October 7, 2016
Angular 2 Animate.css Tutorial – How to use Animate.CSS in NG2 Application?
This Article will serve as a guide to implementing Animate.css animations with Angular 2 animation system. Animate.css is a popular and handy library for simple CSS Animations. We’ll apply the animation to a component and control it via a button. We will not use ngClass but convert the Animate.css to fit Angular 2 Animate.
Final Result:
Git Commits as Diff:
Github Repository
Final Result
Full Tutorial:
First of all, lets start a new project. We will use Angular Cli for that.
1 2 3 |
ng new animation-example cd animation-example ng serve |
Step 1: Add Component and Markup:
Create a new component as the target of our animation:
1 |
ng g component animation-target |
Now include the component in your app.component.html
1 2 3 4 5 |
<h1> {{title}} </h1> <app-animation-target></app-animation-target> |
And add a button responsible for the animation triggering
1 2 3 4 5 6 7 |
<h1> {{title}} </h1> <app-animation-target></app-animation-target> <button (click)="triggerAnimation()">Click to Trigger the Animation</button> |
Now go ahead and create the triggerAnimation method in your app component. We also need a method to reset our trigger when the animation is done.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { title = 'app works!'; triggerAnimation(){ } reset(){ } } |
Since Animations are state based in Angular 2 we need a variable that holds the current state as a string. Since we will implement the Wobble Animation from Animate.css we call our state the wobbleState.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import {Component} from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.sass'] }) export class AppComponent { title = 'app works!'; public wobbleState: string; triggerAnimation() { } reset() { } } |
Step 2: Add some Styles to our Application:
1 2 3 4 |
body, * { font-family: 'Roboto', sans-serif; font-weight: lighter; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
:host { padding: 50px; width: 500px; display: block; margin:auto; } button { border:none; padding: 25px; background: #181d69; color: #fff; font-size: 26px; width: 500px; font-weight: lighter; &:hover { background: #1a2580; } } |
1 2 3 4 5 6 7 8 9 10 11 |
:host { width: 500px; height: 200px; background: #ADFF2F; color: #1a2580; font-size: 40px; line-height: 200px; display: block; text-align: center; margin: 50px 0; } |
Step 3: Chose a Animation and prepare it to fit Angular 2 Syntax
We will go with the wobble animation from Animate.css. It is keyframe based and can simply be converted to a Angular 2 Animation. Here is the original CSS Code taken from Animate.css:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
@keyframes wobble { from { -webkit-transform: none; transform: none; } 15% { -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); } 30% { -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); } 45% { -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); } 60% { -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); } 75% { -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); } to { -webkit-transform: none; transform: none; } } .wobble { -webkit-animation-name: wobble; animation-name: wobble; } |
We will only need the Keyframes and we can remove the -webkit prefixes. Just keep it somewhere for now. We will make use of it in Step 4. Plain Animation looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
@keyframes wobble { from { transform: none; } 15% { transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); } 30% { transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); } 45% { transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); } 60% { transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); } 75% { transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); } to { transform: none; } } |
Now add the animation to the component annotation in our app.component.ts. Make sure to copy all imports.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import {Component, trigger, keyframes, animate, transition} from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], animations: [ trigger('wobble', [ transition('inactive => active', animate(1000, keyframes([ ]))), ]) ] }) export class AppComponent { title = 'app works!'; public wobbleState: string; triggerAnimation() { } reset() { } } |
Step 4: Translate the animation and add Keyframes
Now we can ‘translate’ the animation to fit Angulars needs. You can see that the keyframes have a percentage value that describes the current state of the animation. In Angular this will be called the offset. Instead of using percentage value use values between 0 and 1. Add the keyframes like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import {Component, trigger, keyframes, animate, transition, style} from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], animations: [ trigger('wobble', [ transition('inactive => active', animate(1000, keyframes([ style({transform: 'translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg)', offset: .15}), style({transform: 'translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)', offset: .30}), style({transform: 'translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)', offset: .45}), style({transform: 'translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)', offset: .60}), style({transform: 'translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)', offset: .75}), style({transform: 'none', offset: 1}), ]))), ]) ] }) export class AppComponent { title = 'app works!'; public wobbleState: string; triggerAnimation() { } reset() { } } |
Step 5: Finalize Animation Trigger
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import {Component, trigger, keyframes, animate, transition, style, NgZone} from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], animations: [ trigger('wobble', [ transition('inactive => active', animate(1000, keyframes([ style({transform: 'translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg)', offset: .15}), style({transform: 'translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)', offset: .30}), style({transform: 'translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)', offset: .45}), style({transform: 'translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)', offset: .60}), style({transform: 'translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)', offset: .75}), style({transform: 'none', offset: 1}), ]))), ]) ] }) export class AppComponent { title = 'app works!'; public wobbleState: string; constructor(public zone: NgZone) { } triggerAnimation() { this.wobbleState = "active"; } reset() { this.zone.run(() => { this.wobbleState = "inactive"; }); } } |
1 2 3 4 5 6 7 |
<h1> {{title}} </h1> <app-animation-target [@wobble]="wobbleState" (@wobble.done)="reset()"></app-animation-target> <button (click)="triggerAnimation()">Click to Trigger the Animation</button> |
We need to use ngZone in order to tell the view that our value is updated. Thats it. You can apply this probably to all animations from Animate.css. Show us your results in the comments. If you have any issues, the code diffs on GitHub could be helpful to you.
This is not working in safari and some other browsers, since transform needs a prefix such as -webkit-. I’m struggling with this :S
safari issue and some other browsers, since transform needs a prefix such as -webkit-. need a solution?
I found two wonderful libraries, maybe it can achieve these results.
https://www.npmjs.com/package/ngxani?activeTab=readme
https://github.com/fabiandev/css-animator
So you have to hardcode CSS in typescript to use CSS for these animations to work vs just attaching a CSS style to a element??