G11▸I101▸gsap
Draggable Cards
可拖曳卡片
難度 ★★★★★標籤 drag · draggable · inertia3 min read
效果簡述
卡片可被滑鼠 / 觸控拖曳。GSAP Draggable 是免費 plugin,比 framer-motion 的 drag 多了 inertia / hitTest / 進階回呼。但簡單拖曳的話 framer 也夠用。
拖我 · 限制邊界
卡片 A
卡片 B
卡片 C
Claude Code Prompt
參考:I101 draggable cards
技術:gsap Draggable
具體行為:
- gsap.registerPlugin(Draggable)
- Draggable.create(el, { type: 'x,y', bounds: containerRef, edgeResistance: 0.65, inertia: true })
- 想要慣性的話需要 InertiaPlugin(付費);只用 Draggable 本身免費
限制:
- inertia 是付費功能,沒買就 false
- bounds 設定要嚴格,不然會拖出去找不回來
- 跟頁面滾動衝突時用 dragClickables: false完整程式碼
'use client'
import gsap from 'gsap'
import { Draggable } from 'gsap/Draggable'
import { useEffect, useRef } from 'react'
export function DraggableCards() {
const root = useRef<HTMLDivElement>(null)
useEffect(() => {
gsap.registerPlugin(Draggable)
const cards = root.current?.querySelectorAll<HTMLElement>('.card')
if (!cards) return
const inst: Draggable[] = []
cards.forEach((c) => {
inst.push(...Draggable.create(c, { type: 'x,y', bounds: root.current, edgeResistance: 0.65 }))
})
return () => inst.forEach((i) => i.kill())
}, [])
return (
<div ref={root} className="relative h-72">
<div className="card absolute h-20 w-28 bg-orange-500/30" />
</div>
)
}何時用
- ✅ Kanban / 看板互動
- ✅ 互動式拼貼 / mood board
- ✅ 概念展示 / 玩心專案
何時別用
- ❌ 卡片資訊重要、不想被打亂位置
- ❌ 長列表(拖卡會跟滾動衝突)
- ❌ 沒考慮 a11y 鍵盤操作的場景
我踩過的坑
-
bounds 沒設拖到天荒地老:忘記 bounds 結果用戶拖到 -2000px 都還沒停。一定要 bounds: containerRef。
-
inertia 是付費 plugin:免費版只能 type, bounds, edgeResistance。 想要丟出去再緩停得買 Club GreenSock。
-
mobile 跟頁面滾動衝突:垂直拖卡時被頁面捲走。設定
allowEventDefault: false或限制type: 'x'只能橫拖。
相關效果
- G12 Flip Layout — 配合 drag 重排