Momentum Drag UIの作り方(慣性スクロールをJavaScriptで再現)

Momentum Drag UIのアイキャッチ画像

ドラッグを離したあと、スーッと動き続けるUIを見たことはありませんか?

iOSのスクロールやカードUIなどでよく使われている「慣性(Momentum)」です。

この記事では、JavaScriptでこの動きをゼロから実装します。

まずは基本的なドラッグ操作を知りたい方は、
こちらの記事から読むのがおすすめです。

Drag Interaction UI 

1.実装の全体像

やることはシンプルです。

  • ドラッグ中 → 位置と速度を更新
  • ドラッグ終了 → 速度を使って動き続ける
  • 徐々に減速(摩擦)

この実装では「速度(Velocity)」の考え方を使います。

速度について詳しく知りたい方はこちら👇

Scroll Velocity Animation

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;

ドラッグ終了後も動き続ける

減速の仕組みは、イージングの考え方と似ています。

Easing Animation

③ 摩擦(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シリーズ

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA