ドラッグを離したあと、スーッと動き続けるUIを見たことはありませんか?
iOSのスクロールやカードUIなどでよく使われている「慣性(Momentum)」です。
この記事では、JavaScriptでこの動きをゼロから実装します。
まずは基本的なドラッグ操作を知りたい方は、
こちらの記事から読むのがおすすめです。
1.実装の全体像
やることはシンプルです。
- ドラッグ中 → 位置と速度を更新
- ドラッグ終了 → 速度を使って動き続ける
- 徐々に減速(摩擦)
この実装では「速度(Velocity)」の考え方を使います。
速度について詳しく知りたい方はこちら👇
HTML
<div class="container">
<div class="card" id="card">Drag me</div>
</div>CSS
body {
margin: 0;
height: 200vh;
display: flex;
justify-content: center;
align-items: center;
font-family: sans-serif;
}
.container {
width: 300px;
height: 200px;
overflow: hidden;
border: 1px solid #ccc;
position: relative;
}
.card {
width: 100px;
height: 100px;
background: #333;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
cursor: grab;
position: absolute;
left: 0;
top: 50px;
user-select: none;
}JavaScript
const card = document.getElementById("card");
let isDragging = false;
let startX = 0;
let currentX = 0;
let prevX = 0;
let velocity = 0;
let position = 0;
card.addEventListener("mousedown", (e) => {
isDragging = true;
startX = e.clientX - position;
card.style.cursor = "grabbing";
});
window.addEventListener("mouseup", () => {
isDragging = false;
card.style.cursor = "grab";
});
window.addEventListener("mousemove", (e) => {
if (!isDragging) return;
prevX = currentX;
currentX = e.clientX;
position = currentX - startX;
velocity = currentX - prevX;
});
function update() {
if (!isDragging) {
position += velocity;
velocity *= 0.95;
if (Math.abs(velocity) < 0.1) {
velocity = 0;
}
}
card.style.transform = `translateX(${position}px)`;
requestAnimationFrame(update);
}
update();2.ポイント解説
① 速度(Velocity)の取得
velocity = currentX - prevX;「前フレームとの差分」が速度
② 慣性の実装
position += velocity;ドラッグ終了後も動き続ける
減速の仕組みは、イージングの考え方と似ています。
③ 摩擦(Friction)
velocity *= 0.95;徐々に減速する
3.実験:慣性を体験する
ドラッグを離したあと、どれくらい自然に動くか観察してみてください。
- 速く離す → 長く滑る
- ゆっくり離す → すぐ止まる
- friction値を変えると体験が変わる
※スマートフォンでも動作するように、実装には Pointer Events を使っています。
mousedown / mousemove だけではタッチ操作に対応できないため、PC とスマホの両方で使える形にしています。
velocity *= 0.98; // 長く滑る
velocity *= 0.90; // すぐ止まる4.よくある失敗
❌ 急に止まる
👉 frictionが強すぎる
❌ 動きがカクつく
👉 requestAnimationFrameを使っていない
❌ ドラッグ終了時に速度が0
👉 velocityを更新していない
5.応用アイデア
- 横スクロールUI
- カルーセル
- スワイプ操作
- Snap UIとの組み合わせ
6.まとめ
Momentum UIは「速度」と「摩擦」だけで作れます。
シンプルですが、UXを大きく向上させる重要なテクニックです。
スクロール系の動きと組み合わせると、
さらにリッチなUIになります👇
Scroll Animationシリーズ
- #24 Scroll Reveal Animation
- #25 Scroll Progress
- #26 Scroll Snap Animation
- #27 Parallax Scroll Animation
- #28 Scroll Trigger Animation
- #29 Sticky Scroll Animation
- #30 Scroll Story UI
- #31 Scroll State Machine UI
- #32 Scroll Velocity Animation
- #33 Scroll Mouse Interaction UI
- #34 Scroll Spy UI
- #35 Scroll Sync UI
- #36 Scroll-Driven State UI
- #37 Scroll Time UI
- #38 Scroll Timeline UI
- #39 Scroll Direction UI

コメントを残す