Angular 2 "slide animation" of the routed component

let's say I have 2 routed components and two Routerlinks in a fixed navigation bar to route them. I want them to slide to the right when I click on Routerlinks.

I don't want to offset the component with css and use the timeout function to change the css class so that it can be entered (for example, using ngStyle or ngClass).

Are there even more elegant ways to achieve this in Angular 2?

Thanks!

+6
source share
2 answers

With Angular 4.1, you can now create specific route animations. This is different from starting an animation when a component is displayed, as it allows you to simultaneously activate the input / output component for a smooth transition and let you change the transition depending on which component is coming or going. This means that you can perform complex transitions, for example, move the component to the right if you are drilling content, and move it to the left if you enter it using the back button from another component.

  • First, annotate your router socket (e.g. app.component.html ):

     <div class="page" [@routerAnimations]="prepareRouteTransition(outlet)"> <router-outlet #outlet="outlet"></router-outlet> </div> 
  • Implement the prepareRouteTransition(outlet) function in the corresponding component definition (for example, app.component.js ).

     prepareRouteTransition(outlet) { const animation = outlet.activatedRouteData['animation'] || {}; return animation['value'] || null; } 
  • Define your animations (e.g. app.component.js ):

      const slideLeft = [ query(':leave', style({ position: 'absolute', left: 0, right: 0 ,transform: 'translate3d(0%,0,0)' }), {optional:true}), query(':enter', style({ position: 'absolute', left: 0, right: 0, transform: 'translate3d(-100%,0,0)' }), {optional:true}), group([ query(':leave', group([ animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(100%,0,0)' })), // y: '-100%' ]), {optional:true}), query(':enter', group([ animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(0%,0,0)' })), ]), {optional:true}) ]) ] const slideRight = [ query(':leave', style({ position: 'absolute', left: 0, right: 0 , transform: 'translate3d(0%,0,0)'}), {optional:true}), query(':enter', style({ position: 'absolute', left: 0, right: 0, transform: 'translate3d(100%,0,0)'}), {optional:true}), group([ query(':leave', group([ animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(-100%,0,0)' })), // y: '-100%' ]), {optional:true}), query(':enter', group([ animate('500ms cubic-bezier(.35,0,.25,1)', style({ transform: 'translate3d(0%,0,0)' })), ]), {optional:true}) ]) ] 
  • Add animation metadata to the route definitions (e.g. app.routing.ts ):

     const routes: Routes = [ { path: 'products', component: ProductsComponent, data: { animation: { value: 'products', } } }, { path: 'products/:id', component: ProductDetailComponent, data: { animation: { value: 'product-detail', } } } 
  • Finally, register the routerAnimations animation trigger on your component with the animations you selected and route metadata (e.g. app.component.js ):

     @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], animations: [ trigger('routerAnimations', [ transition('products => product-detail', slideRight), transition('product-detail => products', slideLeft), ]) ] }) 

Don't forget the polyfill web animation API to target older browsers

Mathias Nimela talks about animating routes in ng-conf here (with demo): https://youtu.be/Oh9wj-1p2BM?t=12m21s

His presentation code: https://github.com/matsko/ng4-animations-preview

+7
source

From the point of view of sliding, it is quite simple.

You can link to the Official Angular 2 Animation Papers .

You can also check this Plunker I made for a simple storefront using the new v3 router

Keep in mind that I'm struggling to figure out how to actually have leave / exit / void transitions when the triggered element is about to be destroyed from the view.

I opened another thread in Angular 2 Animation - there is no visible '* => void "effect when changing routes / components to try to figure out how to make the router pay attention to the outgoing animation / transition time.

 @Component({ selector: 'home', directives: [ROUTER_DIRECTIVES], template: ` <div @flyInOut="'active'" class="radibre"> </div> `, styles: ['.radibre { width: 200px; height: 100px; background: red; }'], animations: [ trigger('flyInOut', [ state('in', style({transform: 'translateX(0)'})), transition('void => *', [ style({transform: 'translateX(-100%)'}), animate(100) ]), transition('* => void', [ animate(100, style({transform: 'translateX(100%)'})) ]) ]) ] }) export class Home { constructor() { } } 
 @Component({ selector: 'page', template: ` <div @testingBottom="'active'" class="page"></div>`, styles: ['.page { width: 300px; height: 50px; background: green; }'], animations: [ trigger('testingBottom', [ state('active', style({transform: 'scale(1)'})), transition('void => *', [ style({transform: 'scale(0)'}), animate(100) ]), transition('* => void', [ animate(100, style({transform: 'scale(0)'})) ]) ]) ] }) 
+7
source

All Articles