LoginSignup
4
5

More than 5 years have passed since last update.

Web Animations APIを使った波紋アニメーション(ripple effect)

Last updated at Posted at 2018-02-18

CSSアニメーションを調べていたらWeb Animations APIというJavaScriptで同じことができることがわかったので、勉強も兼ねて簡単なライブラリを作ってみました。この記事はその時得た知識のまとめです。

Web Animations APIについて

CSSのAnimationsとTransitionsをJavaScriptで実現できるAPIです。
現在は、ChromeとFirefoxで実装が進められています。
Safari(WebKit)とEdgeについてはTodoには入ってますが、まだ実装されていません。
web-animations-jsというpolyfillがあるので、そちらを使うとSafariやEdgeでも使えます。

成果物

今回作成したライブラリはパルス(波紋)のアニメーションです。
CSSアニメーションでも簡単に実装できます。これをJavaScriptでやります。
pulsator.gif

GitHub
npm
Demoページ

See the Pen Pulsator JS by Masashi Hirano (@shisama) on CodePen.

今回の記事はこのライブラリを作成した際に調べたことをまとめていきます。

CSS

まずはCSSでの実装を紹介しておきます。

See the Pen Pulsator CSS by Masashi Hirano (@shisama) on CodePen.

keyframesで0pxから20pxの幅の波紋が広がるようにしています。
animationでkeyframesを1.5秒かけて実行。アニメーションを永続的に繰り返すためにinfiniteを設定しています。

JavaScript

上記のCSSで実装しているアニメーションをJavaScriptのみで実装していきます。
順を追って説明します。

styleの適用

今回はJavaScriptですべて完結したいため、アニメーション以外のstyleもJavaScriptにします。
-(ハイフン)で区切っていたCSSプロパティはキャメルケースに変更する必要があります。

const el = document.querySelector(".pulsator");
const style = {
  width: "15px",
  height: "15px",
  borderRadius: "50%",
  borderColor: "red",
  background: "red",
  boxShadow: "0 0 0 rgba(255,0,0, 0.4)"
};
Object.assign(element.style, style);

animate関数を使ってアニメーションを実行する

CSSのanimationやkeyframesをJavaScriptで実現するためにはanimate関数を使います。

const el = document.querySelector(".pulsator");
const animation = el.animate(
  {
    boxShadow: ["0 0 0 0 rgba(255,0,0, 1)", "0 0 0 20px rgba(255,0,0, 0)"]
  },
  {
    duration: 1500,
    iterations: Infinity
  }
);

animate関数を実行するとアニメーションは開始されます。
animate関数の第一引数にはkeyframes用にオブジェクトを設定します。
プロパティ名はキャメルケースにします。
fromとtoは配列で指定します。
複数のプロパティを設定したい場合は以下のようにオブジェクトのプロパティを追加するだけです。

  {
    boxShadow: ["0 0 0 0 rgba(255,0,0, 1)", "0 0 0 20px rgba(255,0,0, 0)"],
    background: ["red", "pink"]
  },

また、以下のようにオブジェクトの配列として指定することも可能です。

const animation = el.animate([
    {
      boxShadow: "0 0 0 0 rgba(255,0,0, 1)",
      background: "red"
    },
    {
      boxShadow: "0 0 0 20px rgba(255,0,0, 0)",
      background: "pink"
    }
  ],
  {
    duration: 1500,
    iterations: Infinity
  }
);

durationはミリ秒で指定します。これはCSSのanimationで1.5s指定していたkeyframesの実行時間です。
iterationsは繰り返しの方法を指定します。CSSのanimationでinfiniteと指定していたのをWeb Animations APIではInfinityと指定します。

KeyframeEffectを使用することでkeyframesの定義のみ先に行うことができます。

const keyframes = new KeyframeEffect(
  el, 
  {
    boxShadow: ["0 0 0 0 rgba(255,0,0, 1)", "0 0 0 20px rgba(255,0,0, 0)"]
  },
  {
    duration: 1500,
    iterations: Infinity
  }
);

const animation = new Animation(keyframes, document.timeline);

Animationのメソッドを使用してアニメーション操作を行う

animate関数はAnimationクラスのインスタンスを返却します。
定義したアニメーションを操作するためにはAnimationのメソッドを実行します。

play()

アニメーションを開始します。

animation.play()

例えば、あるボタンをクリックしたときに開始したいときは以下のようになります。

document.querySelector(".some-button").addEventListener("click", function(event) {
  animation.play();
});

cancel()

アニメーションをキャンセルします。

animation.cancel()

例えば、あるボタンをクリックした際にアニメーションを開始し、5秒後に終了する場合は以下のようにします。

document.querySelector(".some-button").addEventListener("click", function(event) {
  animation.play();
  setTimeout(function () {
    animation.cancel();
  }, 5000);
});

またoncancelはキャンセル時に実行されるイベントハンドラです。キャンセル時に実行される関数を設定しておくことができます。

animation.oncancel = function() {
  alert("canceled!");
}

pause()

アニメーションを停止します。終了させるわけではありません。例えば今回の波紋のアニメーションであれば波紋が広がる途中でアニメーションが止まります。アニメーションの終了ではないため波紋は消えません。

animation.pause()

例えばアニメーションしているDOMにマウスオーバーしたときにアニメーションを止めるには以下のようにします。

el.onmouseover = function(event) {
  animation.pause();
};

finish()

アニメーションを終了させます。
AnimationクラスのプロパティであるplaybackRateに0または0より大きな値が設定されており、iterationsにInfinityを設定している場合はこの関数は使用できません。InvalidStateというエラーが発生します。
※playbackRateは再生スピードを保持しているプロパティです。デフォルトでは1が設定されています。2を設定すれば2倍速になります。また、負の値を設定すると逆再生します。

animation.finish()

例えば、ECSキーを押した時にアニメーションを終了する場合、以下のようになります。

window.onkeydown = function(event) {
  if (event.key === "Escape") {
    animation.finish();
  }
};

またonfinishはアニメーション終了時に実行されるイベントハンドラです。終了時に実行される関数を設定しておくことができます。

animation.onfinish = function() {
  alert("finished!");
}

reverse()

アニメーションを逆再生します。
playbackRateに-1を設定したときと同じ挙動をします。

animation.reverse()

例えばEnterを押したときに逆再生するには以下のようになります。

window.onkeydown = function(event) {
  if (event.key === "Enter") {
    animation.reverse();
  }
};

Animationクラスのプロパティ

今回紹介したもの以外にも細かい設定を行うことができます。
多いので割愛させていただきます。もしくは別記事で使い方など書くかもしれません。
お手数おかけいたしますが、MDNを見て下さい。

まとめ

  • JavaScriptだけでアニメーションを実装することができます。
  • イベント発生時にアニメーションを操作することができます。
  • まだ、ChromeとFirefoxでしか実装されていませんが、polyfill(web-animations-js)も存在します。
  • w3cではまだDraftです。(https://www.w3.org/TR/web-animations-1/)

参考

最後までお読みいただきありがとうございました。
不備、不明点はコメントにてお願い致します。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5