Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular/4 - Route animation not working

I'm trying to implement route animations in an Angular CLI project using Angular/4. I have been trying to follow this tutorial, but with limited success.

My code reads

/src/app/_animations/fadein.animation.ts

import { trigger, state, animate, transition, style } from '@angular/animations';

export const fadeInAnimation =
// trigger name for attaching this animation to an element using the 
[@triggerName] syntax
    trigger('fadeInAnimation', [

        // route 'enter' transition
        transition(':enter', [
         // css styles at start of transition
        style({ opacity: 0 }),
         // animation and styles at end of transition
        animate('3000ms', style({ opacity: 1 }))
    ]),
]);

/src/app/dashboard/dashboard.component.ts

import { Component, OnInit } from '@angular/core';
import { SlimLoadingBarService } from 'ng2-slim-loading-bar';

// import fade in animation
import { fadeInAnimation } from './../_animations/fadein.animation';

import { PickJob } from './../pick-jobs/pick-job';
import { PickJobService } from './../pick-jobs/pick-job.service';
import { FlashService } from './../flash/flash.service';

@Component({
    templateUrl: './dashboard.component.html',
    styleUrls: ['./dashboard.component.css'],
    animations: [fadeInAnimation],
    host: { '[@fadeInAnimation]': '' }
})
export class DashboardComponent {}

/src/app/dashboard/dashboard.component.html

<div class="container_flex">
    <div class="row">
        <div class="col-md-12">
            <div class="btn btn-block btn-primary block shadow">
                Print Next Pick Job
            </div>
            <a class="btn btn-block btn-danger shadow" routerLink="/pick-jobs" routerLinkActive="menu-active">
                List Pick Jobs
            </a>
            <a class="btn btn-block btn-warning shadow" routerLink="/cages/assign" routerLinkActive="menu-active">
                Print Pick Cage Labels
            </a>
        </div>
    </div>
</div>

/src/app/app.module.ts

...
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
...
@NgModule({
  imports: [    
      ...
      BrowserAnimationsModule,
      ...

The animation never runs else, has completed prior to page load. Not sure which. Can anybody spot the error in my code? Any advice is greatly appreciated

like image 591
prime Avatar asked Apr 27 '17 13:04

prime


2 Answers

You can achieve a smooth fade out / in effect now using route animations.

Define your animation and route transitions it applies to:

const fadeIn = [
  query(':leave', style({ position: 'absolute', left: 0, right: 0, opacity: 1 })),
  query(':enter', style({ position: 'absolute', left: 0, right: 0, opacity: 0 })),
  query(':leave', animate('1s', style({ opacity: 0 }))),
  query(':enter', animate('1s', style({ opacity: 1 })))
]

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  /* Allow CSS in this component to cascade down to child components */
  encapsulation: ViewEncapsulation.None,
  animations: [
    trigger('routerAnimations', [
      transition('* => *', fadeIn)
    ])
  ]
})

Annotate your router outlet in your template:

<div class="page" [@routerAnimations]="prepareRouteTransition(outlet)">
  <router-outlet #outlet="outlet"></router-outlet>
</div>

Back in your app.component.ts implement the prepareRouteTransition(outlet) function:

prepareRouteTransition(outlet) {
    const animation = outlet.activatedRouteData['animation'] || {};
    return animation['value'] || null;
}

If you want custom animations depending on which route is coming/going, you need to add some metadata to your routes. Check out Matias Niemela's talk at ng-conf 2017 here for more info, but his demo project contains a working example.

like image 125
SpaceFozzy Avatar answered Oct 24 '22 17:10

SpaceFozzy


Yeah, this one is easy and kinda subtle at first.

Don't use the host component property. That's not doing anything for you.

Instead, what you want to do is add the synthetic property @yourTrigger to the "host" element of the component you want to animate. If that component has a selector that is written in a template as <app-dashboard>, then what you're trying to do is add an "attribute": <app-dashboard @yourTrigger>

You can do this in the component itself with @HostBinding:

@Component({
    templateUrl: './dashboard.component.html',
    styleUrls: ['./dashboard.component.css'],
    animations: [routeAnimation],
})
export class DashboardComponent {
    @HostBinding('@routeAnimation') routeAnimation = true;
}

@HostBinding sets a binding on the component's host element. This is the same element you address with :host in your template's CSS.

Note that you need both the animations property on the component and the @HostBinding decorator. The value of HostBinding should be the trigger you are using in the animation referenced in fadeInAnimation. The tutorials always call this trigger routeAnimation and I'm not sure how special that is but it's probably a good practice.

like image 27
John Christopher Jones Avatar answered Oct 24 '22 15:10

John Christopher Jones