voidで表示/非表示時のアニメーションを指定
HTML要素の表示/非表示が切り替わる時のアニメーションは、非表示状態を表す「void」を利用して、リスト5のように記述します。
transition("void => default", ...), // 非表示からdefault状態への切り替え transition("default => void", ...) // default状態から非表示への切り替え
[補足]voidのエイリアス
「"void => *"」(非表示から任意の状態への切り替え)、「"* => void"」(任意の状態から非表示への切り替え)は、それぞれ「":enter"」「":leave"」とも記述できます。
voidを利用したアニメーションの指定について、図3のサンプルで説明します。画面上部の「表示する」チェックボックスをチェックすると、要素がアニメーションしながら表示され、チェックを外すとアニメーションしながら画面から消えます。
未選択(default)状態で表示/非表示を行うアニメーション記述はリスト6です。
// 非表示→未選択:右にスライドしつつフェードイン ...(1) transition("void => default", [ style({ opacity:0, transform:"translateX(-100px)" }), animate("500ms ease-out") ]), // 未選択→非表示:右にスライドしつつフェードアウト ...(2) transition("default => void", [ animate("500ms ease-in", style({ opacity:0, transform:"translateX(100px)" }) ) ]),
opacity(透明度)とtranslateX(X方向の平行移動)を指定して、フェードイン・フェードアウトと横移動アニメーションを指定します。(1)のアニメーション終了時、(2)のアニメーション開始時のスタイルは指定されていないので、その時点の状態(ここではdefault)のスタイルが適用されます。
なお、選択(selected)状態の場合は、未選択状態とは別のアニメーション(フェードイン/アウトしつつ拡大/縮小する)が設定されています。詳細はサンプルコードを参照してください。
[補足]アニメーションの開始/終了イベント
アニメーションさせるHTML要素の属性をリスト7のように記述すると、アニメーション開始/終了時にイベントを受け取ることができ、イベント変数$eventに渡されるAnimationEventクラスのオブジェクトから、アニメーション前後の状態の名前や、アニメーション時間を取得可能です。
[@myanimation]="innerState" (@myanimation.start)="animStart($event)" ...アニメーション開始イベント (@myanimation.done)="animDone($event)" ...アニメーション終了イベント
詳細は、図3のサンプルをもとに、イベントを受け取るように変更したサンプル(003a_anim3_event)を参照してください。
画面表示後に定まるプロパティ値を自動計算
HTML要素の高さや幅のように、画面に表示して初めて値が決まるプロパティは、アニメーションで指定するときに、事前に値を確定できません。この場合、プロパティに「*」を指定すると、表示後に決まった値を自動で設定してくれます(Automatic property calculationと呼ばれる機能です)。
例として、表示時に高さ(heightプロパティ)を0から変化させる、図4のサンプル(004_anim4)を説明します。
このアニメーション指定はリスト8です。アニメーション前のheightは0ですが、(1)のようにアニメーション後のheightを「*」と指定すると、要素が画面に描画されたときの高さが自動で設定されます。
transition("void => *", [ style({ height:0 }), animate("500ms ease-out", style({ height:"*" // 高さを具体値ではなく「*」と指定できる ...(1) })) ]),
複雑なアニメーションを実現するkeyframesとgroup
Angularのアニメーション機能では、複数のアニメーションを組み合わせて、より複雑なアニメーションを作れます。ダウンロードできるサンプル(005_anim5)では、表示時に「keyframes」、非表示時に「group」の機能を使って、複雑なアニメーションを実現しています。実際に動作させて、アニメーションを確認してみてください。
アニメーションを順番に実行するkeyframes
keyframesは、複数のアニメーションを順番につないで1つのアニメーションにする方法です。keyframesを使ったアニメーション指定例をリスト9に示します。
transition("void => *", [ style({ opacity:1 }), animate("1s ease-out", keyframes([ // キーフレーム指定 ...(1) // 開始時点(offset=0) ...(2) style({backgroundColor:"#2aff2a", transform:"scale(0)", offset:0}), // 全体の70%まで進んだ時点(offset=0.7) ...(3) style({backgroundColor:"#ffff00", transform:"scale(1.2)", offset:0.7}), // 終了時点(offset=1) ...(4) style({backgroundColor:"#80b3ff", transform:"scale(1.0)", offset:1.0}), ])) ]),
animateの第2引数に、(1)のkeyframesでstyleの配列を指定します。styleの配列には、表示内容のほか、「アニメーション全体のどの位置に対応するスタイルか」を表すoffsetを、アニメーション開始時点を0、終了時点を1として指定します。この例ではoffset=0(開始時点)で(2)、offset=0.7(全体の70%まで進んだ時点)で(3)、offset=1(終了時点)で(4)のスタイルが適用されるので、色が変わりつつ0倍から1.2倍まで拡大後、さらに別の色に変わりつつ元の大きさ(1倍)に戻るアニメーションになります。
アニメーションを並列に実行するgroup
groupは、アニメーション時間や遅延が異なる複数のアニメーションを並列に同時実行する方法です。groupを使ったアニメーション指定例をリスト10に示します。
transition("* => void", [ style({ opacity:1 }), group([ // グループ指定 ...(1) // アニメーション1:1秒で半分に縮小 ...(2) animate("1s ease-in", style({ transform:"scale(0.5)" }) ), // アニメーション2:0.5秒待った後、1秒で透明に ...(3) animate("1s 0.5s linear", style({ opacity:0 }) ) ]) ])
transitionの第2引数に、(1)のgroupメソッドでanimateの配列を指定します。ここでは1秒間で半分に縮小するアニメーション(2)と、0.5秒待った後で、1秒で透明にするアニメーション(3)が並列で実行されます。
まとめ
本記事では、Angularで利用できるアニメーションの機能について説明しました。Web Animations APIが提供するアニメーション機能を、Angularの一部として利用できます。適切なアニメーションを設定すれば、Webページ自体の使い勝手を向上させられるでしょう。