Younes
Younes

Reputation: 99

angular animation: component is killed before trigger animation

I am trying to trigger an animation from the popin.component.ts that manage the view.

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

@Component({
  selector: "app-popin",
  templateUrl: "./popin.component.html",
  styleUrls: ["./popin.component.css"],
  animations: [
    trigger("openClose", [
      state(
        "open",
        style({
          transform: "translateY(0%)"
        })
      ),
      state(
        "closed",
        style({
          transform: "translateY(100%)"
        })
      ),
      transition("* => *", animate(500))
    ])
  ]
})
export class PopinComponent {
  @Input() isPopinOpen = false;
  @Input() isPopinAnimationActive = false;
  @Output() isPopinClosed = new EventEmitter<boolean>();

  closePopin() {
    this.isPopinClosed.emit(this.isPopinAnimationActive);
  }
}

The parent component manage the boolean to change the state.

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  isPopinAnimationActive: boolean;
  isPopinOpen: boolean;
  animate() {
    this.isPopinOpen = true;
    this.isPopinAnimationActive = true;
  }

  closeThePopin() {
    this.isPopinOpen = false;
    this.isPopinAnimationActive = false;
  }
}

I have 2 problems.

1 - when I close the popin, the animation for sliding down does not work. It works only if I remove the line in comment.

  closeThePopin() {
    // this.isPopinOpen = false;
    this.isPopinAnimationActive = false;
  }

2 - It seems that angular does not read the state for transition "open" and "closed"

transition("open => closed", animate(500))

It works only when I use * like this:

transition("* => *", animate(500))

here is the codesandbox code:

https://codesandbox.io/s/lucid-wilson-lqzw2?file=/src/app/app.component.ts

Upvotes: 0

Views: 123

Answers (2)

Faiz Shahid
Faiz Shahid

Reputation: 325

In your popin.component.html file you use *ngIf="isPopinOpen" to show/hide the div. On same div you are calling closePopin() function on click event.

So, every time when you click on div the isPopinOpen variable change to false which hide the div that contains animation content.

1 - when I close the popin, the animation for sliding down does not work. It works only if I remove the line in comment.

The animation for sliding down is working perfectly. You aren't able to see the animation because as soon as you click on div that div hides because isPopinOpen = false

To solve the issue you need to use setTimeout function on closeThePopin() function in app.component.ts file or on closePopin() function in popin.component.ts file but not in both function.

I added setTimeOut function in app.component.ts file closeThePopin() function

closeThePopin() {
    // Added
    setTimeout(() => {
      this.isPopinOpen = false;
    }, 1000);
    this.isPopinAnimationActive = false;
}

Working Code Example: CodeSandBox

Upvotes: 0

Eliseo
Eliseo

Reputation: 57981

you need "play" with Animations callback or use :enter and :leave aliases. Take account that if you has a *ngIf if is false there're no posibility to animate.

Using animations callBack is change a few your poping component

<div class="container" *ngIf="isPopinOpen " (click)="isPopinAnimationActive=false">
  <div class="popin" (@openClose.done)="!isPopinAnimationActive && closePopin()" 
       [@openClose]="isPopinAnimationActive ? 'open': 'closed'">
    content
  </div>
</div>

See that the click() only change the variable "isPopinAnimationActive"

In in (@openClose.done)where, if isPopinAnimationActive=false execute the function "closePopin()" to emit the event.

I use the "abreviate" method "condition && myFunction()". If condition is true, the function is executed, if condition is false the function is not executed.

Use :enter and :leave allow animate components under a *ngIf

Upvotes: 1

Related Questions