4

I'm a real newbie in angular animations, never had to use anything else than simple transitions until now. I think what i'm looking for is very simple, yet I can't figure out what I'm missing.

I have an array displayed in template with ngFor. I can insert or delete elements of this array with a simple button click. Right now I have a simple animation taken from the Angular doc to change the opacity of inserted or deleted element :

trigger(
      'inOutAnimation', 
      [
        transition(
          ':enter', 
          [
            style({ opacity: 0 }),
            animate('1s ease-out', style({ opacity: 1 }))
          ]
        ),
        transition(
          ':leave', 
          [
            style({ opacity: 1 }),
            animate('1s ease-in', style({ opacity: 0 }))
          ]
        )
      ]
    )

What I need now is to create an animation to move surrounding elements to their new position on the page. I don't want the existing elements to just pop on their new positions. How can I do this ? Because it looks like the trigger inOutAnimation only targets the added or deleted element. How to manage transitions of other array elements ? Also I was always using moving transitions on elements with known initial and final positions. Now with an array the positions of elements are dynamic.

Your help would be gladly appreciated

EDIT:

https://stackblitz.com/edit/angular-szt5hm

In this example I would like when I click on Add that the div 3 slides/moves to position of 4 instead of just poping. same for 4 to 5 etc.

3
  • Can you provide a stackblitz that shows what exactly you are looking for? Commented Apr 30, 2020 at 6:06
  • angular material cdks drap and drop` module here helps you a lot Commented Apr 30, 2020 at 6:25
  • @MikeS. stackblitz update Commented Apr 30, 2020 at 6:35

1 Answer 1

2

You could use keyframes to define an animation similar to CSS. Try the following

Controller

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ],
  animations: [
    trigger("inOutAnimation", [
      state("in", style({ opacity: 1 })),
      transition(":enter", [
        animate(
          300,
          keyframes([
            style({ opacity: 0, offset: 0 }),
            style({ opacity: 0.25, offset: 0.25 }),
            style({ opacity: 0.5, offset: 0.5 }),
            style({ opacity: 0.75, offset: 0.75 }),
            style({ opacity: 1, offset: 1 }),
          ])
        )
      ]),
      transition(":leave", [
        animate(
          300,
          keyframes([
            style({ opacity: 1, offset: 0 }),
            style({ opacity: 0.75, offset: 0.25 }),
            style({ opacity: 0.5, offset: 0.5 }),
            style({ opacity: 0.25, offset: 0.75 }),
            style({ opacity: 0, offset: 1 }),
          ])
        )
      ])
    ])
  ]
})
export class AppComponent  {
  elements = [
    { value: 1, background: 'green' },
    { value: 2, background: 'red' },
    { value: 3, background: 'blue' },
    { value: 4, background: 'yellow' },
    { value: 5, background: 'pink' }
  ]

  add() {
    this.elements.splice(2, 0, { value: 6, background: 'violet' });
  }

  remove() {
    this.elements.splice(2, 1);
  }
}

Template

<div class="container">
    <div [@inOutAnimation]="'in'" *ngFor="let element of elements" [ngStyle]="{ 'background-color': element.background }">
        {{ element.value }}
    </div>
</div>
<button (click)="add()">Add</button>
<button (click)="remove()">Remove</button>

The animation needs to be bound to the element with the *ngFor to use the :enter and :leave.

I've modified your Stackblitz.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer, but I don't know how this can help me for animating the others array elements. Other elements impacted by the add or delete need to move/slide to their new position
Animations can be simplified like: animations: [ trigger('inOutAnimation', [ state('in', style({ opacity: 1 })), transition(':enter', [style({ opacity: '0' }), animate('.5s ease-out', style({ opacity: '1' }))]), transition(':leave', [style({ opacity: '1' }), animate('.5s ease-out', style({ opacity: '0' }))]), ]), ]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.