Web Animations API

## CSS transition、CSS animationとの比較

キーフレームの制御まで含めてJavaScriptだけで管理可能

[CSSによるアニメーション(CSS Transition、CSS Animation)](https://qiita.com/takeshisakuma/items/e178e545089bce4efdad)もご参照ください。

|Web Animations APIのオプション|CSS Animationsのオプション|
|---|---|
|duration|animation-duration|
|delay|animation-delay|
|fill|animation-fill-mode|
|iterations|animation-iteration-count|
|direction|animation-direction|
|easing|animation-timing-function|
|iterationStart|なし|
|endDelay|なし|

|web animations api独自のオプション|内容|
|---|---|
|iterationStart|アニメーションの実行開始位置を設定　0.5 の場合 50% の位置から始まり1周する (50% -> 100%/0% -> 50%)|
|endDelay|アニメーションが終わってから後続のアニメーションを開始するまでの時間|


## キーフレーム
offsetで指定できます。範囲(0～1)
未指定の場合は等間隔になります。

## アニメーションの例

### 大きさ変更のアニメーション

```:html
<div class="rect"></div>
```

```:css
.rect {
  background-color: red;
  width: 100px;
  height: 100px;
}
```

```:js
const element = document.querySelector(".rect");

element.animate(
  [
    {
      transform: "scale(1)",
      offset: 0
    },

    {
      transform: "scale(2)",
      offset: 0.8
    },

    {
      transform: "scale(10)",
      offset: 1
    }

  ],

  {
    duration: 1000,
    fill: 'forwards',
    easing: 'ease'
  }
);
```

### 移動のアニメーション

```:html
<div class="rect"></div>
```

```:css
.rect {
  background-color: red;
  width: 100px;
  height: 100px;
}
```

```:js
const element = document.querySelector(".rect");

element.animate(
  [
    {
      transform: "translateX(0px)",
      offset: 0
    },

    {
      transform: "translateX(10px)",
      offset: 0.8
    },

    {
      transform: "translateX(100px)",
      offset: 1
    }

  ],

  {
    duration: 1000,
    fill: 'forwards',
    easing: 'ease'
  }

);
```

### 透明度のアニメーション

```:html
<div class="rect"></div>
```

```:css
.rect {
  background-color: red;
  width: 100px;
  height: 100px;
}
```

```:js
const element = document.querySelector(".rect");

element.animate(
  [
    {
      opacity: 0,
      offset: 0
    },

    {
      opacity: 0.5,
      offset: 0.8
    },

    {
      opacity: 1,
      offset: 1
    }
  ], 
  {
    duration: 10000,
    fill: 'forwards',
    easing: 'ease'
  }
);
```

### 明度のアニメーション

```:html
<div class="rect"></div>
```

```:css
.rect {
  background-color: red;
  width: 100px;
  height: 100px;
}
```

```:js
const element = document.querySelector(".rect");
 
element.animate(
  [
    {
      filter: "brightness(0%)",
      offset: 0
    },

    {
      filter: "brightness(50%)",
      offset: 0.2
    },

    {
      filter: "brightness(100%)",
      offset: 1
    }

  ],

  {
    duration: 1000,
    fill: 'forwards',
    easing: 'ease'
  }
            
);
```

### 彩度のアニメーション

```:html
<div class="rect"></div>
```

```:css
.rect {
  background-color: red;
  width: 100px;
  height: 100px;
}
```

```:js
const element = document.querySelector(".rect");

element.animate(
  [
    {
      filter: "grayscale(0%)",
      offset: 0
    },

    {
      filter: "grayscale(50%)",
      offset: 0.2
    },

    {
      filter: "grayscale(100%)",
      offset: 1
    }

  ],

  {
    duration: 1000,
    fill: 'forwards',
    easing: 'ease'
  }
);
```


### 複合アニメーション
例：四角が徐々に不透明になり、回転しながら右に移動

```:html
<div class="rect"></div>
```

```:css
.rect{
  background-color: red;
  width:100px;
  height:100px
}
```

```:js
const element = document.querySelector(".rect");

element.animate(
  [
    {
      transform: "translateX(0px) rotate(0deg)",
      opacity: 0,
      offset: 0
    },

    {
      transform: "translateX(10px) rotate(180deg)",
      opacity: 0.2,
      offset: 0.5
    },

    {
      transform: "translateX(1000px) rotate(270deg)",
      opacity: 1,
      offset: 1
    }

  ],

  {
    duration: 1000,
    fill: 'forwards',
    easing: 'ease'
  }
);
```

## アニメーション実行中のコントロール

|メソッド|内容|
|---|---|
|play()|再生する|
|pause()|一時停止する|
|reverse()|逆再生する|
|cancel()|再生をやめる|
|finish() |終了時点まで進める|
|updatePlaybackRate()|再生速度を設定|


|プロパティ|内容|
|---|---|
|currentTime|アニメーションの現在時間を表示(ミリ秒)|
|effect	|アニメーションのAnimationEffectReadOnlyの取得、設定|
|finished|アニメーション終了時に Promiseを返す|
|id|アニメーションを識別するStringの取得、設定|
|pending|アニメーションが再生の非同期処理(初期化、再生停止)のため現在待ち状態かどうか|
|playState|アニメーションの再生状況を返す|
|playbackRate|アニメーションの再生速度の取得、設定|
|ready|アニメーションの再生準備ができた時にPromiseを返す|
|startTime|アニメーションが再生される時間の取得、設定|
|timeline|アニメーションのtimelineの取得、設定|

|再生速度のプロパティの値|内容|
|---|---|
|playbackRate =2|2倍速|
|playbackRate =-1|逆再生|
|playbackRate *= 1.5|実行されるたびに再生速度が 1.5 倍|


|イベント|内容|
|---|---|
|oncancel|アニメーション中止時に発生するイベント|
|onfinish|アニメーション終了時に発生するイベント|


```:html
<div class="rect"></div>

<div class="pause">Pause</div>
<div class="play">Play</div>
<div class="reverse">Reverse</div>
<div class="finish">Finish</div>
<div class="cancel">Cancel</div>
```

```:css
.rect {
  background-color: red;
  width: 100px;
  height: 100px;
}
```

```:js
const element = document.querySelector(".rect");

const pause = document.querySelector(".pause");
const play = document.querySelector(".play");
const reverse = document.querySelector(".reverse");
const cancel = document.querySelector(".cancel");
const finish = document.querySelector(".finish");

const move = element.animate(
  [
    {
      transform: "translateX(0px) rotate(0deg)",
      offset: 0
    },

    {
      transform: "translateX(10px) rotate(180deg)",
      offset: 0.5
    },

    {
      transform: "translateX(1000px) rotate(270deg)",
      offset: 1
    }

  ],

  {
    duration: 10000,
    fill: 'forwards',
    easing: 'ease'
  }
);
move.pause();


move.onfinish = () => {
  console.log("アニメーションが終了した");
};

move.oncancel = () => {
  console.log("アニメーションがキャンセルされた");
};


play.addEventListener("click", () => {
  move.play();
});

pause.addEventListener("click", () => {
  move.pause();
});

reverse.addEventListener("click", () => {
  move.reverse();
});

cancel.addEventListener("click", () => {
  move.cancel();
});


finish.addEventListener("click", () => {
  move.finish();
});
```

## polyfill
https://github.com/web-animations/web-animations-js/tree/866e01726cf61ffeabad2baa7f6c10e3cadee138