Leverage the new Animation support in RC 5 to animate each item in an *ngFor list sequentially in Angular 2

I have a unique component that retrieves a list of items from the server and then displays that list using *ngFor in the template.

My goal is to add animation to the list display, with each item animating in one after the other.

I am experimenting with the following code:

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

@Component({
    selector: 'list-item',
    template: ` <li  @flyInOut="'in'">{{item}}</li>`,
    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 ListItemComponent {
    @Input() item: any;
}

and in my list component template this is how I am implementing it:

<ul>
    <li *ngFor="let item of list;">
     <list-item [item]="item"></list-item>
    </li>
</ul>

Currently, the entire list is displayed at once. However, I want the items to enter one by one with a smooth animation effect.

Answer №1

The documentation does not include stagger support for ngFor, but now there are animation.done events that enable the creation of staggered ngFor animations.

Check out StackBlitz demo

@Component({
  selector: 'my-app',
  template: `
    <ul>
    <li *ngFor="let hero of staggeringHeroes; let i = index"
        (@flyInOut.done)="doNext()"
        [@flyInOut]="'in'" (click)="removeMe(i)">
      {{hero}}
    </li>
  </ul>
  `,
  animations: [
  trigger('flyInOut', [
    state('in', style({transform: 'translateX(0)'})),
    transition('void => *', [
      animate(300, keyframes([
        style({opacity: 0, transform: 'translateX(-100%)', offset: 0}),
        style({opacity: 1, transform: 'translateX(15px)',  offset: 0.3}),
        style({opacity: 1, transform: 'translateX(0)',     offset: 1.0})
      ]))
    ]),
    transition('* => void', [
      animate(300, keyframes([
        style({opacity: 1, transform: 'translateX(0)',     offset: 0}),
        style({opacity: 1, transform: 'translateX(-15px)', offset: 0.7}),
        style({opacity: 0, transform: 'translateX(100%)',  offset: 1.0})
      ]))
    ])
  ])
]
})
export class App {
  heroes: any[] = ['Alpha', 'Bravo', 'Charlie', 'Delta', 'Echo', 'Foxtrot', 'Golf', 'Hotel', 'India'];

  next: number = 0;
  staggeringHeroes: any[] = [];

  constructor(){
    this.doNext();
  }

  doNext() {
    if(this.next < this.heroes.length) {
      this.staggeringHeroes.push(this.heroes[this.next++]);
    }
  }

  removeMe(i) {
    this.staggeringHeroes.splice(i, 1);
  }
}

Answer №2

In order to implement angular2 animations, I assigned a state property to each item in the iteration and then created a toggle function for the mouseover and mouseout events. This allowed each item to control its own animated state, making it easy to update as needed.

<li
   *ngFor="let item of itemsList"
   (mouseover)="toggleAnimation(item)"
   (mouseout)="toggleAnimation(item)"
>{{ item.name }}
  <div class="animation_wrapper" [@slideInOut]="item.state">
    <span class="glyphicon glyphicon-refresh"></span>
    <span class="glyphicon glyphicon-trash"></span>
  </div>
</li>

Answer №3

If you want to adjust the time between each item in a list, check out this code snippet. Simply change the file extension from .css to .scss for customization.

Here is an example: https://codepen.io/jhenriquez856/pen/baPagq

$total-items: 5;

body {
  font-family: sans-serif;
  background: #111;
  color: #fff;
}

ul {
  width: 300px;
  left: 50%;
  margin-top: 25px;
  margin-left: -150px;
  
  position: absolute;
}

li {
  position: relative;
  display: block;
  border: 1px solid hotpink;
  margin-bottom: 5px;
  padding: 10px;
  text-align: center;
  text-transform: uppercase;
  animation: fadeIn 0.5s linear;
  animation-fill-mode: both;
}

// Adjust delay for each List Item
@for $i from 1 through $total-items {
  li:nth-child(#{$i}) {
    animation-delay: .25s * $i;
  }
}

// Keyframe animation
@-webkit-keyframes fadeIn {
  0% {
    opacity: 0;
  }
  75% {
    opacity: 0.5;
  }
  100% {
    opacity: 1;
  }
}
<ul>
  <li>item 1</li>
  <li>item 2</li>
  <li>item 3</li>
  <li>item 4</li>
  <li>item 5</li>
</ul>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Implementing the click event in angular2-openlayers will display the information for the selected marker

Exploring Angular and Openlayers (3) is a new endeavor for me. Recently, I stumbled upon this open source library that conveniently wraps Openlayers within Angular. A straightforward question has come to mind: How can I detect when a user clicks on a gene ...

Setting input autofocus in a recursive Angular2 component

Currently, I am working on creating a tree view system similar to Workflowy for practice purposes. The simple version is operational; however, I am facing difficulty in setting the input focus when adding a new component. I have experimented with various ...

The ajv-based middy validator does not adhere to the specified date and time format

When it comes to validation, I rely on middy as my go-to package, which is powered by ajv. Below is an example of how I set up the JSON schema: serviceDate: { type: 'string', format: 'date-time' }, The structure o ...

What is the best way to retrieve an object within a class?

Exploring a Class Structure: export class LayerEditor { public layerManager: LayerManager; public commandManager: CommandManager; public tools: EditorTools; constructor() { this.commandManager = new CommandManager(); this.lay ...

Steps for deploying Angular 2 using grunt

I'm currently in the process of developing an Angular2 application and my goal is to utilize Grunt for deployment. However, upon running the deployed index.html file, I've encountered issues with my code not functioning as intended. The specific ...

Do I have to utilize npm packages?

As a newcomer to Node.js, I'm diving into the world of node features while working on an Angular 2 project. One thing I've noticed is that every plugin seems to be imported from the node_modules folder. This has me wondering - is it absolutely n ...

Receiving the [object HTMLInputElement] on the screen rather than a numerical value

I have an input box where a user can enter a number. When they click a button, I want that number to be displayed on the page. However, instead of seeing the number, I am getting the output as [object HTMLInputElement]. Below is my TypeScript code: let qu ...

How can you add a Git submodule without specifying a URL?

I am looking to integrate my Angular folder as a submodule into my primary directory. The Angular folder has already been initialized as a git repository. It is currently a local folder on my Windows machine with no URL. After successfully initializing gi ...

refreshing the existing component (when clicked) only if the routerlink is currently pointing to the same component

When I click on a link, I want it to take me back to the "/" route. This functionality is already working perfectly. <a routerLink="/">Login</a> However, if I am currently on the "/" route, I want the current component to be refreshed when I ...

Unleash the potential of a never-ending expansion for grid cells on Canvas

ts: templateStyle = { display: 'grid', 'grid-template-columns': 'calc(25%-10px) calc(25%-10px) calc(25%-10px) calc(25%-10px)', 'grid-template-rows': '150px auto auto', 'grid-gap ...

How to implement tree selection feature in Angular PrimeNG version 11.x on a tree component

I am currently working with primeng v11.x and utilizing p-tree to showcase hierarchy view with checkboxes. However, I would like to have this displayed within a dropdown similar to p-treeselect. Due to constraints, I am unable to upgrade primeng at the mom ...

Storing a value in a variable using ngFor in Angular 4

Here is the code snippet I am working with: <ng-container *ngFor="let item of items"> <div>{{item.subArray[0].attr1}}</div> <div>{{item.subArray[0].attr2}}</div> </ng-container> I am wondering if it's possible to ...

Using TypeScript with Vue and Pinia to access the store

Is it necessary to type the Store when importing it to TypeScript in a Pinia Vue project? // Component <p>{{ storeForm.firstName }}</p> // receiving an error "Property 'storeForm' does not exist on type" // Store ...

Obtain the current state of an Angular Material radio button that has been selected

I am currently working with an Angular Material mat-table that has columns for checkboxes and rows, using Material components for each. Extracting the selected state of the checkbox is straightforward with row.checked, as demonstrated below. However, I am ...

Steps for fixing the error message "Type 'Observable<string>' is not assignable to type 'Observable<{ userId: string; partyId: string; }>'"

Having some trouble with my Angular project. I have this code snippet in my getUser() method, but the compiler isn't happy about it and I can't seem to figure out what's wrong: public getUser(): Observable<{ userId: string; partyId: strin ...

A guide on incorporating ng2-canvas-whiteboard into your Ionic 3 project

I'm trying to implement the npm package ng2-canvas-whiteboard into my Ionic 3 app. I followed all the instructions on the npm page and here is my package.json: "dependencies": { "@angular/common": "4.0.2", "@angular/compiler": "4.0.2", ...

Show Data from API on Angular 6 Webpage

Hello everyone, I am a beginner in the world of frontend development and I'm currently facing a challenge with displaying API data in an Angular 6 application. I have managed to showcase values from the main level of the returned details, but I am str ...

Unable to send a function as props to a child component in TypeScript

Within my application, I have a parent component that holds a state and a setState function. This state and function are then passed down to a child component in order to retrieve values (such as input field data). When the function is triggered in the chi ...

Verifying whether the filter query will produce any matches

I'm currently working with a *ngIf statement and I need to show a specific message when the condition is not met. However, I'm facing difficulties in finding a way to achieve the opposite of the filtered result. Essentially, I want to display a m ...

Display a picture retrieved from a POST request using Angular and a Spring Boot backend

Recently, I've been delving into the world of HTTP requests. My latest task involves uploading an image from the client and sending it to the server using a POST request. When testing this process in Postman, everything works smoothly as I receive th ...