どうも、らこです。 Angular 2の勉強会で出た質問でアニメーションのことがあったので、試してみたら問題なく動いたので使い方を紹介します。
はじめに
Angular 2のメインパッケージに含まれているのはangular2/animate
モジュールです。これはもう実用段階のAPIです。
それとは別に、ngAnimate
というプロジェクトも動いており、これはアノテーションベースでアニメーションを宣言的に記述できるようにしようというものです。まだ全然出来てないのでいまは使えませんがデザインドキュメントはみることができます。
Animations for Angular 2 Beta - Google ドキュメント
今回紹介するのは前者の今使える方です。
完成形
マウスオーバーで背景を指定された色に変更するアニメーションが動くディレクティブを書きました。
いろいろごちゃ混ぜですが動くサンプルはここにあります
import {Directive, Input, HostListener, AfterViewInit} from "angular2/core";
import {AnimationBuilder} from "angular2/animate";
@Directive({
selector: "[egAnimate]"
})
export class AnimateDirective implements AfterViewInit {
@Input() color: string;
private originalColor: string;
constructor(private animate: AnimationBuilder) {
}
ngAfterViewInit(): any {
this.color = this.color || "red";
}
@HostListener("mouseover", ["$event.target"])
onMouseOver(el: HTMLElement) {
this.originalColor = el.style.color;
return this.animate.css()
.setFromStyles({
"background-color": this.originalColor,
})
.setToStyles({
"background-color": this.color,
})
.setDuration(1000)
.start(el);
}
@HostListener("mouseleave", ["$event.target"])
onMouseLeave(el: HTMLElement) {
return this.animate.css()
.setFromStyles({
"background-color": this.color
})
.setToStyles({
"background-color": this.originalColor
})
.setDuration(1000)
.start(el);
}
}
本稿では@Input
や@HostListener
、AfterViewInit
については省略します。
準備
angular2/animate
はAngular 2本体に同梱されているので、単純にimportするだけでいいです。
import {AnimationBuilder} from "angular2/animate";
AnimationBuilder
は特にproviderを書かなくてもComponentかDirectiveのコンストラクタなら最初からDIできるようになっています。
constructor(private animate: AnimationBuilder) {
}
AnimationBuilderの使い方
AnimationBuilder
は、アニメーションを手続き的に組み立てるためのAPIです。
アニメーションを組み立てるには、まず初めにcss()
関数を呼び出し、CSSアニメーションの組み立てを始めます。
(おそらく将来的にはCSS以外にもなんかサポートするのかもしれません)
this.animate.css()
css()
関数の戻り値はCssAnimationBuilder
です。CssAnimationBuilder
は以下のような機能でアニメーションを組み立てられます。
- クラスを追加する
- クラスを除去する
- スタイルをセットする
- アニメーションの時間を設定する
- アニメーションが始まるまでの遅延時間を設定する
- アニメーションが終わった時にコールバックを受け取る
クラスを追加する・削除する
動的にクラスを追加するにはaddClass
関数、またはaddAnimationClass
関数を使います。
addClass
関数はアニメーションの開始時にクラスを追加するだけです。addAnimationClass
関数はそれに加えてアニメーションが終了した時に自動でそのクラスを除去します。
animate.css()
.addClass("some-class")
.addAnimationClass("some-temporary-class")
スタイルをセットする
動的にCSSのスタイルを変更するにはsetStyles
、setFromStyles
、setToStyles
の3つの関数を使います。
setStyles
はアニメーション開始時にセットする初期のスタイルと、終了時にセットするスタイルを一度に設定できます。
animate.css()
.setStyles({
"background-color": "white",
},{
"background-color": "red",
})
setFromStyles
とsetToStyles
は初期スタイルと終了スタイルを個別に設定できるAPIです。
animate.css()
.setFromStyles({
"background-color": "white",
})
.setToStyles({
"background-color": "red",
})
アニメーションの時間を設定する
setDuration
関数でアニメーションの開始から終了までの時間を設定します。具体的にはCSSのtransition-duration
が設定されます。
animate.css()
.setDuration(1000)
アニメーションの開始までの遅延時間を設定する
setDelay
関数でアニメーションの開始までの時間を設定します。具体的にはCSSのtransition-delay
が設定されます。
animate.css()
.setDelay(1000)
アニメーションを開始する
CssAnimationBuilder
でアニメーションを組み立て終わったら、start()
関数でアニメーションを開始します。start()
関数にはHTMLElement
型のオブジェクトを渡します。
this.animate.css()
.setFromStyles({
"background-color": this.originalColor,
})
.setToStyles({
"background-color": this.color,
})
.setDuration(1000)
.start(el)
start()
関数が実行された瞬間からアニメーションが開始します。
アニメーションの終了でコールバックを受け取る
start()
関数の戻り値はAnimation
型ですが、Animation
は内部でPromiseを持っているので、終了時に処理を実行できます。onComplete()
関数にコールバック関数を渡せばアニメーション終了時に一度だけ呼びだされます
this.animate.css()
.setFromStyles({
"background-color": this.originalColor,
})
.setToStyles({
"background-color": this.color,
})
.setDuration(1000)
.start(el)
.onComplete(()=> {
console.log("animated!")
});
まとめ
angular2/animate
めっちゃ良いので使いましょう。setTimeout
とRenderer
で頑張るのやめよう!