ブログ

Blog

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

スクロールすると要素が奥行きを持って立体的に重なるアニメーション

今回もおしゃれなサイトでよく見る、スクロールに応じて要素が奥行きを持って立体的に重なるアニメーションの実装方法について解説しています。実装にはGSAPを使用しています。

実装例

下記が実装例です。

スクロールに応じて要素が立体的に重なるアニメーション

スクロールに応じてグレーの背景エリアが重なり、立体感を演出しています。実際には画像やリストになっているアイテムなどをアニメーションさせることが最適かなと思います。

解説

今回はCSSで各アイテムの高さを便宜上指定していますが、必須ではありません。中の要素の高さに依存する形でOKです。

CSS
.item {
width: 100%;
/* 高さの指定は必須ではない */
height: 75vh;
background-color: #ddd;
}

GSAPの処理を言語化

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

ScrollTriggerのコード
const items = gsap.utils.toArray("[data-item]"); // data-item属性を持つ要素を配列として取得
const wrapper = document.querySelector("[data-wrapper]"); // data-wrapper属性を持つ要素を取得
gsap.to(items[0], {
// itemsの最初の要素をアニメーションさせる
y: "250%", // y軸方向に250%移動(下方向)
scale: 0.82, // サイズを0.82倍に縮小
ease: "none", // イージング関数を指定しない(線形アニメーション=linear)
scrollTrigger: {
// スクロールトリガーの設定
trigger: items[0], // アニメーション開始のトリガー要素
endTrigger: wrapper, // アニメーション終了のトリガー要素
start: "center top+=50%", // トリガー要素の中央がビューポートの上から50%の位置に来たら開始
end: "bottom top+=50%", // 終了のトリガー要素の底部がビューポートの上から50%の位置に来たら終了
scrub: true, // スクロール量に応じてアニメーションを滑らかに制御
},
});
// items[1],items[2]の処理が続く

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

[data-item]属性の要素をy軸方向に250%移動させ、サイズを0.82倍に縮小しています。立体感を演出するために、移動距離と縮小率は要素ごとに変えています。

要素の中央がビューポートの中央に重なる時にアニメーションがスタートし、[data-wrapper]属性の要素の底部がビューポートの中央に重なる時にアニメーションが終了します。

今回の例では3つ目のアイテムが画面中央に来る頃には1つ目のアイテムは完全に見えなくなっていますが、y軸の移動距離と縮小率を調整することで3つのアイテムの重なりを画面内で表現することも可能です。

参考サイト