JavaScriptアニメーションはGSAP一択?メリット・使い方について

前回GSAPを使って「途中から横にスクロールするサイトを作る方法」をご紹介しました。

今回はその続きとして、GSAP(GreenSock Animation Platform)の基礎と、実務で使う場面が多い機能を順に取り上げます。タイムライン、ScrollTrigger、Flip の3点を中心に、最小構成のコードから始めて段階的に広げます。

GSAPとは

GSAPは、Web上のさまざまな要素に対してアニメーションを与えるためのJavaScriptライブラリです。CSSプロパティ、SVGの属性、数値や色など“数値化できるもの”を時間軸に沿って滑らかに変化させられます。単発の動きを扱う「Tween」と、複数の動きを連ねて管理する「Timeline」を中核に、必要に応じてプラグインを足して拡張できる構成になっています。

JavaScriptアニメーションはGSAP一択?|GSAPを使うメリット

  • 時間軸の考え方がわかりやすい

    複数要素の出入りや重なりを、時間の前後関係としてまとめて扱えます。順序変更や微調整が後からでも崩れにくく、リリース後の修正にも耐えます。

  • スクロール連動の設計がしやすい

    特定セクションの開始・終了、固定表示、進捗との同期、スナップなど、スクロールを基準にした演出を一貫して組み立てられます。章立てのページや横スクロール表現と相性が良いです。

  • レイアウト遷移を自然に見せられる

    要素の並び替えやサイズ変更など、DOM構造が変わる場面でも“前後の差分を補間する”形でつながりを保てます。カード一覧→詳細、フィルタやソート時の並び替えなど、UIの迷子を防ぐのに有効です。

  • 保守対応/サイトのパフォーマンスが下がりにくい

    タイムラインやラベルで動きに名前を付けられるため、チーム内の共有や保守がしやすくなります。プラグインは必要な分だけ選んで導入でき、バンドルを肥大化させにくいのも利点です。

【機能①】Timeline(タイムライン)

複数のアニメーション(Tween)を時間軸に並べてまとめて管理します。開始順序・重なり・相対遅延・再生/一時停止/逆再生などをひとつの塊として扱えます。

<script>
  // タイムラインを作成。以降のアニメに共通のdurationとeaseを適用
  const tl = gsap.timeline({ defaults: { duration: 0.6, ease: "power1.out" } });

  // 見出し(.hero-title)を「下から・不透明度0→1」で表示
  // from() は「この状態から現在の状態へ」遷移させる指定
  tl.from(".hero-title", { y: 24, opacity: 0 })

    // リード文(.hero-lead)を見出しの直後に続けて表示
    // "<0.1" は直前ステップより0.1秒遅らせて開始(相対タイミング)
    .from(".hero-lead",  { y: 18, opacity: 0 }, "<0.1")

    // CTA(.hero-cta)も同様に短い遅延で続ける
    // 3要素を短い間隔で重ねることで、自然な段階表示になる
    .from(".hero-cta",   { y: 12, opacity: 0 }, "<0.1");
</script>

Timeline(タイムライン)実例

See the Pen gsap – timeline by Julia Shikanova (@jshikanova) on CodePen.

See the Pen GSAP 101 – complex timeline by GSAP (@GreenSock) on CodePen.

【機能②】ScrollTrigger(スクロール連動)

スクロール位置をトリガーにして、開始・終了・固定(pin)・同期(scrub)・スナップなどを制御します。

<script>
  // ScrollTriggerプラグインを有効化
  gsap.registerPlugin(ScrollTrigger);

  // .section-visual をわずかに拡大しながら、スクロール位置と同期させる
  gsap.to(".section-visual", {
    scale: 1.05, // 対象の拡大率
    scrollTrigger: {
      // 監視対象(この要素がビューポート内でどこに来たら開始/終了するかを判定)
      trigger: ".section-visual",

      // 開始/終了の基準:
      // "targetのtop が viewportの70%位置に来たら開始"
      start: "top 70%",
      // "targetのbottom が viewportの30%位置に来たら終了"
      end:   "bottom 30%",

      // スクロール量とアニメ進行を同期
      scrub: true,

      // セクションを固定(pin)。スクロールしてもその場に留めて演出を見せる
      // 余白は自動で確保(pinSpacing: true が既定)。不要なら false を指定
      pin:   true,
    }
  });

  // 画像やWebフォントの読込完了で高さが変わる場合、
  // 開始/終了位置を再計測してズレを防ぐ
  window.addEventListener("load", () => ScrollTrigger.refresh());
</script>

ScrollTrigger(スクロール連動)実例

See the Pen Infinite Scrolling Snapping Cards with GSAP and ScrollTrigger (smooth) by GSAP (@GreenSock) on CodePen.

See the Pen scrollTrigger.observe() – swipe gallery by Cassie Evans (@cassie-codes) on CodePen.

