GSAPで実装するシンプルなパララックスアニメーション
おしゃれなサイトでよく見る、画像のパララックスアニメーションの実装方法について解説しています。
この記事で解説しているパララックスとは、スクロールした際に画像が遅れて移動する動きを指します。WEBサイトに奥行きが生まれて、リッチなイメージを演出することができます。実装にはGSAPを使用しました。
実装例
早速ですが下記が実装例です。
デフォルトとカスタムの2パターンを用意しており、それぞれの設定値は次のとおりです。カスタムの方がより動きの大きいものになっています。
| パターン | y軸の移動量 | 画像の拡大率 | 遅延 |
|---|---|---|---|
| デフォルト | 5% | 1.1倍 | 1.5秒 |
| カスタム | 10% | 1.2倍 | 2.5秒 |
解説
HTMLは次のとおりです。
<!-- デフォルト --><figure class="img" data-parallax> <img src="https://picsum.photos/800/500/?random=1" alt="画像" width="800" height="500" decoding="async" /></figure>
<!-- カスタム --><figure class="img" data-parallax data-y="10%" data-scale="1.2" data-delay="2.5"> <img src="https://picsum.photos/800/500/?random=1" alt="画像" width="800" height="500" decoding="async" /></figure>パララックスさせたい画像の親要素にdata-parallax属性を付与しています。カスタムする場合はdata-yで移動量を、data-scaleで拡大率を、data-delayで遅延時間をそれぞれ個別に設定できるようにしています。
JavaScriptでは次のコードを実行しています。事前にGSAP本体とScrollTriggerを読み込んでいます。
const mm = gsap.matchMedia();
mm.add("(prefers-reduced-motion: no-preference)", () => { const items = document.querySelectorAll("[data-parallax]"); // data-parallax属性を持つ要素を取得
// 各パララックス要素に対して処理を行う for (const item of items) { const y = item.getAttribute("data-y") ?? "5%"; // itemのdata-y属性を取得。未設定の場合は'5%'をデフォルト値として使用 const scale = item.getAttribute("data-scale") ?? 1.1; // itemのdata-scale属性を取得。未設定の場合は'1.1'をデフォルト値として使用 const delay = item.getAttribute("data-delay") ?? 1.5; // itemのdata-delay属性を取得。未設定の場合は'1.5'をデフォルト値として使用 const img = item.querySelector("img"); // itemの中にあるimg要素を取得
gsap.set(item, { overflow: "hidden" }); // itemのoverflowをhiddenに設定。ちらつきが発生する場合はCSSで設定 gsap.set(img, { scale: scale }); // imgのscaleに上記で設定した「scale」を適用
gsap.fromTo( // gsap.fromToでアニメーションを設定 img, // 対象の要素をimgで指定 { y: `-${y}`, // アニメーション開始時のy位置 }, { y: y, // アニメーション終了時のy位置 scrollTrigger: { // スクロールトリガーを設定 trigger: item, // itemをトリガーとなる要素として指定 start: "top bottom", // 要素の上端がビューポートの下端に達したときに開始 end: "bottom top", // 要素の下端がビューポートの上端に達したときに終了 scrub: delay, // スクロールに追従してアニメーションを行う(本実装の初期値は1.5秒) }, ease: "none", // イージング関数を指定しない(線形アニメーション) }, ); }});JavaScriptの処理を言語化
y軸の移動量(y)と拡大率(scale)と遅延時間(delay)の初期値を、Null合体演算子を用いて設定しています。??の左辺がnullまたはundefinedの場合に右辺の値を返します。なおdata-scaleとdata-delayは文字列として取得されますが、GSAPが内部で数値に変換してくれるため、明示的な変換は省略しています。
GSAPアニメーションでは、fromToを使用し、アニメーション前後のCSSプロパティを指定しています。
scrollTriggerではscrubを使用し、スクロール量に応じて各プロパティをアニメーションさせています。scrubには遅延時間(秒)を渡すことができ、本実装では未指定時に1.5秒を適用しています。
easeはnoneを指定することで、アニメーションの変化の速度を一定(線形)に保っています。GSAPのデフォルトではアニメーションの終盤にかけて減速する挙動(power1.out)となっています。noneを指定しない場合、アニメーション終盤にあたる「画像がビューポート上部に来た際」の動きが鈍くなり、スクロールと画像の動きがずれてしまい違和感の原因となります。
今回は移動量と拡大率と遅延時間のみをカスタマイズできるようにしてみました。より細かな制御をしたい場合は、simpleParallax等のライブラリを使用することをおすすめします。
アクセシビリティ上の注意
パララックスはめまいを誘発する可能性がある代表的なアニメーションで、WCAGでもprefers-reduced-motion: reduceへの配慮が推奨されています。
今回のコードでもgsap.matchMedia()で分岐し、OSで「視差効果を減らす」が有効になっていない場合にのみアニメーションを実行するようにしています。
