【GSAP】スクロール速度で要素を回す!ScrollTriggerの getVelocity() を使ったUI実装
以前の記事で、GSAPの ScrollTrigger を使って「スクロール全体の進捗(progress)」を取得し、プログレスバーを作る方法をご紹介しました。 今回はその応用編として、「スクロールの速度と方向(velocity)」 を取得する方法をご紹介します!
関連記事
【GSAP】onUpdate で進捗を取得!スクロール連動の円形プログレスバーを作る方法
ScrollTrigger の getVelocity() メソッドを使うと、「今どれくらいの勢いでスクロールしているか」「上と下、どちらの方向にスクロールしているか」を数値として簡単に取得できます。
今回はこれを利用して、画面右下に固定した要素を「スクロールの勢いに合わせて右回転・左回転させる」という、少し遊び心のあるインタラクティブなUI実装をしてみましょう!
デモ動作
See the Pen ScrollTriggerのvelocityでスクロール速度を取得する by mikanbako (@mikanbako) on CodePen.
demo: ScrollTriggerのvelocityでスクロール速度を取得する
実装コード紹介
【HTML】
<!-- スクロールを発生させるための全体ラッパー -->
<div class="l-wrap js-trigger-wrap">
<h2>ScrollTrigger: getVelocity() デモ</h2>
<p class="p-desc">上下に激しく、またはゆっくりスクロールしてみてください!<br>右下の要素がスクロール速度に連動して回転します。</p>
<!-- スクロール領域を確保するためのダミーコンテンツ -->
<div class="p-scroll-space">
<span>Scroll Down ↓</span>
</div>
<div class="p-scroll-space">
<span>Keep Scrolling ↓</span>
</div>
<div class="p-scroll-space">
<span>Scroll Up ↑</span>
</div>
</div>
<!-- Velocity値表示用テキスト要素 -->
<div class="c-velocity-value">Velocity: <span class="js-velocity-value"></span></div>
<!-- 画面右下に固定する回転要素 -->
<div class="c-gear js-gear">⚙️</div>
【CSS】
.l-wrap {
width: 100%;
padding-top: 40px;
color: #3e3e3e;
text-align: center;
}
h2 {
margin-bottom: 16px;
font-size: 16px;
color: #1bb4d4;
}
.p-desc {
margin-bottom: 40px;
font-size: 16px;
font-weight: bold;
color: #666;
line-height: 1.6;
}
/* スクロール用の余白 */
.p-scroll-space {
height: 80vh; /* スクロールさせるために高さを出す */
display: flex;
justify-content: center;
align-items: center;
font-size: 32px;
font-weight: bold;
color: #ccc;
border-top: 1px dashed #ddd;
}
/* Velocity値表示用テキスト要素 */
.c-velocity-value {
position: fixed;
bottom: 140px;
right: 40px;
font-size: 15px;
color: #ccc;
}
/* 💡 回転させる右下の要素(固定配置) */
.c-gear {
position: fixed;
bottom: 40px;
right: 40px;
font-size: 60px;
/* GSAPで動かす際、中心を基準に回転させる設定 */
transform-origin: center center;
z-index: 100;
/* ※CSSのtransitionは書かない!(GSAPと衝突するため) */
}
【JavaScript】
// プラグインの登録
gsap.registerPlugin(ScrollTrigger);
// Velocity値表示用テキスト要素
const velocityValueText = document.querySelector('.js-velocity-value');
// .l-wrap 全体をトリガーにして設定
ScrollTrigger.create({
trigger: ".js-trigger-wrap",
start: "top top",
end: "bottom bottom",
onUpdate: (self) => {
// 1. スクロール速度(velocity)を取得
// 下スクロール時はプラスの値、上スクロール時はマイナスの値になります
const velocity = self.getVelocity();
// 値表示用テキスト更新
velocityValueText.textContent = Math.round(velocity);
// 2. 取得した速度を使って要素を回転させる
gsap.to('.js-gear', {
// "+=" を使うことで、現在の角度に「速度 × 係数」を足し続ける
// 0.05は回転具合を調整するための係数です。お好みで変更可能!
rotation: `+=${velocity * 0.05}`,
// 滑らかに減速して止まるための設定
ease: "power2.out",
duration: 0.5,
// 連続でスクロールされた時にアニメーションを上書きして自然に繋ぐ
overwrite: "auto"
});
}
});
コードの解説・仕組み
self.getVelocity() が返す値
onUpdate: (self) => {
// 1. スクロール速度(velocity)を取得
// 下スクロール時はプラスの値、上スクロール時はマイナスの値になります
const velocity = self.getVelocity();
...
onUpdate 内で取得できる velocity は、ピクセル/秒(px/s)のスクロール速度を表しています。 最大のポイントは、方向によって値の「プラス / マイナス」が変わるという点です!
- 下へスクロール: プラスの値(例:
1500) - 上へスクロール: マイナスの値(例:
-1500)
rotation: "+=" で回転を更新させる
// 2. 取得した速度を使って要素を回転させる
gsap.to('.js-gear', {
// "+=" を使うことで、現在の角度に「速度 × 係数」を足し続ける
// 0.05は回転具合を調整するための係数です。お好みで変更可能!
rotation: `+=${velocity * 0.05}`,
// 滑らかに減速して止まるための設定
ease: "power2.out",
duration: 0.5,
// 連続でスクロールされた時にアニメーションを上書きして自然に繋ぐ
overwrite: "auto"
});
GSAPの rotation に +=${velocity * 0.05 と指定しています。 こうすることで、下スクロール時は角度がどんどん足されて右回転し、上スクロール時は角度が引かれて左回転するという動きを実装できます!
※ velocity の数値は激しくスクロールすると数千という大きな値になるため、そのまま使うと要素が高速回転しすぎます。そのため、0.05 のような係数を掛けて調整するのがコツです。
補足:公式ドキュメント
より詳しい仕様や最新の対応状況については、以下の公式ドキュメントをご参照ください。
まとめ
今回は ScrollTrigger の velocity を使った少し特殊なUI実装をご紹介しました。
以前の progress が「ページのどの位置にいるか」という「絶対的な位置」を取得するのに対し、今回の velocity は「今どんな勢いで動いているか」という「瞬間的な値」を取得します。
これらを使い分けたり組み合わせたりすることで、ユーザーの操作にピタッと吸い付くような、気持ちの良いUIを作ることができます。ぜひ皆さんのWeb制作でも取り入れてみてください!