7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GSAP ScrollToPluginでページ内リンクの移動をスムージングする

Last updated at Posted at 2022-05-23

ScrollToPluginとは

ScrollToPluginとは、GSAPのプラグインの1つで、windowやDOM要素のスクロールにアニメーションを追加するものです。
(このプラグインを使用する際にClub GreenSockに加入する必要はありません。)

GSAPのプラグインにしては機能も使い方もかなりシンプルなプラグインで、GSAPのCoreモジュールの基本的な使い方を知っていれば、何も抵抗感なく、また、簡単に扱うことが可能だと思います。

使い方

基本

ウィンドウを任意の位置までスクロールさせるには、以下の様にwindowをターゲットとして指定し、scrollToにスクロール終了位置を指定します。

// 画面上部から400px下にスクロール
gsap.to(window, { duration: 2, scrollTo: 400 });

// 'someID'というIDを持つ要素までスクロール
gsap.to(window, { duration: 2, scrollTo: '#someID' });

ある要素内でスクロールさせるには、下記のようにターゲットに要素を指定します。
また、この指定した要素にはoverflow: scrollを設定する必要があります。

// elemクラスの付与された要素の上から250px下にスクロール
gsap.to('.elem', { duration: 2, scrollTo: 250 });

x方向のスクロール

x方向へのスクロールも以下のように指定することができます。

// 上から400px 左から200px
gsap.to('.elem', { duration: 2, scrollTo: { y: 400, x: 200 }, ease: 'power2' });

最大値までスクロール

最大値(一番下)までスクロールさせたい場合は、maxを指定することもできます。

gsap.to('.elem', { duration: 2, scrollTo: { y: 'max' } });
// もしくは
gsap.to('.elem', { duration: 2, scrollTo: 'max' });

オフセット

offsetXoffsetYを指定することでスクロール先の位置からのオフセットを指定することができます。

// #section1要素の上50pxオフセットをつけてスクロール
gsap.to(window, { duration: 2, scrollTo: { y: '#section1', offsetY: 50 } });

アニメーションのキャンセル

autoKilltrueに設定することで、ScrollToPluginによるアニメーション中にスクロールバーを直接ドラッグしたりしてスクロール位置を変更しようとしたときに、これを検知してアニメーションをキャンセルさせることができます。

gsap.to(window, { duration: 2, scrollTo: { y: 400, autoKill: true }, ease: 'power2' });

また、このautoKillがいつ発火したかはonAutoKillで検出することができます。

gsap.to(window, { duration: 2, scrollTo: { y: 400, autoKill: true, onAutoKill: autoKillFunction }, ease: 'power2' });

サンプル

See the Pen ScrollToPlugin_Tutorial by heeroo-ymsw (@heeroo-ymsw) on CodePen.

軽い解説

ページ内リンクのスクロールにアニメーションをつけてみました。

aタグにそのままScrollToのアニメーションをつけてもそのまま瞬時に遷移してしまうので、デフォルトのクリック処理をpreventDefault()でキャンセルしています。

navLink.addEventListener("click", (e) => {
  e.preventDefault();

また、ヘッダメニューが画面上部に追従してくるので、ScrollToにはヘッダ分のoffsetを追加しています。

gsap.to(window, {
  duration: 1,
  ease: "power3.inOut",
  scrollTo: {
    y: navLink.getAttribute("href"),
    offsetY: 96,
    autoKill: true
  }
});

こちらは基本的なJavaScriptの扱い方になりますが、href属性の値を取得する際、念の為getAttribute()の前にhasAttribute()でhrefに値が入っていることを確認しています。

getAttribute()の説明として、MDN Web Docsでは、以下のように記されています。

属性が存在しない場合、値は null か "" (空文字列)のどちらかになります。(中略)結果的に、指定された要素に指定された属性が存在しない可能性があるのであれば、 element.hasAttribute() を使用して属性の存在をチェックしてから getAttribute() を呼び出すべきでしょう。1

また、startsWith()にnullを渡すとエラーになってしまうため、どっちみち存在チェックをしておく方が良いでしょう。
存在が確認できれば、仮に<a href>link</a>という指定だったとしても、getAttribute("href")は空文字を返します。つまり、startsWith()はエラーを吐かないということです。

if (navLink.hasAttribute("href") && navLink.getAttribute("href").startsWith("#")) {

論理積演算子は左から順番に評価し、falseが現れた時点でそれ以降の式は評価せず、この評価式全体はfalseと判断されます。
つまり、この一文では、「href属性の存在チェックを行い、それがtrueだった時に初めてhref属性値がハッシュから始まるアンカーを指定しているかを確認する」、ということになります。

まとめ

GSAPのプラグインであるScrollToPluginを使用して、ページ内リンクへのスムーススクロールを行う方法を紹介しました。

jQueryのscrollTop、animateとeasing pluginなどを用いれば同じようなことができますが、Vanilla JSで既にGSAPのCoreモジュールをインポートしている場合や、GSAPの使用感が手に馴染んでいる方などは十分使用を検討する選択肢に入ると思いますので、ぜひ活用してみてください。

  1. Element.getAttribute() - Web API | MDNより抜粋

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?