💈

GSAP 日記 Part.1 無限スクロールアニメーションを作ってみた

2022/08/31に公開

https://dennissnellenberg.com/
先日この方のホームページを見てまして、いろんながアニメーションがありまして、素敵だなと思いました。
BuiltWithで解析してみたら、アニメーションはGSAPを利用しているそうです。GSAPを聞いたことありますが、実際に使ったことないので今回GSAPをいろいろ遊んでみたいと思います。
Part1 は無限に名前がスクロールしているアニメーションを作ってみます。

アニメーションの分析

作りたいアニメーションはこの部分:

ご覧の通り文字が無限にスクロールしていて、そして上下にスクロールしたらスクロール方向が反転されます。
そのため二段階でこのアニメーションを作りたいと思います。

  1. 無限にスクロールさせる
  2. 上下にスクロールしたら方向を反転させる

GSAP

概要

GSAP(GreenSock Animation Platform)は、GreenSock社が開発している軽量で多機能なJavaScriptアニメーションライブラリです。基本の機能を加えて、様々なプラグインもあるので、発想通りにアニメーションを実装できます。ちなみに、GSAP(ジーサップ)と読むらしいです。
https://greensock.com/gsap/

インストール

インストール方法がいくつかあります。ソースをダウンロードして使うか、パッケージ管理ツール(NPM/yarn)でインストールするか、CDN経由で読み込みなどプロジェクトにふさわしい方法を選んで良いと思います。
インストールの詳しい情報はドキュメントを参考していただければと思います。
https://greensock.com/docs/v3/Installation
今回は簡単に NPM でインストールしたいと思います。

npm install gsap

実装

下準備

まずはベースを作ります。

スクロールさせる

ベースがありましたので、スクロールさせましょう。

GSAPの使い方

GSAPアニメーションの基本が Tween というものです。Tweenは、すべてのアニメーション処理を行うもので、高性能なプロパティセッターのようなものだと考えてください。ターゲット(動かせたいオブジェクト)、動作時間、各種プロパティを入力すると、新しい位置に移動したときのプロパティの値を計算し、それに応じて適用します。
Tween を作る基本のメソッドは gsap.to()gsap.from()gsap.fromTo()の三つです。それぞれの名称通り:

  • gsap.to()が今の状態(位置・色・サイズなど)から どのような状態になる (終点) を定義する。
  • gsap.from()どのような状態から(起点) 今の状態になるを定義する。
  • gsap.fromTo()はい最初と最後の状態を両方定義する。

とりあえず動かせましょう

まず基本の gsap.to()を使ってみましょう。

gsap.to('.name-wrap', { x: 200, duration: 2, repeat: 5, ease: 'none' });

第一引数はターゲットになります。".class""#id"で指定します。GSAPはdocument.querySelectorAll()を利用してターゲットを選択します。その他、直接にelementやelementnのリストを渡してOK。
第二引数はプロパティのオブジェクトです。様々な属性を設定できます。
以上の例だと:

  • x: x軸の移動を指定、translateXと似たような感じでピクセルやパーセンテージで指定できます。x: "-=20"(ターゲット要素より左20ピクセル)などでも指定可能です。
  • duration: 動作時間を指定します。
  • repeat: リピート回数を指定します。-1を指定すると無限にリピートします。
  • ease: イージングを指定します。イージング動作のパターンが変わります。公式の可視化ツールで確認できます。

この1行だけ入れると、もう動けるようになりましたね!

ループしてるを見えるように

今時点ではスクロールしていますが、ループのように見えませんですね・・・
文字が右にスクロールするともに、Windowの左から文字が入るとループのように見えそうですね。
ではもう1個 div を入れましょう。

index.html
<div class="name-container">
  <div class="name-wrap">
    <h1 class="name-text">Hello World !</h1>
  </div>
  <div class="name-wrap name-wrap-right">
    <h1 class="name-text">Hello World !</h1>
  </div>
</div>

css で位置を調整します。2個目が左からWindowに入るので、rightで位置を固定します。
(位置を調整せず、2個目の Tween を作るのも目的達成できますが、ちょっと複雑になります。)

style.css
.name-container {
  display: flex;
  width: 100%;
  position: relative;
}
.name-wrap {
  white-space: nowrap;
  width: 100%;
  position: relative;
}
.name-wrap-right {
  position: absolute;
  right: 100vw;
}

でこんな感じになりました。

おお!結構良い感じにできていますね!

上下スクロールしたら方向反転させる

次は上下スクロールしたら、スクロールの方向を反転させるように実装。
別の記事で紹介した IntersectionObserver APIonScrollでも実装できそうですが、
https://zenn.dev/articles/6e5b5906c8b384/edit
せっかく GSAP を使っているのでプラグインの ScrollTrigger を利用して実装したいと思います。

ScrollTrigger

ScrollTriggerは GSAP のプラグインで、名前通りスクロール様関連のトリガー機能を提供しています。これがあると、スクロールによる様々な演出を簡単に実装できます。
Importするだけで簡単に入れます。

import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);

ScrollTriggerを作る

ScrollTrigger は多数な機能があり、カスタマイズもできますが、この記事では深く触りません。今後の記事にまた紹介します。
簡単なトリガーを作ります。

ScrollTrigger.create({
  trigger: '.name-wrap',
  start: '-99999 top',
  onUpdate: (self) => {
    self.direction === -1 ? a1.reverse() : a1.play();
  },
});

設定したパラメータは

  • trigger: トリガーオブジェクト、今回はスクロールするdivにします。
  • start: トリガーのスタート場所。前の方はトリガーオブジェクトからの相対位置。後ろの方はWindowの位置。両方ともピクセルやtopcenterbottomで指定できます。今回はページがローディングされたら有効にさせたいので、start 場所を1番上に設定します。
  • onUpdate: 字面通りスクロールトリガーが発火した(今回は1番上にスタート場所を設定したのでローディング後すぐ発火する)後スクロールしたらの動作を定義する。中にself.directionでスクロールの方向を判断します。下にスクロールしたら値が1になって、上にスクロールしたら値が-1になります。.play().reverse()はアニメーションの再生とリバースをコントロールするメソッドです。

最終はこんな感じになります:

上下スクロールしてみてくださいー

最後に

GSAPを1時間ぐらい学んでこのアニメーションを作ってみました。GSAPの強さ、使いやすさを確かに感じました。次に面白いアニメーションを見つけたらまたGSAPで作ってみたいと思いますー

Discussion