Skip to content

Instantly share code, notes, and snippets.

@marcorinck
Last active February 13, 2018 13:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcorinck/7c865115dca4e06f15d2a253e76d2f6a to your computer and use it in GitHub Desktop.
Save marcorinck/7c865115dca4e06f15d2a253e76d2f6a to your computer and use it in GitHub Desktop.
An example when you need dynamic properties inside of an angular animation and need to implement the animation in ts code and not in the animation DSL
<card (click)="clicked()">
<card-content>
<card-title [ngStyle]="{'font-size': fontsize}">{{itemDetails.name}}</ion-card-title>
<icon [svgIcon]="itemDetails.icon" [style.height.px]="iconWidthHeight"
[style.width.px]="iconWidthHeight" ></icon>
</card-content>
</card>
import {animate, AnimationBuilder, AnimationPlayer, style, OnChanges} from "@angular/animations";
import {Component, ElementRef, HostBinding, Input} from "@angular/core";
@Component({
templateUrl: 'animated-item.component.html',
selector: 'animated-item',
})
export class AnimatedItemComponent implements OnChanges {
itemPlayer: AnimationPlayer;
iconPlayer: AnimationPlayer;
titlePlayer: AnimationPlayer;
leftPosition: number;
topPosition: number;
fontsize: string;
iconWidthHeight = 0;
@Input()
itemDetails: MyCustomDetailClass;
@HostBinding("style.width.px")
width: number;
@HostBinding("style.height.px")
height: number;
constructor(private el: ElementRef, private animationBuiler: AnimationBuilder) {}
animate() {
//... calculate Heights,widths and all other parameters, details omitted bc clarity
this.destroyPlayers();
const itemAnimation = this.createItemAnimation(width, height, leftPosition, topPosition);
const iconAnimation = this.createIconAnimation(iconWidthHeight);
const titleAnimation = this.createTitleAnimation(fontsize);
this.itemPlayer = itemAnimation.create(this.el.nativeElement);
this.iconPlayer = iconAnimation.create(this.icon.nativeElement);
this.titlePlayer = titleAnimation.create(this.title.getNativeElement());
this.itemPlayer.play();
this.iconPlayer.play();
this.titlePlayer.play();
this.itemPlayer.onDone(() => {
//a CustomEvent not only bubbles to the immediate (angular) parent element but can bubble up to the root element
//this event happens when the animation is done
const ev = new CustomEvent("animationDone", {bubbles: true});
this.el.nativeElement.dispatchEvent(ev);
})
}
clicked() {
//a CustomEvent not only bubbles to the immediate (angular) parent element but can bubble up to the root element
//this event happens when the component/item is clicked and triggers the animatin (implementation detail)
const ev = new Event("wasClicked", {bubbles: true, cancelable: true});
this.el.nativeElement.dispatchEvent(ev);
}
ngOnChanges() {
this.animate();
}
private createTitleAnimation(fontsize: string) {
return this.animationBuiler.build([
style({
"font-size": this.fontsize,
}),
animate(`500ms ${this.delay}ms cubic-bezier(.35, 0, .25, 1)`, style({
"font-size": fontsize
}))
]);
}
private createIconAnimation(iconWidthHeight: number) {
return this.animationBuiler.build([
style({
width: this.iconWidthHeight,
height: this.iconWidthHeight,
}),
animate(`500ms ${this.delay}ms cubic-bezier(.35, 0, .25, 1)`, style({
width: iconWidthHeight + "px",
height: iconWidthHeight + "px",
}))
]);
}
private createItemAnimation(width: number, height: number, leftPosition: number, topPosition: number) {
return this.animationBuiler.build([
style({
width: this.width,
height: this.height,
transform: `translate3d(${this.leftPosition}px, ${this.topPosition}px, 0)`
}),
animate(`500ms ${this.delay}ms cubic-bezier(.35, 0, .25, 1)`, style({
width: width + "px",
height: height + "px",
transform: `translate3d(${leftPosition}px, ${topPosition}px, 0)`
}))
]);
}
//when there is already an animation running you have to stop/destroy it first, before you create a new one
private destroyPlayers() {
if (this.itemPlayer) {
this.itemPlayer.destroy();
}
if (this.iconPlayer) {
this.iconPlayer.destroy();
}
if (this.titlePlayer) {
this.titlePlayer.destroy();
}
}
}
<animated-item *ngFor="let item of items; let i = index" [itemDetails]="item"
(wasClicked)="selectItemSoAnimationWillBeTriggered(item)">
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment