MonacaアプリやWebアプリの開発では、アニメーションを取り入れることで、使いやすさ・楽しさが格段にアップします。たとえば、次のような動きです。

  • ボタンを押したときにふわっと反応
  • スクロールに合わせて要素がスライドイン
  • マウスの動きに追従するインタラクション

こうした表現を手軽に実現できるのが、今回紹介する Anime.js です。

Anime.jsとは?

Anime.jsは、JavaScriptでアニメーションを実装するための軽量かつ高機能なライブラリです。以下のような特徴があります。

  • CSSだけでなくSVGやDOM、JSオブジェクトも対象にできる
  • ease(イージング)やタイムライン、ループなど細かな制御が可能
  • 直感的な書き方ができ、初心者でも導入しやすい
img

デモ紹介:スクロール連動アニメーション

まずはこちらをご覧ください。Anime.js公式サイトのトップページでは、スクロールに連動して要素が登場するインタラクティブなデモが体験できます。

img

Anime.jsを使ってみよう(基本の準備)

スクリプトの読み込み

<script type="module">
  import {
    animate, utils, createDraggable, createSpring
  } from "https://cdn.jsdelivr.net/npm/animejs/+esm";
</script>

import 文でAnime.jsの関数を読み込みます。
animateはアニメーションの基本関数、utilsは要素取得などの補助機能、createDraggableは要素をドラッグ可能にする関数、createSpringはバネのような動きを加えるease関数です。

これらの関数を組み合わせることで、様々なインタラクティブなアニメーションを作成できます。

HTMLを用意しよう(ロゴとボタン)

img
<div class="large centered row" style="display: flex; justify-content: center; align-items: center; width: 200px;">
  <svg class="logo js" preserveAspectRatio="xMidYMid meet" viewBox="0 0 630 630">
    <path fill="currentColor" d="M577,....27 Z"></path> <!-- SVGパスの中身は省略 -->
  </svg>
</div>

<div class="medium row">
  <fieldset class="controls">
    <button>rotations: 0</button>
  </fieldset>
</div>

<script type="module" src="app.js"></script>

このHTMLではアニメーション対象となるSVGロゴと操作用のボタンを配置しています。

SVG要素にはlogo jsのクラスを付与してJavaScriptから操作できるようにし、ボタンはクリックでロゴの回転数を管理する役割を持ちます。

最後に外部JavaScriptファイルapp.jsを読み込んで、実際のアニメーション処理を実行します。

app.jsの実装と解説

1. 要素を取得して準備

Anime.jsから必要な関数をインポートした後、utils.$を使用してDOM要素を取得しています。ロゴとボタンをそれぞれ変数に格納し、回転回数を追跡するためのrotations変数を初期化しています。

import { animate, utils, createDraggable, createSpring } from "animejs";

const [ $logo ] = utils.$(".logo.js");
const [ $button ] = utils.$("button");
let rotations = 0;

2. ロゴをスケール(拡大→縮小)するアニメーション

ロゴに連続的なスケールアニメーションを適用しています。

まず1.25倍に拡大してから元のサイズに戻る動作を繰り返し、拡大時は滑らかなイージング、縮小時はバネのような自然な動きを使用しています。

loop: trueで永続的に繰り返し、各ループ間に250msの間隔を設けています。

animate(".logo.js", {
  scale: [
    { to: 1.25, ease: "inOut(3)", duration: 200 },
    { to: 1, ease: createSpring({ stiffness: 300 }) }
  ],
  loop: true,
  loopDelay: 250,
});

3. ロゴをドラッグできるようにする

createDraggable関数を使用してロゴをマウスや指で自由に移動できるようにしています。要素を離した際にはバネのような動きで元の位置に戻るよう設定し、より自然で気持ちの良いインタラクションを実現しています。

createDraggable(".logo.js", {
  container: [0, 0, 0, 0],
  releaseEase: createSpring({ stiffness: 200 })
});

4. ボタンでロゴを回転させる

ボタンクリック時に実行される関数を定義しています。
クリックごとに回転数を1増やしてボタンのテキストを更新し、累積的な回転角度でロゴを回転させます。
イージングには加速してから減速する自然な動きを使用し、1.5秒かけてゆっくりと回転を完了させています。

const rotateLogo = () => {
  rotations++;
  $button.innerText = rotations: ${rotations};
  animate($logo, {
    rotate: rotations * 360,
    ease: 'out(4)',
    duration: 1500,
  });
};

$button.addEventListener('click', rotateLogo);

Anime.jsのその他機能(応用編)

タイマー(定期的に更新)

createTimerを使用することで一定間隔での処理実行が可能になります。

