1. CSSアニメーション
CSSアニメーションはJSアニメーションに対して、主に2つの利点があります:
- 滑らかさ
レンダリングエンジンがフレームスキップ(frame-skipping)などの技術を利用して、パフォーマンスを可能な限り滑らかに保つことができるためです。
- ブラウザによる性能最適化
アニメーションのシーケンスをブラウザの制御に任せることで、ブラウザがパフォーマンスと効率を最適化できます。例えば、表示されていないタブについては更新頻度を下げるといった制御が可能です。
定義アニメーションは2つの部分に分かれます:
-
animationの各サブプロパティの設定 -
@keyframesによるキーフレームスタイルの定義
ブラウザはこれらに基づいて補間アニメーションを作成し、補間計算を行って各キーフレームを繋ぎ合わせます。
2. animationサブプロパティ
animation-name @keyframesで定義されたキーフレーム名、デフォルトはnone
animation-duration アニメーション時間、デフォルトは0s。transitionと全く同じ
animation-timing-function イージング関数、デフォルトはease。transitionと全く同じ
animation-delay 遅延時間、デフォルトは0s。transitionと全く同じ
animation-iteration-count 繰り返し回数、デフォルトは1
animation-direction 方向、デフォルトはnormal
animation-fill-mode スタイル適用モード、デフォルトはnone
animation-play-state アニメーションシーケンスの一時停止/再開に使用、デフォルトはrunning
注意点:
-
durationが先、delayが後になります。その他のパラメータの順序は任意です。 -
animation-nameにはキーワードと同じ名前を使用しないでください。属性名が優先的にマッチされます。
animation-iteration-count
animation-iteration-count = infinite | <number>
アニメーションの繰り返し回数です。それぞれの値は無限回、指定された回数を表します。
animation-direction
animation-direction = normal | reverse | alternate | alternate-reverse
アニメーションの実行方向です。それぞれの値は、正方向、逆方向、交互(奇数回目は正方向、偶数回目は逆方向)、逆方向交互(奇数回目は逆方向、偶数回目は正方向)を表します。
animation-fill-mode
animation-fill-mode = none | forwards | backwards | both
スタイル適用モードです。それぞれの値は、キーフレームスタイルを適用しない、(終了後に)最終状態のスタイルを適用する、(delay期間中に)初期状態のスタイルを適用する、(delay期間中に)初期状態のスタイルを適用し、かつ(終了後に)最終状態のスタイルを適用することを表します。
注意:初期状態と最終状態は、 animation-iteration-count と animation-direction によって 0% になるか 100% になるかが決まります。
キーワードの意味は以下の通りです:
none アニメーション終了後、@keyframesで定義されたスタイルを削除し、元のスタイルに戻します
forwards アニメーション終了後、最終状態のスタイルを保持します
backwards アニメーション開始前(delay期間中)、初期状態のスタイルを保持します
both forwardsとbackwardsの両方の効果を持ちます。つまり、delay期間中は初期状態のスタイルを保持し、アニメーション終了後は最終状態のスタイルを保持します
具体的な違いはデモを参照してください:http://www.ayqy.net/temp/animation/animation-fill-mode.html。赤いブロックをクリックするとアニメーションが開始されます。
animation-play-state
animation-play-state = running | paused
アニメーションを実行するか一時停止するかを決定します。アニメーションの一時停止や再開を制御するのに使用でき、 delay よりも強力で柔軟です。
具体的な効果はデモを参照してください:http://www.ayqy.net/temp/animation/animation-play-state.html
3. @keyframes
構文は以下の通りです:
@keyframes anmiationName {
0% {}
/*...*/
100% {}
}
0% と 100% が定義されていない場合、ブラウザは他の時点のキーフレームに基づいて、すべてのプロパティの値を算出します。
追記: to と from はそれぞれ 0% と 100% のエイリアスです。初期状態と最終状態は重要であるため、英語名が割り当てられています。
4. イベント
transition には end イベントが1つあるだけですが、 animation は3つのイベントを提供します:
animationstart 開始
animationend 終了
animationiteration 次回の繰り返しの開始
イベントオブジェクトには3つの特別なプロパティがあります:
-
animationName
すなわち
animation-nameです。 -
elapsedTime
単位は秒です。
animationstartとanimationendについてはその時点までのアニメーション実行時間を表し、animationiterationについては次回の繰り返しが開始される時間を表します。transitionendイベントと同様に、通常はdelayの影響を受けません。特例として、
animationstartにおけるelapsedTimeは通常0ですが、animation-delayが負の値の場合はelapsedTimeは-1 * delayとなります。 -
pseudoElement
::で始まる擬似要素名です。アニメーションが擬似要素に適用されていない場合は空文字列となります。
注意:最後の繰り返しが終了したときは、 animationiteration ではなく animationend がトリガーされます。
5. テクニック
1. steps(1)で滑らかな遷移をなくす
steps(1) は linear とよく似ています。 linear アニメーションから補間遷移を取り除き、キーフレームのみを残すと、キーフレーム間のフレームが前のキーフレームを継続するようになり、それが steps(1) となります。
Flashを制作する際、2つのキーフレームを挿入すると、その間のフレームは通常フレーム(前のキーフレームの再生時間を延長するもの)になり、この時の効果が steps(1) に相当します。後ろのキーフレームを右クリックして補間アニメーションを作成すると、 linear の効果が得られます。
例は以下の通りです:
.rgb {
-webkit-animation: rgb 1.5s linear infinite;
animation: rgb 1.5s linear infinite;
}
@keyframes rgb {
0% {
opacity: red;
}
33% {
background: green;
}
66% {
background: blue;
}
}
効果は背景色が赤・緑・青と滑らかに変化します。グラデーションの滑らかな遷移をなくしたい場合は、以下のように linear を steps(1) に変更するだけです:
.rgb-step {
-webkit-animation: rgb 1.5s steps(1) infinite;
animation: rgb 1.5s steps(1) infinite;
}
これにより、0.5秒ごとに背景色が切り替わり、グラデーションの遷移がなくなります。
具体的な応用:2つの状態の無限切り替え(点滅)
.blink {
-webkit-animation: blink 1s steps(1) infinite;
animation: blink 1s steps(1) infinite;
}
@keyframes blink {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
}
2. キーフレームの追加で滑らかな遷移をなくす
点滅効果には、もう一つの興味深い実現方法があります:
.blink {
-webkit-animation: blink 1s linear infinite;
animation: blink 1s linear infinite;
}
@keyframes blink {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
50.01% {
opacity: 1;
}
100% {
opacity: 1;
}
}
依然として linear による滑らかな遷移ですが、挿入された:
50.01% {
opacity: 1;
}
により、 50% -> 100% の補間がなくなり、不透明度の補間が 50% -> 50.01% に移動します。時間が短い場合、この補間の変化は感知されません。もちろん、時間が十分に長い場合(例:)
.blink {
-webkit-animation: blink 10000s linear infinite;
animation: blink 10000s linear infinite;
}
ある1秒の間で不透明度が0から1へ変化するのが見えるはずですが、通常の場合、この方法で点滅を実現しても効果に問題はありません。
3. キーフレームによる遅延の制御
animation-delay はアニメーション開始前にのみ有効で、繰り返しのたびに遅延が挿入されることはありません。上記の 50.01% のテクニックと同様に、空白のキーフレームを挿入することで、繰り返しのたびに遅延を入れ、ローディングが一周回って少し止まるといった効果を実現できます:
.wait {
-webkit-animation: wait 1s linear infinite;
animation: wait 1s linear infinite;
}
@keyframes wait {
0% {
-webkit-transform: rotateZ(0);
transform: rotateZ(0);
}
40% {
-webkit-transform: rotateZ(0);
transform: rotateZ(0);
}
100% {
-webkit-transform: rotateZ(360deg);
transform: rotateZ(360deg);
}
}
これにより、一周ごとに 0.4s 待機するようになります。
4. stepsによるコマ送りアニメーション
シーケンスフレームを1枚の画像に並べ、 background-position を変更します。
steps() で実現する場合、最後に最初のフレームをコピーする必要があります(例えば6フレームのアニメーションなら、7フレーム並んだ画像が必要です)。例:
.walk {
background: url(walk.svg);
width: 162px;
height: 230px;
-webkit-animation: walk 1s steps(22) infinite;
animation: walk 1s steps(22) infinite;
}
@keyframes walk {
0% {
background-position: 0 0;
}
100% {
background-position: -3564px 0;
}
}
このうち、 walk.svg は横に23フレーム並んでおり、各フレームのサイズは 162 * 230 です。背景画像を左にずらしていき、最大で 162 * 22 = 3564 までずらすと、最後のフレーム(内容は最初のフレームと同じ)が表示され、最初と最後が繋がります。
もちろん別の方法もあり、 steps(1) で滑らかな遷移をなくし、手動で22個のキーフレームを設定することも可能です。手間はかかりますが、確実に実現可能です。
オンラインデモ:http://www.ayqy.net/temp/animation/css-animation-tricks.html
6. まとめ
CSS animationの定義方法はFlashと非常によく似ています。例えばFlashにおける以下の概念を考えてみてください:
-
キーフレーム:ある箇所の内容を前と変えたい場合に挿入します。
-
空白キーフレーム:内容がないことを示し、白い点で表示されます。キーフレームと相互に変換可能で、内容を置けばキーフレームになり、キーフレームの内容を消せば空白キーフレームになります。
-
通常フレーム:キーフレームや空白キーフレームの後に続くフレームです。前のキーフレームの内容を継続するため、アニメーションの表示時間を制御する役割があります。
これらをCSSの @keyframes 定義に当てはめて考えてみると、なかなか面白いと思いませんか?
コメントはまだありません