andy
andy

Reputation: 129

Fade list items in and out when items change in angular 6

I have a list of products which is controlled by a list of categories so when a category is clicked it displays all the products within it

I want to animate this list so that when the category is clicked each list item fades up from +50% to 0 staggered

If a different category is clicked i want the current products list to fade up again but this time from 0 to -50% staggered and then the new items from +50% to 0 staggered

I currently have this

<ul @listInOut>
 <li *ngFor="let product of products;">
   //item
 </li>
<ul>

    trigger('listInOut', [
      transition(':enter', [
        query('li', [
          style({ opacity: 0, transform: 'translateY(50%)' }),
          stagger(100, [
            animate('1s ease', style({ opacity: 1, transform: 'translateY(0)' }))
          ])
        ])
      ]),
      transition(':leave', [
        query('li', [
          style({ opacity: 1, transform: 'translateY(0)' }),
          stagger(100, [
            animate('.5s ease', style({ opacity: 0, transform: 'translateY(-50%)' }))
          ])
        ])
      ])
    ])

the first time the category is clicked the animation works as it should but clicking other categories doesn't work at all

Upvotes: 0

Views: 1415

Answers (2)

&#216;rjan
&#216;rjan

Reputation: 2879

I think @listInOuthas to be on the tag that contains the *ngForloop. I've tried placing you animation in a component like this, and it works:

Result

Example

Here follows the code:

HTML

<div @listInOut *ngFor="let item of list" class="item">
  <ul>
    <li>{{ item }}</li>
  </ul>
</div>

<button (click)="addItem()">Add Item</button>

app.component.ts

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  animations: [
    trigger('listInOut', [
      transition(':enter', [
        query('li', [
          style({ opacity: 0, transform: 'translateY(50%)' }),
          stagger(100, [
            animate('1s ease', style({ opacity: 1, transform: 'translateY(0)' }))
          ])
        ])
      ]),
      transition(':leave', [
        query('li', [
          style({ opacity: 1, transform: 'translateY(0)' }),
          stagger(100, [
            animate('.5s ease', style({ opacity: 0, transform: 'translateY(-50%)' }))
          ])
        ])
      ])
    ])],
})
export class AppComponent {
  list: string[] = [];

  constructor() {}

  addItem() {
    this.list.push('item')
  }
}

Remember to import the following module inn app.modules.ts as well: BrowserAnimationsModule

Upvotes: 1

rpajo
rpajo

Reputation: 71

I think you need to tell your component when to re-animate the elements. Because the trigger is set to the list element (and not the list items), the items don't get animated aside from the first time (:enter on load).

Take a look at the angular's example page for the animations. I think the filter/stagger solves a similar problem.

Upvotes: 1

Related Questions