Swipe Gesture UI(カードをスワイプして操作するUI)

SWIPE UIのアイキャッチ画像

スマホアプリでは当たり前になっている「スワイプ操作」。

カードを左右に動かして
「YES / NO」や「削除 / 保存」などを直感的に選択できるUIです。

今回はこのスワイプUIを、JavaScriptでシンプルに実装してみます。

スワイプUIは、ドラッグ操作をベースにしたインタラクションです。

ドラッグの基礎については以下の記事で解説しています。
Drag Interaction UI

1.このUIのポイント

  • ドラッグでカードが追従
  • 一定距離で判定(threshold)
  • 条件を超えると画面外へスワイプ
  • 戻るときはスムーズにスナップ

2.基本実装

HTML

<div class="stage">
  <div class="card" id="card">
    SWIPE
  </div>
</div>

CSS

body {
  margin: 0;
  height: 200vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #111;
  color: #fff;
  font-family: sans-serif;
}

.stage {
  width: 300px;
  height: 400px;
  position: relative;
}

.card {
  width: 100%;
  height: 100%;
  background: #222;
  border-radius: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 24px;
  user-select: none;
  touch-action: none;
  cursor: grab;
  transition: transform 0.3s ease;
}

JavaScript

const card = document.getElementById("card");

let startX = 0;
let currentX = 0;
let isDragging = false;

const threshold = 100;

card.addEventListener("pointerdown", (e) => {
  isDragging = true;
  startX = e.clientX;
  card.style.transition = "none";
});

window.addEventListener("pointermove", (e) => {
  if (!isDragging) return;

  currentX = e.clientX - startX;

  const rotate = currentX * 0.1;

  card.style.transform = `translateX(${currentX}px) rotate(${rotate}deg)`;
});

window.addEventListener("pointerup", () => {
  if (!isDragging) return;
  isDragging = false;

  card.style.transition = "transform 0.3s ease";

  if (Math.abs(currentX) > threshold) {
    const direction = currentX > 0 ? 1 : -1;
    card.style.transform = `translateX(${direction * 500}px) rotate(${direction * 20}deg)`;
  } else {
    card.style.transform = `translateX(0px) rotate(0deg)`;
  }
});

3.実装のポイント

① pointerイベントで統一

  • マウス / タッチ両対応
  • pointerdown / move / up

Pointer Events を使うのが現代的

マウスとタッチを統一して扱うには、
入力設計の考え方が重要になります。

このあたりは以下の記事でも触れています。
Input設計

② 移動量(dx)でUIを制御

currentX = e.clientX - startX;

これだけで「どれだけ動いたか」が分かります。

③ thresholdで判定

if (Math.abs(currentX) > threshold)
  • 小さい → 元に戻る
  • 大きい → スワイプ確定

この「どこで確定するか」という設計は、
スクロールUIでも重要な考え方です。
Scroll Snap UI

④ transformでパフォーマンス確保

transform: translateX() rotate()

GPU Acceleration により滑らか

transformを使うことでパフォーマンスを維持できます。

アニメーションの滑らかさについては以下で詳しく解説しています。
フレームレートとパフォーマンス

4.実験:スワイプ閾値実験

実際に触って違いを体感してみてください。

観察ポイント

  • threshold 50px → すぐ消える
  • threshold 150px → なかなか消えない
  • rotate強め → 感情的な動きになる
  • transitionなし → カクつく

5.応用アイデア

  • カードスタック(次のカード表示)
  • YES / NOラベル表示
  • velocityで判定強化
  • 縦スワイプ追加

スワイプUIを理解すると、より高度なインタラクション設計に進めます。

次におすすめの記事:
Scroll Sync UI(連動するUI)
Scroll Timeline UI(時間軸UI)
Drag Interaction UI(基礎に戻る)

6.まとめ

スワイプUIは、

  • 直感的
  • スマホとの相性が良い
  • 実装もシンプル

という非常に強力なUIパターンです。

Drag Interactionと組み合わせることで、
よりリッチなインタラクション設計ができるようになります。

コメント

コメントを残す

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

CAPTCHA