Reputation: 29199
After a bit of a struggle I finally have staggering animations working
DEMO (The code was originally copied from here)
The relevant animation code is
trigger('cardAnimation', [
// Transition from any state to any state
transition('* => *', [
// Initially the all cards are not visible
query(':enter', style({ opacity: 0 }), { optional: true }),
// Each card will appear sequentially with the delay of 300ms
query(
':enter',
stagger('300ms', [
animate(
'.5s ease-in',
keyframes([
style({ opacity: 0, transform: 'translateY(-50%)', offset: 0 }),
style({
opacity: 0.5,
transform: 'translateY(-10px) scale(1.1)',
offset: 0.3,
}),
style({ opacity: 1, transform: 'translateY(0)', offset: 1 }),
])
),
]),
{ optional: true }
),
// Cards will disappear sequentially with the delay of 300ms
query(
':leave',
stagger('300ms', [
animate(
'500ms ease-out',
keyframes([
style({ opacity: 1, transform: 'scale(1.1)', offset: 0 }),
style({ opacity: 0.5, transform: 'scale(.5)', offset: 0.3 }),
style({ opacity: 0, transform: 'scale(0)', offset: 1 }),
])
),
]),
{ optional: true }
),
]),
]),
As you can see in the demo, adding and removing is animated. What I don't understand is, that this same logic (removing/adding) is not applied when I replace a card item in the list. I would expect that both the :leave
and then the :enter
would trigger.
Any suggestion what I missed in my animation?
Upvotes: 0
Views: 130
Reputation: 1806
Of course it doesn't work. The animation is triggered, if the length of the array changes. But clicking on the replace button updates only a specific element.
Change the onReplace
function like this:
this.cards.splice(index, 1);
setTimeout(() => this.cards.splice(index, 0, `Card ${++this.index}`));
The setTimeout
is needed, because deleting and inserting has to be done in a separate execution context, in order to let angular detect the change in the array size.
Upvotes: 1