Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

175
Views
Angular2: How do you run 2 animations in parallel?

I have a container that expands/shrinks. There is an element inside that container that should fade in when the container expands and fade out when the container shrinks.

My Problem

  • When the container expands, the animation of both elements work.
  • When the container shrinks, only the container animation works.
  • If I remove the container expansion animation, then the fade in/out animations work as expected.

How do I make all animations execute in parallel under both expand/shrink conditions?

Note the use of ngIf. This is intentional as it destroys the element at the end of the animation sequence.

Here is a plunkr of my current state: https://embed.plnkr.co/TXYoGf9QpErWmlRvQF9Z/

The component class:

export class App {
  expanded = true;

  toggleExpandedState() {
    this.expanded = !this.expanded;
  }

  constructor() {
  }
}

The template:

<div class="container" [@expansionTrigger]="expanded">
  <div class="constant-item"></div>
  <div class="fade-item" [@stateAnimation] *ngIf="expanded"></div>
</div>

<button (click)="toggleExpandedState()">Toggle Fade</button>

and the component animation:

  trigger('expansionTrigger', [
    state('1', style({
      width: '250px'
    })),
    state('0', style({
      width: '160px'
    })),
    transition('0 => 1', animate('200ms ease-in')),
    transition('1 => 0', animate('200ms ease-out'))
  ]),
  trigger('stateAnimation', [
    transition(':enter', [
      style({
        opacity: 0
      }),
      animate('200ms 350ms ease-in', style({
        opacity: 1
      }))
    ]),
    transition(':leave', [
      style({
        opacity: 1
      })
      animate('1s', style({
        opacity: 0
      }))
    ])
  ])
about 4 years ago · Santiago Trujillo
2 answers
Answer question

0

In hopes to save others the frustration, it looks like it is a bug with Angular 4.

There are currently two open issues on Github that appear to be pretty closely related:

https://github.com/angular/angular/issues/15798

https://github.com/angular/angular/issues/15753

Update

According to the github issue, the animation bug won't be fixed to work as it once did in Angular2. Instead query() and animateChild() are being introduced. The new animation features are available as of 4.2.0-rc2.

In summary:

Component Definition

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <button (click)="toggle()">Toggle</button>
      <div *ngIf="show" @ngIfAnimation>
        <h3 @easeInOut>I'm inside ngIf</h3>
      </div>
    </div>
  `,
animations: [
  trigger('ngIfAnimation', [
    transition(':enter, :leave', [
      query('@*', animateChild())
    ])
  ])
  trigger('easeInOut', [
    transition('void => *', [
        style({
            opacity: 0
        }),
        animate("1s ease-in-out", style({
            opacity: 1
        }))
    ]),
    transition('* => void', [
        style({
            opacity: 1
        }),
        animate("1s ease-in-out", style({
            opacity: 0
        }))
    ])
  ])
]]

})
export class App {
  name:string;
  show:boolean = false;

  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }

  toggle() {
    this.show = !this.show;
  }
}

There is a working example available here: https://embed.plnkr.co/RJgAunJfibBKNFt0DCZS/

about 4 years ago · Santiago Trujillo Report

0

here is what you'll need to do:

plnkr here: https://plnkr.co/edit/AQEVh3GGc31ivQZMp223?p=preview

remove *ngIf="expanded" use [@stateAnimation]="expanded"

replace your stateAnimate trigger with this:

trigger('stateAnimation', [
          state('1', style({ opacity: 0 })),
          state('0', style({opacity: 1})),
          transition('0 => 1', animate('200ms ease-in')),
          transition('1 => 0', animate('200ms ease-out'))
        ])

here is the full code:

//our root app component
import {Component, NgModule, VERSION, 
  Output,
  trigger,
  state,
  style,
  transition,
  animate,
} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@Component({
  selector: 'my-app',
  template: `
    <div class="container" [@expansionTrigger]="expanded">
      <div class="constant-item"></div>
      <div class="fade-item" [@stateAnimation]="expanded"></div>
    </div>

    <button (click)="toggleExpandedState()">Toggle Fade</button>
  `,
  animations: [
    trigger('expansionTrigger', [
      state('1', style({ width: '250px' })),
      state('0', style({width:'160px'})),
      transition('0 => 1', animate('200ms ease-in')),
      transition('1 => 0', animate('200ms ease-out'))
    ]),
    trigger('stateAnimation', [
      state('1', style({ opacity: 0 })),
      state('0', style({opacity: 1})),
      transition('0 => 1', animate('200ms ease-in')),
      transition('1 => 0', animate('200ms ease-out'))
    ])
  ]
})
export class App {
  expanded = true;

  toggleExpandedState() {
    this.expanded = !this.expanded;
  }

  constructor() {
  }
}

@NgModule({
  imports: [ BrowserModule, BrowserAnimationsModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}
about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!