お役立ちコラム
JavaScript

matchMediaを使ってGSAPアニメーションをレスポンシブ対応させる方法

※本記事には広告が含まれます

アニメーションを作っている際に、PCとSPで微妙にアニメーションの動きやscrollTrggerプラグインのトリガー要素を変えたいことがあります。

こんなときGSAPを使っている場合は、mathMediaメソッドを使うことで簡単にPCとSPで異なるアニメーションを実装できます。

今回は、GSAPアニメーションをレスポンシブ対応させるのに便利なメソッドmatchMedia()の使い方を解説します。

※本記事執筆時点のGSAPバージョンは、「3.13.0」です。ご利用の時期や環境によっては、内容が異なる場合がありますので、あらかじめご了承下さい。

GSAPのmatchMedia()メソッドの使い方

今回は以下のようなデモを作成しながら、GSAPのmatchMedia()の使い方を解説します。

PC(768px以上)の場合は、水色のボックス要素が右下に回転しながら移動します。

一方、SP(767px以下)の場合は、水色のボックス要素が下から上に回転しながら移動します。

※下の「0.25×」や「0.5×」をクリックするとPC表示時のアニメーションを、「1.0×」をクリックするとSP表示時のアニメーションを確認できます。

See the Pen GSAP matchMedia 使い方デモ by E-VALUE WORKS (@evw) on CodePen.

なお、スタート時点のファイル構成として、HTML・CSS・JavaScriptは以下の内容を使用します。

■HTML

<div class="box"></div>

■CSS

.box {
  width: 100px;
  height: 100px;
  background: #18c1f0;
  opacity: 0;
}

■JavaScript

document.addEventListener("DOMContentLoaded", () => {
  gsap.fromTo(
    ".box",
    { opacity: 0, scale: 0.5 },
    {
      opacity: 1,
      x: 200,
      y: 150,
      scale: 1,
      rotation: 360,
      duration: 1.5,
      ease: "power2.out",
    }
  );
});

現時点では、PC(768px以上)でもSP(767px以下)でも水色のボックス要素が右下に回転しながら移動するようになっています。

STEP. 1:matchMedia()メソッドを呼び出し専用のオブジェクトを作成する

まずは、matchMedia()メソッドを呼び出して専用のオブジェクトを作成します。

本例では、作成したオブジェクトを格納する変数名をmmとしておきます。

document.addEventListener("DOMContentLoaded", () => {
  const mm = gsap.matchMedia();

  gsap.fromTo(
    ".box",
    { opacity: 0, scale: 0.5 },
    {
      opacity: 1,
      x: 200,
      y: 150,
      scale: 1,
      rotation: 360,
      duration: 1.5,
      ease: "power2.out",
    }
  );
});

このオブジェクトにadd()メソッドを使って、画面サイズごとにアニメーションを登録することができます。

STEP. 2:add()メソッドを使って、画面サイズごとのアニメーションを登録する

続いて、add()メソッドを使って画面サイズごとのアニメーションを登録します。

add()メソッドの第1引数には、条件を示すメディアクエリ文字列(例:”(min-width: 768px)”)を、第2引数にはその条件が一致したときに実行する関数を指定します。

document.addEventListener("DOMContentLoaded", () => {
  const mm = gsap.matchMedia();

  mm.add("(min-width: 768px)", () => {
    gsap.fromTo(
      ".box",
      { opacity: 0, scale: 0.5 },
      {
        opacity: 1,
        x: 200,
        y: 150,
        scale: 1,
        rotation: 360,
        duration: 1.5,
        ease: "power2.out",
      }
    );
  });
});

これで、画面幅が768px以上(PC表示) のときだけ、gsap.fromTo()で作成したアニメーションが実行されます。

続いて、767px以下(SP表示)のときのアニメーションも登録します。

document.addEventListener("DOMContentLoaded", () => {
  const mm = gsap.matchMedia();

  mm.add("(min-width: 768px)", () => {
    gsap.fromTo(
      ".box",
      { opacity: 0, scale: 0.5 },
      {
        opacity: 1,
        x: 200,
        y: 150,
        scale: 1,
        rotation: 360,
        duration: 1.5,
        ease: "power2.out",
      }
    );
  });

  mm.add("(max-width: 767.99px)", () => {
    gsap.fromTo(
      ".box",
      { opacity: 0, scale: 0.5, y: 100 },
      {
        opacity: 1,
        y: 0,
        scale: 1,
        rotation: 360,
        duration: 1.5,
        ease: "power2.out",
      }
    );
  });
});

これで、PCとSPで別々のアニメーションを実装できました。

See the Pen GSAP matchMedia 使い方デモ by E-VALUE WORKS (@evw) on CodePen.

なお、GSAPのmatchMedia()では、登録したメディアクエリの条件が変化した場合、該当しなくなったアニメーションは自動的にアニメーション前の状態に戻され、現在の条件に合うアニメーションが再実行されます。

