Issue
So, after avoiding getting my feet wet with Angular Animation, I wanted to finally try working with it. In theory, I like this a lot. But there seems to be odd behavior that doesn't seem to make sense to me.
animations: [
trigger('enterAnimation', [
transition(':enter', [
query(':self, td', [
style({ transform: 'translateX(100%)', opacity: 0 }),
stagger(100, [
animate(
'500ms',
style({
transform: 'translateX(0)',
opacity: 1,
'overflow-x': 'hidden',
})
),
]),
]),
]),
]),
trigger('rowAnimations', [ //NOTE: I need to include this, otherwise manually added items do not work
transition(':enter', [
style({ transform: 'translateX(100%)', opacity: 0 }),
query(':self', [
animate(
'500ms',
style({
transform: 'translateX(0)',
opacity: 1,
'overflow-x': 'hidden',
})
),
]),
]),
transition(':leave', [
query(':self', [
style({
transform: 'translateX(0)',
opacity: 1,
overflow: 'hidden',
width: '100%',
height: '*',
}),
animate('500ms', style({ transform: 'translateX(50%)', opacity: 0 })),
]),
]),
]),
],
The trigger animation enterAnimation
works perfectly fine with preloaded data. Animation is staggered and everything with the first load of items. However, without the trigger rowAnimations
on the :enter transition that I added and subsequently added item does not get rendered. I added the stackblitz for good measure.
EDIT: Solution:
<table [@tableAnimations]="items.length" id="customers">
<tr>
<th>Name</th>
<th>Country</th>
</tr>
<ng-container *ngFor="let o of items; let i = index">
<tr class="data" [@rowAnimations]>
<td>{{ o.Name }}</td>
<td>{{ o.Country }}</td>
</tr>
</ng-container>
</table>
Just as suggested in the solution by Andrei, we want to add a trigger that goes beyond the :enter
selector. And for that, it's simpler to bind to the array length. On its own, it's not doing much. Again, as suggested, that is being solved with the transition rule * <=> *
which means, ANY value bound to the trigger will trigger the animation.
transition('* <=> *', [
query('@rowAnimations', [stagger(100, [animateChild()])]),
]),
And without that transition rule, the row animation isn't triggered in a staggered fashion, but all in parallel. Makes sense, in retrospect.
Solution
The trigger
binding should change to trigger the trigger
. for example
[@enterAnimation]="items.length"
, and transition('* <=> *'
. In your case when it enters - it is just executed once, as expected.
second: you don't really need query(':self')
. it can be ommited
and third: you can animateChild()
to control animation on the higher level and describe animation for the element at the element level
trigger('enterAnimation', [
transition(':enter', [
query('@rowAnimations', [
stagger(100, [
animateChild()
])
])
])
....
trigger('rowAnimations', [
transition(':enter', [
style({ transform: 'translateX(100%)', opacity: 0 }),
animate(
'500ms',
style({
transform: 'translateX(0)',
opacity: 1,
'overflow-x': 'hidden',
})
),
]),
this way animation is staggered at parent->:enter and then every element enter only child animation is triggering
Answered By - Andrei
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.