AngularのAnimate
はじめに
前回に続いてAngular.jsのお話。
昔Angular.jsの弱点としてアニメーションが挙げられていた気がしていたので(別のものと混同している恐れもあります)、
ちょこっと調べてみたところver.1.14位からちゃんと対応されていました。
というわけで今回は、公式ドキュメントを中心に試してみたことをメモることにします。
あ、ちなみに扱うのはver.2系だけです。
アニメーションさせてみる
まずはボタンをクリックした時に、ボタンのサイズ変更、及び背景色を変更するサンプルを試してみました。
前回作成したプロジェクトに、「ng g component gui-anime」でコンポーネントを追加し、それをあれこれいじっています。
まずはコードから。
Htmlにアニメーションのターゲット兼トリガーとなるボタンを追加し、
Typescript側でアニメーションとアニメーション開始のトリガーとなる要素(State)を作成します。
gui-anime.component.html
< p> gui-anime works! < /p> < button [@buttonState]="state" (click)="onAnimeButtonClicked()">Anime< /button>
gui-anime.component.ts
import { Component, Input, trigger, state, style, transition, animate, OnInit } from '@angular/core'; @Component({ selector: 'app-gui-anime', templateUrl: './gui-anime.component.html', styleUrls: ['./gui-anime.component.css'], animations: [ trigger('buttonState', [ state('inactive', style({ backgroundColor: '#eee', transform: 'scale(1)' })), state('active', style({ backgroundColor: '#cfd8dc', transform: 'scale(1.5)' })), transition('inactive => active', animate('100ms ease-in')), transition('active => inactive', animate('100ms ease-out')) ]) ] }) export class GuiAnimeComponent implements OnInit { public state: string; constructor() { } ngOnInit() { this.state = "inactive"; } private onAnimeButtonClicked(){ this.state = (this.state === "active")? "inactive": "active"; } }
イベント
Angularではクリックなどのイベントは()で囲まれます。
今回はボタンクリックのイベントを取得したいため、gui-anime.component.htmlで「(click)」を設定しています。
(click)="onAnimeButtonClicked()"
アニメーションのトリガーとなる要素(State)の指定と値の変更
上記のコードでは、クリックしたらアニメーションが始まるのではなく、gui-anime.component.tsで設定している「buttonState」が特定の値(inactive、active)に変更された場合に開始されるようになっています。
これをボタンに設定して、クリックイベントで「state」の中身を入れ替える、という処理を行っています。
[@buttonState]="state"
[@〜]とすることで、コンポーネントの持つ要素(今回はアニメーションのトリガーとなる「buttonState」)の「state」との関連付けができるようです。
[]は下記のPropertyBindingか?とも思うのですが、確信が持てず。。。
この辺りは追って調べてみることにします。
アニメーション
さて、今回のメインであるアニメーションです。
animations: [ trigger('buttonState', [ state('inactive', style({ backgroundColor: '#eee', transform: 'scale(1)' })), state('active', style({ backgroundColor: '#cfd8dc', transform: 'scale(1.5)' })), transition('inactive => active', animate('100ms ease-in')), transition('active => inactive', animate('100ms ease-out')) ]) ]
ここでは2つのstateが指定されており、
先ほど登場した「buttonState」の値が「inactive」または「active」(それぞれのstateの第一引数)に変更された時に、
第二引数でそれぞれ指定しているCSSの値(背景色、スケール値)が適用される内容となっています。
で、その後ろに連なる2つのtransitionによって、「inactive」から「active」またはその逆への変化がアニメーションで繋げられる、という処理が行われます。
transitionの第二引数にてアニメーションの時間と後述するEaseTypeが指定されています。
EaseType
transitionで指定されているEaseType。
これを指定することで、アニメーション(今回は拡大・縮小)する速度が一定ではなく最初だけゆっくり(ease-in)や、最後だけゆっくり(ease-out)といった変化をつけることができます。
UnityのTween系でも登場しますね。
そちらでは覚えきれない位たくさんの種類のEaseTypeから目的に合致したものを利用することができます。
ではAngularではどうかというと、実は今回使っているアニメーション、というのはAngular独自のものではなくCSSのアニメーションです。
で、CSSで使用できるものはというと、下記のみです。
- ease(デフォルト)
- linear(はじめから終わりまで一定)
- ease-in(最初だけゆっくり)
- ease-out(最後だけゆっくり)
- ease-in-out(最初と最後だけゆっくり)
- cubic-bezier()(カスタム)
SCSSなどであればEasing Function 早見表で紹介されているようなEaseTypeが使えるようなのですが、
CSSでは種類がかなり少ない(またはカスタムで作成する)ようです。
カスタムについては次回辺りためしてみたいと思います。
アニメーションの開始・終了イベント
複数のアニメーションを連続で実行したい、アニメーションの実行後に何か処理をしたい、といった場合に、それを検知するイベントが欲しいところ。
そのような場合は、クリックイベントのように「start」「done」イベントを設定します。
Start
< button [@buttonState]="state" 〜省略〜(@buttonState.start)="onAnimeStarted()">Anime< /button>
Done
< button [@buttonState]="state" 〜省略〜(@buttonState.done)="onAnimeFinished()">Anime< /button>
アニメーションのトリガーである「buttonState」に紐付けられていますね。
あとはクリックイベントと同じく、gui-anime.component.tsに「onAnimeStarted()」や「onAnimeFinished()」を追加するだけです。