kaibukuroのブログ

HTML/CSS/JavaScript/PHPなどのアウトプット

AstroとGSAPでアニメーション実装

経緯

実際の案件で取り入れてることも多くなってきた、静的サイトのフレームワークAstro。
特にLPなどでは、スクロールに応じたアニメーションを使うことがあると思うので、試しに実装してみました。

デモ

準備中

解説

使い方など詳しくは、公式やICSさんのページが分かりやすいのでそちらを参照ください。
GSAP - GreenSock
GSAP入門 - アニメーション制作のための高機能なJSライブラリ(前編) - ICS MEDIA

構成

  • 今回動かす対象は、矢印などのSVG要素です。
  • 個人的に、アイコンなどの要素は、属性などをCSSやJSで操作しやすい為、インラインSVG(HTMLに<svg>で設置する形式)で設置しています。
  • SVGは複雑なものであるほどコードが長くなりますが、その点、Astroではコンポーネントとして読み込む形で利用できるのが良いと思います。

例)

pages/index.astro

---
import IconArrow from "../components/IconArrow.astro";
---

<IconArrow classStr="js-anim-down center" />

components/IconArrow.astro
(「親」から、この「子」(コンポーネント)に値(props)を渡せるので、それによりclassを自由に変えられるようにしています)

---
const { classStr } = Astro.props;
---

<svg
  // (中略)
  class={classStr}
  >

GSAP基本の形

import {gsap} from "gsap";

// 横軸に200px移動
gsap.to(".box", { x: 200 })
  • jqueryみたいなメソッドが分かりやすく記述できて分かりやすい印象です。

※ちなみに、gsap発火させる要素は、単一要素だけじゃなく、複数要素でも問題なく全てに処理できました。
例)h2要素が複数ある場合:

const titleList = document.querySelectorAll('h2');

gsap.to(titleList, { x: 200 })



ここからは、よく使いそうなGSAPの機能を実装したので、その解説です。

リピート処理

  • リピートさせるためには、timeline()を使うことが必要そうでした。
  • それにより作成したインスタンスにadd()を繋げ、to()などで動かせる処理を書きます。細かい処理が楽に設定できますね。
const tl = gsap.timeline({ repeat: -1, repeatDelay: 0.5 });

tl.add(
  gsap.to(targetDown, {
    y: 0,
    autoAlpha: 1,
    duration: 1,
  }),
);
tl.add(
  gsap.to(targetDown, {
    autoAlpha: 1,
    y: 50,
    ease: "power1.out",
    duration: 1.5,
  }),
);
tl.add(
  gsap.to(targetDown, {
    autoAlpha: 0,
    y: 50,
    ease: "power1.out",
    duration: 1.5,
  }),
);

複数要素を時間差で処理

  • まずは、スクロールして画面に入った時に、アニメーションを実行したいので、、プラグインScrollTriggerクラスを読み込み、registerPlugin()で登録します。
  • staggerプロパティにより、時間差を用いて処理を実行できます。
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);

const scrollAnim = gsap.from(targetSlideInLeft, {
    autoAlpha: 0,
    xPercent: -500,
    ease: "power3",
    duration: 2,
    stagger: 0.8,
});
// スクロールトリガーの設定
ScrollTrigger.create({
    trigger: targetSlideInLeft,
    animation: scrollAnim,
    start: "top+=100 bottom",
    once: true,
    toggleActions: "play none none none",
    markers: false,
});

matchMediaで端末ごとに処理を分ける

  • 先述のScrollTriggerのメソッドとしてmatchMediaを記述し、その中に画面幅を登録することで、端末ごとの処理を書けます。
ScrollTrigger.matchMedia({
    // 769px以上
    "(min-width: 769px)": function () {
        gsap.to(targetMatchMedia, {
            autoAlpha: 1,
            x: 500,
            rotation: 360,
            duration: 3,
            scrollTrigger: {
                trigger: targetMatchMedia,
                start: "top+=100 bottom",
            },
        });
    },

    // 768px以下
    "(max-width: 768px)": function () {
        gsap.fromTo(targetMatchMedia, {
            autoAlpha: 0,
            y: -50,
            scale: 2,
            rotation: 0,
            duration: 2,
            scrollTrigger: {
                trigger: targetMatchMedia,
                start: "top bottom",
            },
        },
        {
            autoAlpha: 1,
            y: 50,
            scale: 2,
            rotation: 360,
            duration: 2,
            scrollTrigger: {
                trigger: targetMatchMedia,
                start: "top bottom",
            },
        });
    },

    // メディアのサイズに関係なく、すべてに適用する
    all: function () {
        gsap.set(targetMatchMedia, { autoAlpha: 0 });
    },
});

終わりに

GSAPはやはり扱いやすかったです。
料金が発生するサイトでの利用でなければ無料で使用可能とのことなので、ありがたいライブラリです。

参考にさせて頂いたサイト

ics.media

yumegori.com