スクロールすると要素が奥行きを持って立体的に重なるアニメーション
今回もおしゃれなサイトでよく見る、スクロールに応じて要素が奥行きを持って立体的に重なるアニメーションの実装方法について解説しています。実装にはGSAPを使用しています。
実装例
下記が実装例です。
スクロールに応じてグレーの背景エリアが重なり、立体感を演出しています。実際には画像やリストになっているアイテムなどをアニメーションさせることが最適かなと思います。
解説
今回はCSSで各アイテムの高さを便宜上指定していますが、必須ではありません。中の要素の高さに依存する形でOKです。
.item { width: 100%; /* 高さの指定は必須ではない */ height: 75vh; background-color: #ddd; }
GSAPの処理を言語化
GSAPのでは以下のコードを実行しています。
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つのアイテムの重なりを画面内で表現することも可能です。