【GSAP】data属性で一括管理!ScrollTriggerで作る汎用的なパララックス(視差効果)
Webサイトに奥行きや立体感を持たせる「パララックス(視差効果)」。 スクロールに合わせて要素が異なるスピードで動くリッチな演出ですが、要素ごとにJavaScriptで細かい動きを設定していくと、コードが長くなり管理が大変になってしまいます。
そこで今回は、HTMLの data 属性(data-speed)に速度の比率を持たせ、JavaScriptの処理は共通化してスッキリさせるという、非常に使いやすいGSAP ScrollTriggerの実装手法をご紹介します!
少し極端に視差をつけて動きを分かりやすくしたデモを用意したので、ぜひスクロールして動きを確かめてみてください!
デモ動作
See the Pen GSAP ScrollTriggerで作るパララックス by mikanbako (@mikanbako) on CodePen.
demo: GSAP ScrollTriggerで作るパララックス
実装コードの紹介
【HTML】
<div class="l-spacer">
<p>↓ スクロールしてパララックスを確認 ↓</p>
</div>
<!-- パララックスさせる要素の親コンテナ -->
<div class="p-parallax-wrap">
<!-- data-speed属性でそれぞれの動く速度(比率)を設定 -->
<!-- 数値が大きいほど速く(大きく)動くようにします -->
<div class="c-box js-parallax" data-speed="1.5">
<p>Speed: 1.5 (速い)</p>
</div>
<div class="c-box c-box--blue js-parallax" data-speed="0.5">
<p>Speed: 0.5 (遅い)</p>
</div>
<div class="c-box c-box--red js-parallax" data-speed="-1">
<p>Speed: -1 (逆方向)</p>
</div>
</div>
<div class="l-spacer">
<p>↑ 上に戻る ↑</p>
</div>
【CSS】
/* スクロール用の余白 */
.l-spacer {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
font-weight: bold;
color: #888;
}
/* パララックス要素のコンテナ */
.p-parallax-wrap {
display: flex;
justify-content: center;
gap: 32px;
padding: 100px 0;
}
/* ボックスの共通装飾 */
.c-box {
width: 200px;
aspect-ratio: 1;
background-color: #1bb4d4;
border-radius: 12px;
display: flex;
justify-content: center;
align-items: center;
padding: 0.5em;
color: #fff;
font-weight: bold;
font-size: 16px;
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}
.c-box--blue { background-color: #4a90e2; }
.c-box--red { background-color: #c72c4c; }
【JavaScript】
// GSAP ScrollTriggerの登録
gsap.registerPlugin(ScrollTrigger);
// クラスが付与された要素をすべて取得
const parallaxElements = document.querySelectorAll('.js-parallax');
parallaxElements.forEach(el => {
// HTMLの data-speed 属性の値を取得し、数値(Float)に変換
const speed = parseFloat(el.dataset.speed);
// 視差効果の強さ(基本となる移動距離)
// 動きを分かりやすくするため、今回は極端に「-200」という大きめの数値を掛けています
const yValue = -200 * speed;
gsap.to(el, {
y: yValue, // スクロールに合わせてY軸に移動
ease: "none", // パララックスの場合は ease を none にするのが自然に見せるコツ!
scrollTrigger: {
trigger: el, // 要素自身が画面に入ったら判定開始
start: "top bottom", // 要素の上端が、画面の下端に触れた時
end: "bottom top", // 要素の下端が、画面の上端に抜けた時
scrub: true, // スクロール量に完全に連動させるプロパティ
}
});
});
コードの解説・こだわったポイント
HTMLの data 属性で速度を管理する(保守性の向上)
<!-- data-speed属性でそれぞれの動く速度(比率)を設定 -->
<div class="c-box js-parallax" data-speed="1.5">
<p>Speed: 1.5 (速い)</p>
</div>
// HTMLの data-speed 属性の値を取得し、数値(Float)に変換
const speed = parseFloat(el.dataset.speed);
パララックスを実装する際、各要素の移動距離をすべてJavaScript内に直接記述してしまうと、要素が増えたときにコードが肥大化してしまいます。 今回のように data-speed="1.5" とHTML側に独自のデータを持たせ、JS側で el.dataset.speed として取得することで、JavaScriptの処理は共通のループ処理(数行)だけで済むようになります。
y: -200 * speed で移動距離を算出
取得したスピードの値に対して、基準となる移動量(今回は -200)を掛け算することで、要素ごとの移動距離(y の値)を算出しています。 この基準値を調整することで、サイト全体のパララックスの「強さ(極端さ)」を一括でコントロールできます。
ease: "none" を設定して自然な追従に
GSAPの初期設定では、アニメーションにイージング(徐々に遅くなるような動き)がかかっています。しかし、スクロール連動(scrub: true)のパララックスでイージングがかかっていると、スクロールを止めた後に要素が少し遅れて動く不自然な挙動になってしまいます。 そのため、ease: "none" を指定して、スクロールに対して常に一定の速度で追従するように設定するのが鉄則です。
まとめ
今回は、GSAPの ScrollTrigger と data 属性を組み合わせた、効率的なパララックスの実装方法をご紹介しました。
「スクロールに合わせて動かす」という処理自体は scrub: true で簡単に実装できますが、HTMLとJSの役割分担を意識して「どうすれば汎用的に、かつ保守しやすいコードになるか」を考えることが重要です。
これからもGSAPの強力な機能を使いこなしつつ、美しくて管理のしやすいコーディングを心掛けていきたいと思います!