I'm subscribed to a Firebase real-time database so that when I submit something to it, it immediately renders in the view without any need for jQuery or ajax.
I'd like to animate the rendering of such elements, so that when a new element is added to the DOM its div
's background-color
is green and slowly fades away. What I don't want is for all div
s of this class to perform this animation on load.
I know how to do the former:
@keyframes green-fade {
0% {background: rgb(173, 235, 173);}
100% {background: none;}
}
.post-div {
animation: green-fade 5s ease-in 1;
}
But of course this animation happens for this class any time it's rendered, including on load.
I'm interested in the "Angular 2 way" to do this.
Since Angular 4.25 there's an easier way to do this: If you want to suppress an :enter animation on view initialization, just wrap it with the following animation:
template: `
<div [@preventInitialChildAnimations]>
<div [@someAnimation]>...</div>
</div>
`,
animations: [
trigger('preventInitialChildAnimations', [
transition(':enter', [
query(':enter', [], {optional: true})
])
]),
...
]
Add a trigger that checks the state of a item when it comes through the network. Here I'm triggering the animation when itemState
is new
.
trigger('itemState', [
transition('* => new', animate(5000, keyframes([
style({ backgroundColor: 'red', offset: 0 }),
style({ backgroundColor: '*', offset: 1.0 })
]))),
Give your trigger a reference to the state of your item, and set it to null when the animation finishes.
<div [@itemState]="someItem.itemState" (@itemState.done)="someItem.itemState=''">
Be sure to add an itemState
property to your posts so that you can flag them as new!
You can use the life cycle hook AfterViewInit to activate the animation after the initial view rendering has finished.
https://embed.plnkr.co/5l1kf5lMLEXSE8pNzqik/
@Component({
selector: 'my-app',
template: `
<div *ngFor="let item of items" [@greenFade]="animate ? 'in' : null">
{{item}}
</div>
<button (click)="addItem()">add</button>
`,
animations: [
trigger('greenFade', [
transition('void => in', [style({background: 'rgb(173, 235, 173)'}), animate('5s ease-in')])
])
]
})
class App implements AfterViewInit {
constructor(private cdRef: ChangeDetectorRef){}
items: String = ['Item','Item','Item'];
addItem(){
this.items.push('Item');
}
animate: boolean;
ngAfterViewInit(){
this.animate = true;
this.cdRef.detectChanges();
}
}
Easiest solution:
@Component({
selector: 'myComponent',
template: '<div [@.disabled]="disableAnimations" [@someAnimation]="someValue">',
animations: [trigger('someAnimation', [transition('* => *', [style({ transform: 'scale(1.1)' }), animate(250)])])]
})
export class MyComponent implements AfterViewInit {
disableAnimations: boolean = true;
constructor() {}
ngAfterViewInit(): void {
this.disableAnimations = false;
}
}
Reference: https://angular.io/api/animations/trigger (scroll to "disable animations")
来源:https://stackoverflow.com/questions/42847920/animation-for-newly-rendered-elements-but-not-on-page-load