8

I'm currently experimenting with Angular7 route transition animations and have the following problem:

In my app there is a entry-component which has its own routing module and <router-outlet>. What I'm trying to achieve is that whenever the route changes the old displayed component fades away (opacity: 0) before the new component fades in. But unfortunately I can't seem to make it work. The animations don't play at all, and debugging as explained in the angular docs:Animations transition and triggers

(@routeAnimation.start)="onAnimationEvent($event)"
(@routeAnimation.done)="onAnimationEvent($event)"

shows that the animation is only triggered once (on pageload; and even then it doesn't play) but not while I use my navigator-component to navigate through the app.

My code looks like this:

entry.component.ts

@Component({
  selector: 'entry',
  templateUrl: './entry.component.html',
  styleUrls: ['./entry.component.css'],
  animations: [routeAnimation],
})
export class EntryComponent implements OnInit {

  constructor() { }

  ngOnInit() { }

  prepareRoute(outlet: RouterOutlet) {
    const animation = outlet.activatedRouteData['animation'] || {};
    return animation['value'] || 'WelcomePage';
  }
}

entry.component.html

<navigator>
</navigator>
<div [@routeAnimation]="prepareRoute(o)" id="entry-content">
  <router-outlet #o="outlet" name="entry"></router-outlet>
</div>

entry-routing.module.ts

const routes: Routes = [
  {
    path: 'entry',
    component: EntryComponent,
    children: [
        {
            path: '',
            component: WelcomeComponent,
            outlet: 'entry',
            data: { animation: 'WelcomePage' }
        },
        {
            path: 'introduction',
            component: IntroductionComponent,
            outlet: 'entry',
            data: { animation: 'IntroductionPage' }
        }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class EntryRoutingModule { }

route.animation.ts

export const routeAnimation = trigger(
  'routeAnimation', [
    transition('* => *', [
      group([
        query(':enter', style({ opacity: 0 })),
        query(':leave', [
          animate('0.5s', style({ opacity: 0 })),
          style({ display: 'none' })
        ], { optional: true }),
        query(':enter', [
          animate('2s',
          style({ opacity: 1 })),
          animateChild()
        ], { optional: true })
      ])
    ]),
  ]
);

Any Ideas what's missing/what I do wrong? Help is greatly appreciated and many thanks in advance!

Mick
  • 113
  • 1
  • 8
  • Did you find a solution? I'm struggling with the same problem. – Shy Agam Mar 07 '19 at 21:19
  • 1
    I was facing the same issue and it ended up being caused by my prepareRoute() method. I was checking activated route data for the animation (as in the Angular docs), however I was wanting transitions on all route changes, so I was not using route data to set the animation. Needed to not check route data in my prepareRoute() method and everything is great again! :) – CICSolutions Feb 26 '20 at 18:20

1 Answers1

0

Here, your

entry.component.html would be,

<navigator>
</navigator>
<div class="parent-router-cls" [@routeAnimation]="o.isActivated ? o.activatedRoute : ''" id="entry-content">
  <router-outlet #o="outlet" name="entry"></router-outlet>
</div>

entry.component.scss

.parent-router-cls{
    position: relative;
    router-outlet ~ * {
        position: absolute;
        height: 100%;
        width: 100%;
    }
}

Here, I think you want animation on all router-outlet, I think don't need to add animation in entry-routing.module.ts

data: { animation: 'WelcomePage' }

So, your entry-routing.module.ts would be,

const routes: Routes = [
  {
    path: 'entry',
    component: EntryComponent,
    children: [
        {
            path: '',
            component: WelcomeComponent,
            outlet: 'entry',
        },
        {
            path: 'introduction',
            component: IntroductionComponent,
            outlet: 'entry',
        }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class EntryRoutingModule { }

and animation file will be,

import {
    trigger,
    animate,
    transition,
    style,
    query,
    group
  } from '@angular/animations';
  
export const fadeAnimation = trigger('fadeAnimation', [
  transition('* => *', [
    query(
      ':enter',
      [style({ opacity: 0 })],
      { optional: true }
    ),
    query(
      ':leave',
      [style({ opacity: 1 }), animate('0.3s', style({ opacity: 0 }))],
      { optional: true }
    ),
    query(
      ':enter',
      [style({ opacity: 0 }), animate('0.3s', style({ opacity: 1 }))],
      { optional: true }
    )
  ])
]);