スマホアプリでは当たり前になっている「スワイプ操作」。
カードを左右に動かして
「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と組み合わせることで、
よりリッチなインタラクション設計ができるようになります。

コメントを残す