JavaScriptとCSSアニメーションの連携
CSS Animationsの基本的な書き方が分かったら、実際にランナーを走らせてみましょう。
Handy Stadiumの走塁アニメーションは、ランナーにアニメーション用のclass名を割り当てることで実現しています。たとえば、ホームから1塁へ走塁するときはランナーに「first」classを付与し、「first」classではアニメーションを定義したkeyframes「toFirst」を実行します。アニメーションにかける時間や回数は塁に関係なく共通ですので、共通設定用のclass「runner」で定義し、ランナーに付与します。
以下はホームから1塁へ走塁するときのCSSです。
@-webkit-keyframes toFirst {
from { /* アニメーションの開始地点 */
top: 251px;
left: 216px;
}
to { /* アニメーションの終了地点 */
top: 185px;
left: 336px;
}
}
/* 中略 */
/* ランナーの共通設定項目 */
.runner {
/* アニメーションsetting */
-webkit-animation-timing-function: ease;
-webkit-animation-duration: .6s; /* アニメーションにかける時間 */
-webkit-animation-iteration-count: 1; /* 1回だけアニメーションする */
position: absolute;
}
.first {
-webkit-animation-name: toFirst;
top: 185px; /* 終了地点のtop */
left: 336px; /* 終了地点のleft */
background-position: 0 0 !important; /* Spriteの画像位置指定 */
}
/* 省略 */
このCSSでは、ランナーを以下のように移動させています。
ランナーのキャラクター画像は、各塁間を走塁中のときと待機中とで右のような6種類のバリエーションを持たせています。キャラクターはCSS Sprite画像として1枚にまとめておき、ステータスに応じてclassを変更することで、CSSで表示する画像を切り替えます。
class名 | ステータス |
---|---|
classなし | バッターボックスに立っている |
first | 1塁へ走塁している |
second | 2塁へ走塁している |
third | 3塁へ走塁している |
home | ホームへ走塁している |
wait | 待機している |
ただし、この表のように、単純に現在の塁から次の塁へランナーを移動させるときはclassを変更するだけでいいのですが、実際には2ベースヒットやホームランの場合など、次の塁以上へ移動させたい場合もあります。
そこで、CSSでは各塁から次の塁へ走塁する場合だけを定義しておき、どこからどこへ走塁するかはJavaScriptで制御します。JavaScriptで、1塁先への走塁が完了したタイミングを取り、次の塁へランナーを移動させるclassを付け直すわけです。
CSS Animationにはアニメーションが終わったことをキャッチするための「webkitAnimationEnd」というイベントがありますが、今回はすべてタイマーを利用したキューで処理しています。
たとえばホームから2塁へ走塁する場合の処理は、
ホーム
↓走塁(300msかかる)
1塁
↓走塁(300msかかる)
2塁
という流れですが、JavaScriptで300ms待ってから処理を実行しようとすると、setTimeout()を使うしかありません。走塁のイベントは非同期通信で発火するため走塁のタイミングがずれてしまい、setTimeout()で処理するには複雑です。そこで、Handy Stadiumではキュー関数を用意して、順番に実行する処理をキューで管理します。
アニメーションが完了するまでの待ち時間は、実行されるCSSアニメーションの「animation-duration」を参照することで求められます。animation-durationの値はgetComputedStyleから参照できます。
this.waitTime = this.player.css()["-webkit-animation-duration"];
// .css()を実行すると、ライブラリーが.getComputedStyle()の値を返す
alert(this.waitTime);
実行結果は以下のようになります。
0.6000000238418579s
このように「-webkit-animation-duration」を参照すると、CSSで指定した「-webkit-animation-duration」の値が得られます。JavaScriptで扱うためにms(ミリ秒)に変換します。
this.waitTime = this.player.css()["-webkit-animation-duration"];
this.waitTime = parseFloat(this.waitTime) * 1000;