Cacoo 開発チームの山岸です。ウェブにおけるアニメーション・インタラクションが好きなので今回は Web Animations API を紹介します。
Web Animations API (以下 WAAPI)とは
これまでの CSS Transitions / Animations や SVG Animation を JavaScript で実現するための API です。WAAPI によりアニメーションにおける統一的なインターフェースを提供することを目的として仕様策定が進められています。
何を解決するか
CSS によるアニメーションの場合、実行時の制御ができないことや複雑な CSS Animations の修正の大変さがありました。
また、CSS と JavaScript の両方を用いることも多いですが、アニメーション表現と実行のコントロールが別になることでの管理のしづらさ、requestAnimationFrame 等を用いたパフォーマンスの最適化も必要でした。
ブラウザ対応状況
2018年7月現在 Firefox でLevel 1 の基本機能実装済み、Chrome では一部機能のみ実装という状況であるためこのまま本番で使うことはできませんが、polyfill を使うことでほぼ全てのモダンブラウザで基本機能を動かすことが可能です。
さらに、仕様としてはまだ検討段階のものについても web-animations-next polyfill により試すことができます。
next でサポートされている機能は今後の仕様変更で使えなくなる可能性があるため、今回はすでにブラウザにネイティブ実装されているものについて紹介していきます。
基本的な使い方
animate 関数*
element.animate(keyframes, options)
Animation object のインスタンス生成、対象要素への適用、アニメーション再生が行われます。自動的に再生したくない場合は 後述の pause() メソッドを使い止める必要があります。
引数の keyframes にアニメーションの開始や終了の状態を、options に実行回数や時間を設定して使います。
CSS Animations と比較してみるとわかりますと思います。
.el { animation: changeBG infinite 1s ease-out; } @keyframes changeBG { 0% { background-color: 'cyan'; } 50% { background-color: 'teal'; } 100% { background-color: 'cyan'; } }
el.animate( [ { backgroundColor: 'cyan' }, { backgroundColor: 'teal' }, { backgroundColor: 'cyan' } ], { duration: 1000, iterations: Infinity, easing: 'ease-out' } );
keyframes
keyframes は配列またはオブジェクトで渡します。
[ { backgroundColor: 'cyan' }, { backgroundColor: 'teal' }, { backgroundColor: 'cyan' } ] // or { backgroundColor: ['cyan', 'teal', 'cyan'] }
CSS Animations との違いは
- keyframes の開始位置をフレーム数に合わせて割り振る / 自分で調整することを選択できる
- フレームごとに easing の設定が可能
であるためより柔軟なアニメーション表現が可能です。例として 2個目のフレーム開始位置を 90% 、easing を ease-out にしたい場合は { backgroundColor: 'teal', offset: 0.9, easing: 'ease' }
のように設定することで特定フレームのアニメーションをコントロールできます。
options
上記例の他にも delay, direction, fill といった CSS Animations と同等の機能が提供されています。easing に関しては cubic-bezier にも対応しています。以下は CSS Animations のプロパティとの対応です。
duration
: animation-durationdelay
: animation-delayfill
: animation-fill-modeiterations
: animation-iteration-countdirection
: animation-directioneasing
: animation-timing-function
また、WAAPI 独自の プロパティもあります。
iterationStart
: アニメーションの実行開始位置を設定できます。0.5 の場合 50% の位置から始まり1周します (50% -> 100%/0% -> 50%)endDelay
: アニメーションが終わってから後続のアニメーションを開始するまでの時間
アニメーション実行中のコントロール
CSS によるアニメーションとの一番大きな違う点として、Animation メソッドを使うことでアニメーション実行中のコントロールが可能なことがあげられます。
const elAnimation = element.animate(keyframes, options); el.reverse(); // 逆再生
play()
再生するpause()
一時停止するreverse()
逆再生するcancel()
再生をやめるfinish()
終了時点まで進めるplaybackRate
再生速度のプロパティです。値を 2 にすれば2倍速に、また -1 の設定すると逆再生されます。
下記の例のように ball.playbackRate *= 1.5;
とすると早送りボタン (Fast-forward) がクリックされるたびに再生速度が 1.5 倍になります。
コールバック
アニメーションの中止と終了の イベント として
が提供されています。 elAnimation.onfinish = eventHandler;
のようにアニメーション終了時のコールバックが可能です。
Web Components との組み合わせ
ライブラリに依存することなくアニメーション表現が可能となるため、以前 Cacoo チームの川端が紹介していた Web Components と組み合わせてアニメーション用のコンポーネントを作ることも手軽にできます。
まとめ
WAAPI を使うことで大量の keyframes が宣言された CSS Animations ではなく複数のシーンに切り分けて実行順を制御できるようになりコードの見通しがよくなることが期待できます。
また、パフォーマンス面でも transform / opacity を用いることで CSS Animations 同様に メインスレッドから切り離したアニメーションを実現できます。(詳しくは Creating animations from script 参照)
ブラウザの対応状況はまだまだこれからですが、WAAPI の普及によって各種アニメーション用ライブラリに依存することなく表現できる幅が広がるのではないでしょうか。
現在仕様策定中の機能には複数アニメーションのグループ化や実行管理ができたり、CSS Animations で書かれているアニメーションを JavaScript から操作するものもあります。今回紹介した機能は仕様が定まっているものですのでぜひ試してみてください。