Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically create Angular animations

I am creating a paging component that slides to next or previous fullscreen page. Because issues with different browsers and devices I have abandoned just using CSS transitions for now. I have a working angular animate solution but the new problem is that it doesn't scale.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  animations: [
    trigger('slideTransition', [
      state('firstPage', style({ transform: 'translateX(0)' })),
      state('secondPage', style({ transform: 'translateX(-100%)' })),
      transition('firstPage=>secondPage', animate('0.6s ease')),
      transition('secondPage=>firstPage', animate('0.6s ease'))
  ])]
})
export class AppComponent {

  state = 'firstPage';

  nextPage() {
    this.state = 'secondPage';
  }

  previousPage() {
    this.state = 'firstShowing';
  }

}

The problem is, as you see, when I have for example 9 pages. I do not want to define 9 states and 18 transitions. How can I do reusable states or generate the states and transitions runtime based on the number of pages? Any ideas?

The template would look something like this

<div class="container">
  <div [@slideTransition]="state" class="page">
    <h1>Page 1</h1>
    <div class="clicker" (click)="nextPage()">clickity</div>
  </div>
  <div [@slideTransition]="state" class="page">
    <h1>Page 2</h1>
    <div class="clicker" (click)="previousPage()">clackity</div>
  </div>
</div>
like image 227
Hampus Avatar asked Jun 02 '17 07:06

Hampus


People also ask

How do I use BrowserAnimationsModule?

The BrowserAnimationsModule must be imported in the main module of the application app. module. ts and after importing, it is necessary to restart the application so that the imported module is recognized.

Which animation strategy would you use to apply multiple styles for a transition?

The keyframes() function in Angular allows you to specify multiple interim styles within a single transition. An optional offset can be used to define the point in the animation where each style change should occur.


1 Answers

What you need is sending params to the state. This is possible by adding a class member and keep updating it depending on your page number. Then wire that in your HTML.

Now the following is potential additions to your existing code:

animations: [
  trigger('slideTransition', [
    // ...
    state('*',
          style({ marginLeft: '{{pageMarginValue}}%' }), 
          {params: {pageMarginValue: 0}}),
    transition('*=>*', animate('0.6s ease')),
    // ...
])

]

Then add this to your class:

export class AppComponent {
  // ...
  private currentMargin = 0;
  private step = 10; // replace with actual value

  next(): void { this.currentMargin += this.step; }
  previous(): void { this.currentMargin -= this.step; }

  // ...
}

In your HTML, pass the currentMargin like so:

<div [@slideTransition]="{value: state, params: { pageMarginValue: currentMargin }}"></div>
like image 153
arsanyf Avatar answered Oct 08 '22 19:10

arsanyf