見出し画像

gsapのScrollTriggerプラグインとlottie-reactを利用したスクロールアニメーションの実装について

こんにちわ。nap5です。



gsapのScrollTriggerプラグインとlottie-reactを利用したスクロールアニメーションの実装について紹介したいと思います。


Twitterにも投稿してみました。


gsapのScrollTriggerプラグインについてはこちらのリンクになります。


lottie-reactについてはこちらのリンクになります。


以下のデモですが、不安定のため、zipにしたものも添付します。zipファイルダウンロード後、展開します。展開後のディレクトリに移動した後、以下のコマンド打つとデモが動きます。



$ cd 展開後のディレクトリ
$ yarn install
$ yarn dev


以下のcodesandboxのデモが見れない場合のフォールバックとしてrenderというホスティングサービスでデプロイしたものも用意しました。





デモサイトです。


デモコードです。


実装のポイントとしては2点あります。

1つ目はサイズをレスポンシブに調節することです。

emotionのcss文字列内挿でクラス指定できるのがハンディです。


// https://lottiereact.com/hooks/useLottie#params
  const {goToAndStop, animationContainerRef, View, animationItem} = useLottie(
    {
      animationData,
      loop: false,
      autoplay: false,
      className: css`
        width: 400px;
        height: 400px;
        @media (max-width: 768px) {
          width: 300px;
          height: 300px;
        }
      `,
    },
    {}
  );


もう一つはScrollTriggerのハンドリングをPCとSPのそれぞれ調節することです。

animationItemがマウントされたら、PCとSPのそれぞれでフレームを進捗率をもとに計算して、計算したフレームまで再生シークを進める実装になります。


  useEffect(() => {
    if (!animationItem) {
      return;
    }
    gsap.registerPlugin(ScrollTrigger);
    const itemDom = itemDomRef.current;
    // https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.matchMedia()
    ScrollTrigger.matchMedia({
      '(min-width: 769px)': function () {
        gsap.timeline({
          scrollTrigger: {
            trigger: itemDom,
            start: 'top 10%',
            end: 'bottom+=300% top',
            pin: true,
            markers: true,
            scrub: true,
            onUpdate: function (e) {
              const p = e.progress;
              const maxFrames = animationItem.totalFrames;
              const frame = maxFrames * p;
              // console.log(p, frame, maxFrames);
              animationItem.goToAndStop(frame, true);
            },
          },
        });
      },

      '(max-width: 768px)': function () {
        gsap.timeline({
          scrollTrigger: {
            trigger: itemDom,
            start: 'top 20%',
            end: 'bottom+=900% top',
            pin: true,
            markers: true,
            scrub: true,
            onUpdate: function (e) {
              const p = e.progress;
              const maxFrames = animationItem.totalFrames;
              const frame = maxFrames * p;
              // console.log(p, frame, maxFrames);
              animationItem.goToAndStop(frame, true);
            },
          },
        });
      },
    });

    return () => {};
  }, [animationItem]);




最近では、MENTAをはじめてみました。MENTAを使って提供していることを紹介している記事は以下になります。


また、Twitterでモックアップ動画を公開しているので、こちらもよかったら、覗いてみてください。


最後に、Udemyでコースを公開しました。
良かったら覗いてみてください。

https://www.udemy.com/course/count-down-up-using-javascript-animation-api/


また、コースの内容紹介記事は以下になります。

簡単ですが、以上です。

この記事が気に入ったらサポートをしてみませんか?