Categories
Angular JavaScript TypeScript

Angular Animations Transitions and Triggers

Spread the love

Angular is a popular front-end framework made by Google. Like other popular front-end frameworks, it uses a component-based architecture to structure apps.

In this article, we look at how to apply transitions and triggers when *ngIf is being run.

Predefined States and Wildcard Matching

We can use an asterisk to match any animation state. This is useful for defining transitions that apply regardless of the HTML element’s start or end state.

For example, we can use the asterisk as follows:

app.component.ts :

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

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"],  
  animations: [  
    trigger("openClose", [  
      state(  
        "open",  
        style({  
          height: "250px",  
          opacity: 1,  
          backgroundColor: "pink"  
        })  
      ),  
      state(  
        "closed",  
        style({  
          height: "100px",  
          opacity: 0.5,  
          backgroundColor: "green"  
        })  
      ),  
      transition("* => closed", [animate("1s")]),  
      transition("* => open", [animate("0.5s")])  
    ])  
  ]  
})  
export class AppComponent {  
  isOpen = true;toggle() {  
    this.isOpen = !this.isOpen;  
  }  
}

app.component.html :

<button (click)="toggle()">Toggle</button>  
<div [@openClose]="isOpen ? 'open' : 'closed'">  
  {{ isOpen ? 'Open' : 'Closed' }}  
</div>

In the code above, we have:

transition("* => closed", [animate("1s")]),  
transition("* => open", [animate("0.5s")])

The code above indicates that we animate for a second when we transition from any state to the closed state.

When we transition from anything to the open state, we animate for half a second.

Using Wildcard State with Multiple Transition States

We can have more than 2 states in our transition. To use the asterisk to transition between multiple states as follows:

app.component.ts :

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

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"],  
  animations: [  
    trigger("openClose", [  
      state(  
        "open",  
        style({  
          height: "250px",  
          opacity: 1,  
          backgroundColor: "pink"  
        })  
      ),  
      state(  
        "inProgress",  
        style({  
          height: "130px",  
          opacity: 0.75,  
          backgroundColor: "orange"  
        })  
      ),  
      state(  
        "closed",  
        style({  
          height: "100px",  
          opacity: 0.5,  
          backgroundColor: "green"  
        })  
      ),  
      transition("* => closed", [animate("1s")]),  
      transition("* => open", [animate("0.5s")]),  
      transition("* => inProgress", [animate("2.5s")]),  
      transition("inProgress => closed", [animate("1.5s")]),  
      transition("* => open", [animate("0.5s")])  
    ])  
  ]  
})  
export class AppComponent {  
  states = \["open", "closed", "inProgress"\];  
  index = 0;  
  state = "open"; changeState() {  
    this.index = (this.index + 1) % this.states.length;  
    this.state = this.states\[this.index\];  
  }  
}

app.component.html :

<button (click)="changeState()">Toggle</button>  
<div [@openClose]="state">  
  {{ state }}  
</div>

In the code above, we have multiple transition states and we used the wildcard to specify the animation length.

We cycled through the states with the changeState method.

We can use the void state to configure transitions for an element that’s entering or leaving a page.

It can be combined with the wildcard. It works as follows:

  • * => void — applies when the element leaves a view regardless of what state it was before it left
  • void => * — applies when the element enters a view regardless of what state it assumes when entering
  • The * state matches any state including void .

Animating Entering and Leaving a View

We can animate entering a leaving a view by styling the in state.

Then we animate the transition between the void and wildcard and vice versa to run animation when the element is being added removed and added respectively.

We can do that as follows:

app.component.ts :

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

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"],  
  animations: [  
    trigger("flyInOut", [  
      state("in", style({ transform: "translateX(0)" })),  
      transition("void => *", [  
        style({ transform: "translateX(-100%)" }),  
        animate(100)  
      ]),  
      transition("* => void", [  
        animate(100, style({ transform: "translateX(100%)" }))  
      ])  
    ])  
  ]  
})  
export class AppComponent {}

app.component.html :

<button (click)="show = !show">Toggle</button>  
<div @flyInOut *ngIf="show">  
  foo  
</div>

In the code above, we have the flyInOut trigger which has the transition from void to * , which is applied when the div with the *ngIf is inserted.

The in state has the style for the div when it’s displayed.

Then the other transition is applied when the div is being removed.

In the template, we have div with the *ngIf with the word ‘foo’ inside and a Toggle button that toggles the div on and off.

Then when we click the Toggle button, we see the word ‘foo’ fly to the right before disappearing since we have:

transition("* => void", [  
  animate(100, style({ transform: "translateX(100%)" }))  
])

as the div is being removed with *ngIf .

:enter and :leave Aliases

:enter is short for void => * and :leave is shorthand for * => void .

So we can write:

transition ( ':enter', [ ... ] );  // alias for void => *  
transition ( ':leave', [ ... ] );  // alias for * => void

Conclusion

We can animate *ngIf transitions by adding the * => void and void => * transitions.

* stands for any state and void is the state when an element leaves the screen.

:enter and :leave are short for void => * and * => void respectively.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *