Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Animation: Page transition without style `position: absolute`?

Purpose: I want to add a nice transition effect when click from one page to another


I tried lots of solution online, including:

  • Angular 2 — Animating Router transitions
  • Page transition animations with Angular 2.0 router and component interface promises
  • ....

one thing in common is that they all have style like position: absolute or position: fixed added, which breaks my existing app layout.

I remember when I using Angular 1, there's no need to add position: absolute to <div ui-view><div>

Is it possible in Angular 2 or 4?

like image 452
Alex G Avatar asked Feb 07 '17 11:02

Alex G


2 Answers

You can add the absolute positioning exclusively to the leaving animation.

transition(':enter', [          
    style({transform: 'translateX(100%)'}),    
    animate('0.3s ease-in-out', style({transform: 'translateX(0%)'}))
]),
transition(':leave', [          
    style({transform: 'translateX(0%)', position: 'absolute', left: 0, right: 0, top: 0}),    
    animate('0.3s ease-in-out', style({transform: 'translateX(-100%)'}))
])

So only the leaving route is positioned absolutely, while the entering route is positioned staticly.

If it doesn't work, make sure that your router-outlet is wrapped by position: relative

<div style="position: relative;">
  <router-outlet></router-outlet>
</div>

And that your route-components have display: block

@Component({
  styles:[':host {display: block;}']
like image 119
Martin Cremer Avatar answered Nov 09 '22 03:11

Martin Cremer


Talking about Angular version 4.3.x. Reading the router documentation, they explain how to add animation between routes. Here is a resume for the lazy ones (including myself).

You want to import animations libraries from @angular/core (and not @angular/animations):

import {
  AnimationEntryMetadata,
  animate,
  state,
  style,
  trigger
} from '@angular/core';

export const fadeInAnimation: AnimationEntryMetadata = trigger('fadeInAnimation', [
  transition(':enter', [
    style({
      opacity: 0,
      transform: 'translateY(20px)'
    }),
    animate(
      '.3s',
      style({
        opacity: 1,
        transform: 'translateY(0)'
      })
    )
  ])
]);

Then in your component, use the HostBinding decorator in order to specify the component's layout css properties (you don't need use a fixed or absolute position):

import { Component, OnInit, HostBinding } from '@angular/core';

import { fadeInAnimation } from './../animations/fadein';

@Component({
  animations: [fadeInAnimation],
  selector: 'app-posts',
  templateUrl: './posts.component.html'
})
export class DemandsComponent implements OnInit {
  @HostBinding('@fadeInAnimation') fadeInAnimation = true;
  @HostBinding('style.display') display = 'block';
  @HostBinding('style.position') position = 'relative';

  // Rest of the code
}

Adding this to each routed component can be cumbersome. The documentation suggest, and I quote:

Applying route animations to individual components works for a simple demo, but in a real life app, it is better to animate routes based on route paths.

This article from Matias Niemelä can help https://www.yearofmoo.com/2017/06/new-wave-of-animation-features.html#routable-animations

like image 3
lkartono Avatar answered Nov 09 '22 02:11

lkartono