ブログ

Blog

コンクリートに刻まれた矢印

スクロール量に応じて要素が縦に移動するアニメーション

正式な名称は不明ですが、ときどき見かける「スクロール量に応じて要素が縦に移動するアニメーション」の実装方法について解説しています。実装にはGSAPを使用しています。

実装例

下記が実装例です。

要素が縦に移動するアニメーション

対象の要素は通常の要素より縦方向への移動量が大きくなるため、より手前(画面の前面)に配置されているように見えます。

以下のサイトのHistoryセクションの画像にも同じようなアニメーションが実装されています。

余計なものは入れない。Pascoの超熟余計なものは入れない。

解説

アニメーションの対象となる要素のHTMLは次のとおりです。

デフォルト
<figure data-parallax-front>
<img src="https://picsum.photos/800/500/?random=1" alt="画像" width="495" height="309"/>
</figure>

移動させたい画像の親要素にdata-parallax-front属性を付与しています。カスタムデータ属性のdata-yで移動量を、data-delayで遅延時間をそれぞれ設定できるようにしています。

カスタムした場合
<figure data-parallax-front data-y="100px" data-delay="1">
<img src="https://picsum.photos/800/500/?random=1" alt="画像" width="495" height="309"/>
</figure>

GSAPの処理を言語化

JavaScriptでは以下のコードを実行しています。

JavaScript
const items = document.querySelectorAll("[data-parallax-front]"); // data-parallax-front属性を持つ要素を取得
// 各要素に対して処理を行う
for (const item of items) {
const y = item.getAttribute("data-y") ?? "15%"; // itemのdata-y属性を取得。未設定の場合は'15%'をデフォルト値として使用
const delay = parseFloat(item.getAttribute("data-delay")) || 0.4; // itemのdata-delay属性を数値に変換して取得。未設定の場合は'0.4'をデフォルト値として使用
const target = item.children; // itemの直下の要素を取得
gsap.fromTo(
// gsap.fromToでアニメーションを設定
target, // 対象の要素をtargetで指定
{
y: y, // アニメーション開始時のy位置
},
{
y: `-${y}`, // アニメーション終了時のy位置
scrollTrigger: {
// スクロールトリガーを設定
trigger: item, // itemをトリガーとなる要素として指定
start: "top bottom", // 要素の上端がビューポートの下端に達したときに開始
end: "bottom top", // 要素の下端がビューポートの上端に達したときに終了
scrub: delay, // スクロールに追従してアニメーションを行う(デフォルトでは0.4秒の遅延)
},
ease: "none", // イージング関数を指定しない(線形アニメーション)
}
);
}

各行の実行内容はコメントに記載の通りです。

scrubの値を定義

scrubの値を定義
const delay = parseFloat(item.getAttribute("data-delay")) || 0.4;

scrollTriggerのscrubに渡す数値を定義しています。data-delayに値を設定しなかった場合は、初期値として0.4が代入されます。

data-delayに値を設定した場合は、parseFloat()で文字列を浮動小数点に変換(文字列を数値に変換)した値を代入します。

子要素を取得

直下の子要素を取得
const target = item.children;

childrenプロパティでitemの子要素を取得しています。childrenでは全ての子要素を取得するため、data-parallax-frontの中の要素は1つにすることがポイントです。

参考サイト