この例では1秒間隔で繰り返し処理を行い、30FPSで更新されます。onUpdateコールバックは毎フレーム実行されて現在時刻を表示し、onLoopコールバックは各ループ完了時にループ回数をカウント表示します。

createTimer({
  duration: 1000,
  loop: true,
  frameRate: 30,
  onUpdate: self => $time.innerHTML = self.currentTime,
  onLoop: self => $count.innerHTML = self._currentIteration
});
img

テキストのバウンド(跳ねる)アニメーション

テキスト内の各文字要素(span)に跳ねるような動きを適用しています。

Y軸方向に上昇してから跳ね返るような動きを作り、同時に回転も加えています。
delay: (_, i) => i * 50により各文字のアニメーション開始を50msずつずらすことで、波のような連続的な動きを演出しています。

animate("span", {
  y: [
    { to: "-2.75rem", ease: "outExpo", duration: 600 },
    { to: 0, ease: "outBounce", duration: 800, delay: 100 }
  ],
  rotate: {
    from: "-1turn",
    delay: 0
  },
  delay: (_, i) => i * 50,
  loop: true
});
img

タイムライン(複数要素の順次実行)

createTimelineで複数のアニメーションを時系列で管理できます。

label('start')で基準ポイントを設定し、各要素のアニメーションを異なるタイミングで実行します。

四角形は500ms後に開始、円は'start'ラベルと同時に開始、三角形は直前のアニメーションより500ms早く開始して回転しながら移動します。これにより複雑な連携アニメーションを簡潔に記述できます。

const tl = createTimeline({ defaults: { duration: 750 } });

tl.label("start")
  .add(".square", { x: "15rem" }, 500)
  .add(".circle", { x: "15rem" }, "start")
  .add(".triangle", { x: "15rem", rotate: "1turn" }, "<-=500");
img

マウスに追従する動き

createAnimatableを使用してリアルタイムでアニメーション可能な要素を作成しています。

初期位置を(500, 500)に設定し、ease: 'out(3)'で滑らかな減速カーブを適用しています。マウス移動イベントリスナーでマウスカーソルの座標を取得し、animSquare.x()animSquare.y()メソッドで要素の位置を更新します。

これによりマウスカーソルに追従しながらも、イージング効果により自然で滑らかな動きを実現できます。単純な位置変更とは異なり、慣性のような心地よい動きが加わります。

const animSquare = createAnimatable(".square", {
  x: 500,
  y: 500,
  ease: "out(3)",
});

window.addEventListener("mousemove", e => {
  animSquare.x(e.clientX);
  animSquare.y(e.clientY);
});
img

ドラッグ機能(簡易版)

createDraggable関数にセレクターを渡すだけで、指定した要素を簡単にドラッグ可能にできます。

この一行のコードにより、マウスクリックまたはタッチでの要素移動、ドラッグ中の座標追跡、離した際の処理などが自動的に実装されます。

オプションを指定しない場合はデフォルト設定が適用され、画面内での自由な移動が可能になります。

createDraggable(".square");
img

スクロールに合わせて動かす(詳細は公式へ)

📎 スクロールアニメーション公式ガイド

img

スタッガー(ずらして表示)

stagger関数を使用して複数の要素に時間差を付けたアニメーションを実行しています。

delay: stagger(100)により各要素のアニメーション開始を100msずつずらし、波のような連続的な動きを作り出します。

scale: stagger([1, .1])では要素ごとに異なるスケール値を適用し、最初の要素は通常サイズ(1)、最後の要素は縮小(0.1)され、中間の要素は段階的に変化します。

全ての要素が同じ距離(17rem)移動しながら、それぞれ異なるタイミングとスケールでアニメーションが実行されるため、視覚的に豊かで動的な効果が生まれます。

animate(".square", {
  x: "17rem",
  scale: stagger([1, .1]),
  delay: stagger(100),
});
img

SVGを手書きのように描画

SVG要素を手書きのように段階的に描画するアニメーションです。

svg.createDrawableでSVGパスを描画可能な状態にし、drawプロパティで描画の進行状況を制御します。

値は['開始点', '中間点', '終了点']の形式で、'0 0'から始まって'1 1'で完全に描画されます。

stagger(100)により複数の線がある場合は100msずつずらして描画され、まるで手で順番に線を引いているような自然な効果を生み出します。2秒かけてゆっくりと描画が完了し、ループ設定により繰り返し再生されます。

animate(svg.createDrawable(".line"), {
  draw: ["0 0", "0 1", "1 1"],
  ease: "inOutQuad",
  duration: 2000,
  delay: stagger(100),
  loop: true
});
img