参考:各アニメーションで重複したコードを効率よくまとめる方法

STEP. 2まででアニメーション自体は完成していますが、今回のようにPCとSPで動きを少しだけ変えたい場合、add()で追加した処理の中で、いくつかの記述が重複してしまいます。

その場合、conditions構文(条件付きオブジェクト)を使うことで、同じ設定を1つの関数内にまとめ、条件に応じて分岐させることができます。

上の例では、各メディアクエリごとにadd()を個別に追加しましたが、add()メソッドの第1引数に文字列ではなく、条件オブジェクト(conditions object)を指定します。

document.addEventListener("DOMContentLoaded", () => {
  const mm = gsap.matchMedia();

  mm.add(
    {
      isDesktop: "(min-width: 768px)",
      isMobile: "(max-width: 767.99px)",
    },
    () => {}
  );

  // 一旦コメントアウトをしておく
  // mm.add("(min-width: 768px)", () => {
  //   gsap.fromTo(
  //     ".box",
  //     { opacity: 0, scale: 0.5 },
  //     {
  //       opacity: 1,
  //       x: 200,
  //       y: 150,
  //       scale: 1,
  //       rotation: 360,
  //       duration: 1.5,
  //       ease: "power2.out",
  //     }
  //   );
  // });

  // mm.add("(max-width: 767.99px)", () => {
  //   gsap.fromTo(
  //     ".box",
  //     { opacity: 0, scale: 0.5, y: 100 },
  //     {
  //       opacity: 1,
  //       y: 0,
  //       scale: 1,
  //       rotation: 360,
  //       duration: 1.5,
  //       ease: "power2.out",
  //     }
  //   );
  // });
});

そうすると、各条件の真偽値(true / false)が、第2引数として渡される関数内のcontext.conditionsから取得できるようになります。

context.conditionsには{isDesktop: true,isMobile: false}のような形で真偽値が保存されているため、そ の値を分割代入で受け取ります。

document.addEventListener("DOMContentLoaded", () => {
  const mm = gsap.matchMedia();

  mm.add(
    {
      isDesktop: "(min-width: 768px)",
      isMobile: "(max-width: 767.99px)",
    },
    (context) => {
      const { isDesktop, isMobile } = context.conditions;
    }
  );

  // 一旦コメントアウトをしておく
  // mm.add("(min-width: 768px)", () => {
  //   gsap.fromTo(
  //     ".box",
  //     { opacity: 0, scale: 0.5 },
  //     {
  //       opacity: 1,
  //       x: 200,
  //       y: 150,
  //       scale: 1,
  //       rotation: 360,
  //       duration: 1.5,
  //       ease: "power2.out",
  //     }
  //   );
  // });

  // mm.add("(max-width: 767.99px)", () => {
  //   gsap.fromTo(
  //     ".box",
  //     { opacity: 0, scale: 0.5, y: 100 },
  //     {
  //       opacity: 1,
  //       y: 0,
  //       scale: 1,
  //       rotation: 360,
  //       duration: 1.5,
  //       ease: "power2.out",
  //     }
  //   );
  // });
});

あとは、共通の設定はそのまま残し、条件ごとに異なる部分だけを論理演算AND演算子や三項演算子(条件演算子)を使って切り替えます。

document.addEventListener("DOMContentLoaded", () => {
  const mm = gsap.matchMedia();

  mm.add(
    {
      isDesktop: "(min-width: 768px)",
      isMobile: "(max-width: 767.99px)",
    },
    (context) => {
      const { isDesktop, isMobile } = context.conditions;

      gsap.fromTo(
        ".box",
        { opacity: 0, scale: 0.5, ...(isMobile && { y: 100 }) }, // スマホときだけy: 100を追加
        {
          opacity: 1,
          ...(isDesktop && { x: 200 }), // PCのときだけx: 200を追加
          y: isDesktop ? 150 : 0, // PCとSPで値を切り替え
          scale: 1,
          rotation: 360,
          duration: 1.5,
          ease: "power2.out",
        }
      );
    }
  );
});

これでより効率的にmatchMediaを使いこなすことができました。

まとめ

今回はGSAPのmatchMedia()メソッドを使って、PCとSPで異なるアニメーションを実装する方法を解説しました。

今回のサンプルではfromTo()メソッドを使って、PCとSPで異なるアニメーションを実装する方法で解説しましたが、scrollTriggerなどを使っている場合であれば、PCとSPで異なるトリガー要素を設定できたり非常に便利です。

また、GSAPのアニメーションだけでなく、通常のJavaScript関数なども記述できるため、画面幅に応じて初期化処理を行いたい場合などにも便利です。

この機会にぜひ使い方を覚えて見て下さい。

今回は以上になります。最後までご覧頂き、ありがとうございました。

HOMEお役立ちコラムJavaScriptmatchMediaを使ってGSAPアニメーションをレスポンシブ対応させる方法