Pulse7
9/23/2017 - 4:19 PM

Hierarchical Route Animations

.route-container {
    position:relative;
}
.route-container>* {
    display:block;
}

{path: '', component: HomeComponent, data: {depth: 1}},
{path: 'posts/:id', component: PostComponent, data: {depth: 2}},
{path: 'posts/:id/details', component: PostDetailComponent, data: {depth: 3}}

<div class="route-container" [@routeAnimation]="getDepth(myOutlet)">
    <router-outlet #myOutlet="outlet"></router-outlet>
</div>

getDepth(outlet) {
    return outlet.activatedRouteData['depth'];
}

import { trigger, transition, group, query, style, animate } from '@angular/animations';
animations: [
    trigger('routeAnimation', [
        transition('1 => 2, 2 => 3', [
            style({ height: '!' }), //or remove and add .route-container{height: 200px; padding: 1px;}
            query(':enter', style({ transform: 'translateX(100%)' })),
            query(':enter, :leave', style({ position: 'absolute', top: 0, left: 0, right: 0 })),
            group([
                query(':leave', [
                    animate('0.3s cubic-bezier(.35,0,.25,1)', style({ transform: 'translateX(-100%)' })),
                ]),
                // and now reveal the enter
                query(':enter', animate('0.3s cubic-bezier(.35,0,.25,1)', style({ transform: 'translateX(0)' }))),
            ]),
        ]),
        transition('3 => 2, 2 => 1', [
            style({ height: '!' }), //or remove and add .route-container{height: 200px; padding: 1px;}
            query(':enter', style({ transform: 'translateX(-100%)' })),
            query(':enter, :leave', style({ position: 'absolute', top: 0, left: 0, right: 0 })),
            group([
                query(':leave', [
                    animate('0.3s cubic-bezier(.35,0,.25,1)', style({ transform: 'translateX(100%)' })),
                ]),
                // and now reveal the enter
                query(':enter', animate('0.3s cubic-bezier(.35,0,.25,1)', style({ transform: 'translateX(0)' }))),
            ]),
        ]),
    ])
]