Web Animations API を使ってJavaScriptでAnimationを実装する

JavaScriptでアニメーションを実装しようと調べたところ、Web Animation API というものがあるようです。
MDNを見る限りこのAPIはまだまだ新しいようで、Qiitaにも記事が少なかったのでチートシート的にまとめてみます。

## Web Animation API とは


choromeやsafariなどの一部プラウザで対応してたり対応してなかったりするようです。

polyfillのスクリプトを読み込むと問題なく使えるようです。どうやらWeb Animation自体は数年前から存在しているようです。

``` .js
<script src="https://cdn.jsdelivr.net/web-animations/latest/web-animations.min.js"></script>
```

```
npm install web-animations-js
```


## 基本のアニメーション

``` .js
const element = document.body;
element.animate({ backgroundColor: ['red', 'blue'] }, 3000);
```

### Element.animate

https://developer.mozilla.org/ja/docs/Web/API/Element/animate

animationを実行しanimation object を返します。

`element.animate(keyframes, option)`となっており

第一引数のkeyframesはいくつかフォーマットが用意されています。

``` .js
const keyframes = [
  { // from
    opacity: 0,
    color: "#fff"
  }, 
  { // to
    opacity: 1,
 ​   color: "#000"
  }
]
```

``` .js
const keyframes = {
  opacity: [ 0, 1 ],          // [ from, to ]
  color:   [ "#fff", "#000" ] // [ from, to ]
}
```

[フォーマットについて](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Keyframe_Formats)

第二引数のoptionにはmsの数値かoptionオブジェクトを渡します。


``` .js
element.animate(keyframes, option)
```

## アニメーションのOption

第二引数に渡すOptionについてです。

``` .js
const option = {
  duration: 1000,
  easing: 'ease-in',
  iterations: 'Infinity',
  fill: 'backwards',
};
```

### easing

アニメーションカーブを指定できます。デフォルトでは`liner`になります。
`Ease-in` `ease-in-out`などの他にも`steps(1, end)` `cubic-bezier(0, 0, 0.58, 1)`なども指定できます。

- https://developer.mozilla.org/en-US/docs/Web/API/EffectTiming/easing

### Iterations

アニメーションの回数を指定できます。デフォルトは`1`です。
無限に繰り返すには`Infinity`を指定します。

### delay

名前の通り指定秒アニメーションを遅らせることができます。

### fill

アニメーション終了後にアニメーション終了時の状態を維持するには`forwards`を、
アニメーション開始前の状態に戻る場合は`backwords`を指定します。


---

大抵の場合は上記を指定できれば十分だと思いますが、その他にもいくつかオプションがあるようです。


https://drafts.csswg.org/web-animations/#updating-animationeffect-timing


## Animation Object

`Animation` コンストラクタを使ってAnimationオブジェクトを生成します。
`element.animate`メソッドではanimationが即座に実行されてしまいますが、Animationインターフェースを使う場合は明示的に`play()`メソッドを呼ぶ必要があります。


``` .js
  const element = document.getElementById('body');
  const effect = new KeyframeEffect(
    element,
    { backgroundColor: ['blue', 'orange']},
    1000
  );
 
 const animation = new Animation(effect, document.timeline)

 animation.play()
```


[Animation](https://developer.mozilla.org/ja/docs/Web/API/Animation/Animation)

第二引数はデフォルトでdocument.timelineのようです。


[KeyframeEffect](https://developer.mozilla.org/ja/docs/Web/API/KeyframeEffecthttps://developer.mozilla.org/ja/docs/Web/API/KeyframeEffect)

### メソッド

Animationオブジェクトは以下の制御メソッドが使えます。

- `play()` 再生・再開する
- `pause()` 一時停止する
- `reverse()` 逆再生する
- `cancel()` 中断する
- `finish()` 

https://developer.mozilla.org/ja/docs/Web/API/Animation#%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89

### アニメーションの状態


Animation.playStateプロパティーを参照するとアニメーションの状態が分かります。

|value| 説明|
| --- | --- |
|idle| アニメーション前 |
|running| アニメーション中|
| paused | 中断|
| finished | アニメーション完了|



### イベントハンドラ

アニメーション終了時のコールバックを指定できます。

``` .js
animation.onfinish = () => console.log('finished');
```

キャンセル時のイベントも指定できます。

```.js
animation.oncancel = () => console.log('canceled');
```


## 参考

- https://developers.google.com/web/updates/2015/10/web-animations-resources
- https://danielcwilson.com/blog/2015/07/animations-part-1/
- https://drafts.csswg.org/web-animations/#the-animation-interface



---

簡単なAnimationはCSSの方が簡単で良さそうですが、プログラムから制御したい場面ってやっぱりありますよね。ルーレットアプリを作るときとか。今後も色々変更がありそうです。