Unique Route Animations Per Route Angular
Animations are a must have feature in all the modern applications, so today we will look into something rather had to get right, Route animations.
I’m expecting that anyone who is reading this tutorial is having a basic idea on setting up an angular project and configuring routes.
Ok, Lets start
First things first, Setup
Very first thing we have to do is make sure what we do will work across many browsers, angular animation behind the scene will be using css3 animations and there may be browsers that partially support css3 animations to over come this problem and target as much as browsers you will have to install a polyfill, lets see how you can do that.
- npm install web-animations-js –save
- go to the src/polyfills.ts and look for a comment import ‘web-animations-js’; and uncomment it
Next we need to say angular that we are going to use the Angular Animation module in our application to do that you have to go to the app.module.ts and then because Angular animation does not comes in the core package we will have to import it
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
And Use it like below
@NgModule({ declarations: [ ....... ], imports: [ ......... BrowserAnimationsModule ], providers: [], bootstrap: [ .......... ] }) export class AppModule { }
Ok, We are good to modify our Routes
now i’m assuming that in your project you have 2 or many routes configured to a router-outlet for sake of explaining i’ll expect two of them to be like this
{ path : "login", component : LoginComponent }, { path : "home", component : HomeComponent }
now since we are trying to create unique animations per route, there should be a way that we can say to angular in run time that please use this animation when user routing form login to home right ?
so lets see how we can do that, we are going to achieve that by specifying the state within the route it self, so that in run time we can look at the route A’s state and then when it navigate to route B we can create a transition.
Let us modify our routes like below, ( data attribute in a route is the way we can store data within routes to use in runtime )
{ path : "login", component : LoginComponent , data : { state : "login"} }, { path : "home", component : HomeComponent , data : { state : "home"} }
.we are done here! next is to understand how we are going to use this state attribute in action
Route data in action
Let us go to our root component and write some animation code, first import the required modules
import { trigger, state, animate, style, transition, query, group, animateChild } from '@angular/animations'
and then you will have to write the animation logic in the animation attribute in @Component metadata, and then write a specific method which will return the state according to the route, see the example below.
@Component({ selector : "body", templateUrl : 'app.component.html', styleUrls : [ 'app.component.scss' ], animations : [ trigger('routerAnimations', [ transition('home <=> login', [ query(':enter, :leave', style({ position: 'absolute', top: 0, left: 0, right: 0 })), query(':leave', style({ zIndex: 100 })), query(':enter', style({ transform: 'translateX(100%)' })), group([ query(':leave', group([ animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translateX(-100%)' })), // y: '-100%' animateChild() ])), query(':enter', group([ animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translateX(0%)' })), animateChild() ])) ]) ])]) ] }) export class RootComponent implements OnInit{ prepareRouteTransition(outlet) { const state = outlet.activatedRouteData['state'] || null; return state; } }
Now what happens here is that in few mintues of time we are going to configure our prepareRouteTransition method in a way that it will return a state according to the route and we are using that state to trigger our animation defined in the animations array.
so technically if user goes from home to login page above animation will work.
Final touches
As I explained now we need to pass the current outlet to the prepareRouteTransition method so that it can take out the configuration object of the current route from the outlet.
<div [@routerAnimations]="prepareRouteTransition(outlet)" > <router-outlet #outlet="outlet"></router-outlet> </div>
so we are now dynamically passing the state value to the routeAnimation trigger so that based on that state correct animation can be fired.
So that is it guys if you find any problems in the tutorial or difficulties you can either send me a message or refer to this https://github.com/matsko/ng4-animations-preview which was done in ng conf