JavaScriptでアニメーションを実装できるWeb Animations APIについて、いくつか使い方を試してみます。
対応ブラウザ
Web Animations APIの対応ブラウザはこちら
主要なブラウザで基本的にはサポートされていますが、iOS Safariでcomposite modesという機能が未対応になっています。
サンプルコード
まずはアニメーションする要素をHTMLに追加しておきます。
<div class="sample"></div>
次にJavaSccriptでアニメーションの設定を行っていきます。
Web Animations APIでは、CSSの@keyframesのような形でアニメーションの設定(Keyframeオブジェクト)を行うことができます。
const animateKeyframes = [
  {
    rotate: "0deg",
    backgroundColor: "red"
  }, {
    rotate: "360deg",
    backgroundColor: "orange"
  },
];
配列内の各オブジェクトにプロパティ名と値のセットを指定しています。
次にアニメーションの秒数や回数など、アニメーションのオプションの設定を行います。
const animateOptions = {
  duration: 4000,
  iterations: Infinity,
};
この場合、4000ミリ秒のアニメーションを無限に実行します。
最後に、上記で設定した内容をanimate()メソッドを使ってアニメーションする要素に設定します。
document.querySelector('.sample').animate(animateKeyframes, animateOptions);
これで回転しながら色を変更するアニメーションが実装できました。
アニメーションのデモページ
| animate(keyframes, options) | 指定した要素に対してアニメーションを適用。 keyframes:配列、またはオブジェクト形式でキーフレームを指定 options:アニメーションの秒数(ミリ秒)や回数などのオプションを指定 | 
|---|
keyframes
前述の例ではキーフレームの数が2つだったため、1つ目が0%、2つ目が100%としてアニメーションが実行されました。
例えば間に1つキーフレームを追加した場合、それぞれ0%、50%、100%としてアニメーションが実行されるようになります。
const animateKeyframes = [
  {
    rotate: "0deg",
    backgroundColor: "red"
  }, {
    backgroundColor: "blue"
  }, {
    rotate: "360deg",
    backgroundColor: "orange"
  },
];
このようにキーフレームの数に応じて自動的に均等分割されますが、明示的に設定したい場合はoffsetを指定します。
offsetは0.0から1.0の間で、キーフレーム毎で昇順に並ぶように指定する必要があります。
const animateKeyframes = [
  {
    rotate: "0deg",
    backgroundColor: "red"
  }, {
    backgroundColor: "blue",
    offset: 0.2
  }, {
    rotate: "360deg",
    backgroundColor: "orange"
  },
];
これで2つ目のキーフレームは50%ではなく、20%としてアニメーションが実行されます。
offsetのデモページ
それぞれのキーフレームに対してイージングの設定も可能です。
const animateKeyframes = [
  {
    rotate: "0deg",
    backgroundColor: "red",
    easing: "ease-in"
  }, {
    rotate: "180deg",
    backgroundColor: "blue",
    easing: "ease-out"
  }, {
    rotate: "360deg",
    backgroundColor: "orange"
  },
];
この場合1つ目~2つ目のアニメーションがease-in、2つ目から3つ目のアニメーションがease-outになります。
easingのデモページ
注意点として、以下のrotateのように途中省略している2つ目にイージングを設定した場合、2つ目~3つ目のrotateのアニメーションに対してease-outは適用されないようです。
const animateKeyframes = [
  {
    rotate: "0deg",
    backgroundColor: "red",
    easing: "ease-in"
  }, {
    backgroundColor: "blue",
    easing: "ease-out"
  }, {
    rotate: "360deg",
    backgroundColor: "orange"
  },
];
ここまでのkeyframesは配列形式での指定でしたが、オブジェクト形式での指定も可能です。
const animateKeyframes = {
  rotate: ["0deg", "360deg"],
  backgroundColor: ["red", "blue", "orange"]
};
前述のoffsetやeasingも設定可能です。
const animateKeyframes = {
  rotate: ["0deg", "180deg", "360deg"],
  backgroundColor: ["red", "blue", "orange"],
  easing: ["ease-in", "ease-out"]
};
options
animate()の第二引数に入るoptionsについても確認してみます。
optionsには単一の数値か、オブジェクト形式でオプションを設定できます。
単一の数値の場合、アニメーションの秒数(ミリ秒)になります。
const animateKeyframes = [
  {
    rotate: "0deg",
    backgroundColor: "red"
  }, {
    backgroundColor: "blue"
  }, {
    rotate: "360deg",
    backgroundColor: "orange"
  },
];
document.querySelector('.sample').animate(animateKeyframes, 4000);
iterationsはアニメーションを繰り返す回数で、数値またはInfinityで無限を指定できます。
const animateOptions = {
  duration: 4000,
  iterations: 2,
};
document.querySelector('.sample').animate(animateKeyframes, animateOptions);
iterationStartはアニメーションの開始地点の指定になります。
const animateOptions = {
  duration: 4000,
  iterations: 2,
  iterationStart: 0.5,
};
子の指定の場合、アニメーションは50%の地点(背景色青色)から開始して、2回分の繰り返し(3回目の50%地点)で終了になります。
iterationStartのデモページ
delayはアニメーションの開始を遅延する秒数(ミリ秒)を指定します。
const animateOptions = {
  duration: 4000,
  delay: 2000,
  iterations: 2,
};
easingはアニメーション全体のイージングを指定します。
const animateOptions = {
  duration: 4000,
  iterations: 2,
  easing: "ease-in-out",
};
設定可能な値はこちらをご確認ください。
easingのデモページ
directionはアニメーションの進行方向を指定します。
normalで順方向、reverseで逆方向、alternateで繰り返し毎に反転、alternate-reverseで逆方向から繰り返し毎に反転になります。
const animateOptions = {
  duration: 4000,
  iterations: 2,
  direction: "alternate-reverse",
};
fillはアニメーションの効果を再生前または再生後にも適用するかどうかを指定します。
再生前にも適用する場合はbackwards、
再生後にも適用する場合はforwards、
再生前と再生後の両方に適用する場合はbothを指定します。
初期値はnoneで適用されません。
const animateOptions = {
  duration: 4000,
  delay: 2000,
  iterations: 2,
  fill: "both",
};
endDelayはアニメーション終了後の遅延時間(ミリ秒)を指定します。
例として、アニメーション完了後にconsoleを出力する処理をつかして試してみます。
const animateOptions = {
  duration: 4000,
  endDelay: 2000,
  iterations: 2,
};
const sampleAnimate = document.querySelector('.sample').animate(animateKeyframes, animateOptions);
sampleAnimate.addEventListener('finish', function() {
  console.log('アニメーション完了');
});
動作を確認してみると、アニメーション終了後に2秒間を開けて完了のconsoleが出力されることが確認できます。
endDelayのデモページ
pseudoElementは::beforeなどの疑似要素に対してアニメーションを指定できます。
const animateOptions = {
  pseudoElement: "::before",
  duration: 4000,
  iterations: 2,
};
メソッド・イベント
アニメーションに対して使用できるメソッドとイベントをいくつか試してみます。
まずはメソッドです。
<button class="play" type="button">play()</button> <button class="pause" type="button">pause()</button> <button class="finish" type="button">finish()</button> <button class="cancel" type="button">cancel()</button> <button class="reverse" type="button">reverse()</button> <button class="updatePlaybackRate" type="button">updatePlaybackRate(1)</button> <button class="updatePlaybackRate2" type="button">updatePlaybackRate(2)</button> <button class="updatePlaybackRate-1" type="button">updatePlaybackRate(-1)</button> <div class="sample"></div>
const animateKeyframes = [
  {
    rotate: "0deg",
    backgroundColor: "red"
  }, {
    backgroundColor: "blue"
  }, {
    rotate: "360deg",
    backgroundColor: "orange"
  },
];
const animateOptions = {
  duration: 4000,
  iterations: 5,
};
const sampleAnimate = document.querySelector('.sample').animate(animateKeyframes, animateOptions);
document.querySelector('.play').addEventListener('click', function() {
  sampleAnimate.play();
});
document.querySelector('.pause').addEventListener('click', function() {
  sampleAnimate.pause();
});
document.querySelector('.finish').addEventListener('click', function() {
  sampleAnimate.finish();
});
document.querySelector('.cancel').addEventListener('click', function() {
  sampleAnimate.cancel();
});
document.querySelector('.reverse').addEventListener('click', function() {
  sampleAnimate.reverse();
});
document.querySelector('.updatePlaybackRate').addEventListener('click', function() {
  sampleAnimate.updatePlaybackRate(1);
});
document.querySelector('.updatePlaybackRate2').addEventListener('click', function() {
  sampleAnimate.updatePlaybackRate(2);
});
document.querySelector('.updatePlaybackRate-1').addEventListener('click', function() {
  sampleAnimate.updatePlaybackRate(-1);
});
| play() | アニメーションの再生開始。 | 
|---|---|
| pause() | アニメーション再生の一時停止。 | 
| finish() | アニメーションの再生終了まで移動。 | 
| cancel() | アニメーションの再生中止。 | 
| reverse() | アニメーションの再生方向を反転して再生開始。 再生中の場合、その場で再生方向を反転して開始地点までアニメーションを実行。 | 
| updatePlaybackRate() | アニメーションの再生速度の変更。 負の値の場合は逆方向のアニメーションになる。 | 
次にイベントです。
document.querySelector('.play').addEventListener('click', function() {
  sampleAnimate.play();
});
document.querySelector('.finish').addEventListener('click', function() {
  sampleAnimate.finish();
});
document.querySelector('.cancel').addEventListener('click', function() {
  sampleAnimate.cancel();
});
sampleAnimate.addEventListener('finish', function() {
  console.log('finish');
});
sampleAnimate.addEventListener('cancel', function() {
  console.log('cancel');
});
| finish | アニメーションの再生が完了したときに発火。 | 
|---|---|
| cancel | アニメーションの再生がキャンセルされた時に発火。 | 

コメントが承認されるまで時間がかかります。