Reputation: 71
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.
Upvotes: 4
Views: 4155
Reputation: 31105
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.
Upvotes: 2