Search code examples
cssangularangular-animations

Angular 5: fade animation during routing (CSS)


I have 2 routes :

export const appRoutes: Route[] = [
{
                path: 'page1',
                component: Page1Component,
                data: {
                    animation: 'page1'
                }
            },
{
                path: 'page2',
                component: Page2Component,
                data: {
                    animation: 'page2'
                }
            },
];

My Route animation :

export const routeStateTrigger = trigger('routeState', [
    transition('* => *', [
        query(':enter', [
            style({ position: 'absolute', opacity: 0 })
        ], { optional: true }),
        query(':leave', [
            animate(300, style({ opacity: 0 }))
        ], { optional: true }),
        query(':enter', [
            style({ position: 'relative', opacity: 0 }),
            animate(300, style({ display: 'visible', opacity: 1 }))
        ], { optional: true })
    ])
]);

My router-outlet :

<div [@routeState]="getAnimationData(routerOutlet)">
    <router-outlet #routerOutlet="outlet"></router-outlet>
</div>

and getAnimationData method :

getAnimationData(routerOutlet: RouterOutlet) {
    const routeData = routerOutlet.activatedRouteData['animation'];
    return routeData ? routeData : 'rootPage';
}

This works well, except page transition occurs in two steps (sequential) :

  1. page1 disappears (300 ms)
  2. AND THEN page2 appears (300 ms)

What I want is the disappearing of page1 should happen the same time page2 appears, the transitions should occur simultaneously.

Problem :

I want to prevent the TEMPORARY RESIZING of the content of page1 or page2.

Explanation :

When animating with group() to make them appear-disappear simultaneously AND setting the position temporarily to 'absolute' then the content resizes (because the content is width 100%, and when the container size changes the content changes as well).

I've tried playing with z-index :

position: 'relative', 'z-index': 1

but that didn't work, it's still stacking entering page below leaving page.

Is there a good solution to this ?


Solution

  • I finally made it work :

    export const routeStateTrigger = trigger('routeState', [
        transition('* => *', [
            query(':enter', [
                    style({ opacity: 0 })
                ], { optional: true }
            ),
            group([
                query(':leave', [
                        animate(300, style({ opacity: 0 }))
                    ],
                    { optional: true }
                ),
                query(':enter', [
                        style({ opacity: 0 }),
                        animate(300, style({ opacity: 1 }))
                    ],
                    { optional: true }
                )
            ])
        ])
    ]);
    

    This CSS selector did the trick :

    /deep/ router-outlet~* {
        position: absolute;
        width: 100%;
        height: 100%;
    }