【機能③】Flip(レイアウト遷移の補間)

DOMの並べ替え・サイズ変更・位置変更などで生じる「瞬間移動感」を、変更前後の差分を補間して自然に見せます。

<script>
  // Flipプラグインを有効化
  gsap.registerPlugin(Flip);

  // 並べ替え対象のグリッドを取得
  const grid = document.getElementById("grid");
  // true=昇順 / false=降順 のトグル用フラグ
  let asc = true;

  // 並べ替えボタンをクリックしたら処理開始
  document.querySelector(".js-sort").addEventListener("click", () => {
    // 変更前の位置・サイズ・変形などをスナップショット
    // この後にDOMを並べ替えてから、記録時点の見た目へ「戻す」ように補間して自然に見せる
    const state = Flip.getState(".card");

    // 子要素(.card)を配列化し、data-rankでソート
    const cards = [...grid.children];
    cards.sort((a, b) => {
      const va = +a.dataset.rank, vb = +b.dataset.rank;
      return asc ? va - vb : vb - va; // フラグに応じて昇順/降順
    });

    // 並び替え後の順序でDOMを再配置(ここで見た目は一瞬で入れ替わる)
    cards.forEach(el => grid.appendChild(el));

    // 変更「前」の状態から「今」のDOM配置へ、差分を補間してアニメーション
    Flip.from(state, {
      duration: 0.6,
      ease: "power2.inOut",
      stagger: 0.03 // カードを少しずつずらして動かす
    });

    // 次回クリック時の並び順を反転
    asc = !asc;
  });
</script>

Flip(レイアウト遷移の補間)実例

See the Pen Chess movement (GSAP Flip) by Peter Norton (@graphilla) on CodePen.

See the Pen Generative Re-arranging Grids with GSAP FLIP 💚 by George Francis (@georgedoescode) on CodePen.

【機能④】ScrollTo(スムーススクロール制御)

アンカーリンクや「上へ戻る」などのスムーススクロールを、高精度&制御しやすく実装します。

<script>
  // アンカーリンク(.jump)をすべて取得し、クリック時にスムーススクロールさせる
  document.querySelectorAll(".jump").forEach(a => {
    a.addEventListener("click", e => {
      // ブラウザのデフォルトのページ内ジャンプ(瞬間移動)を無効化
      e.preventDefault();

      // クリックされたリンクのhref(例:"#section2")を取得
      const id = a.getAttribute("href");

      // ScrollToPluginを使い、windowを目的の要素まで滑らかにスクロール
      // duration: アニメ時間 / ease: 速度カーブ
      gsap.to(window, { duration: 0.8, scrollTo: id, ease: "power2.out" });
    });
  });
</script>

ScrollTo(スムーススクロール制御)実例

See the Pen ScrollTrigger – horizontal scroll with variable width sections and anchor links by GSAP (@GreenSock) on CodePen.

【機能⑤】Draggable(ドラッグ機能付与)

要素をドラッグ/スワイプ可能にし、スナップや慣性も付与できます。スライダーや並べ替えUIで使えますね。

<script>
  // 横スライダーのトラック要素を取得
  const track = document.getElementById("track");

  // 各スライド要素を配列化(幅や枚数の計算に使用)
  const slides = gsap.utils.toArray(".slide");

  // 1枚あたりの幅(px)。全スライドが同幅前提のシンプル実装
  const slideW = slides[0].offsetWidth;

  // 左方向への最大移動距離(負方向)。最後のスライド位置まで動かす
  const maxX = -(slideW * (slides.length - 1));

  // 初期位置を0にセット(GSAPで transform: translateX(0) に相当)
  gsap.set(track, { x: 0 });

  // トラックをドラッグ可能にする(Draggableプラグイン)
  Draggable.create(track, {
    type: "x",                       // 水平方向のみ
    bounds: { minX: maxX, maxX: 0 }, // はみ出し防止:左端〜右端の範囲に制限
    inertia: true,                   // 指を離した慣性スクロールを有効化
    // 近いスライド位置へ吸着させる(スナップ)
    snap: (x) => Math.round(x / slideW) * slideW
  });
</script>

Draggable(ドラッグ機能付与)実例

See the Pen GSAP – ScrollSmoother – Drag Demo by Eric Van Holtz (@vanholtzco) on CodePen.

See the Pen [gsap/inertia] ❍ Card Animations Showcase – Challenge #2 / Entry 2 by Filip Zrnzevic (@filipz) on CodePen.

See the Pen GSAP GRID by Shunya Koide (@shunyadezain) on CodePen.

横スクロールの話から一歩広げて、GSAPの輪郭(タイムライン/ScrollTrigger/Flip)をざっと見てきました。動きに“過不足”を出さないための道具として、必要な場面にだけ静かに差し込めるのがGSAPの良さです。皆さんもぜひ触ってみてくださいね。

トラックバックURL