ui
swipe to dismiss / swipe away / drag to dismiss
カードや通知を横へ払うと消え、払いきれなければ元の位置へ戻る操作。肝は「指に1:1で追従する区間」と「離した瞬間のしきい値判定」を分けて設計することで、距離が足りなくても速ければ消す二重判定が入ると一気に手触りが良くなる。
02 — Prompt template
03 — Params
threshold(消えるまでの距離 px) — 範囲 20〜160 / 初期 45
ここを越えて離すと消える。45〜60pxが実測の定番で、120pxを超えると「重い・消えない」と感じられる。20px以下は誤爆する。fling(速度で消す境界 px/s) — 範囲 0〜1200 / 初期 110
距離が足りなくてもこの速さ以上なら消す。110〜400px/sが自然。0にすると少しでも動かせば消えるので誤爆する。flyout(飛び去る時間 s) — 範囲 0.1〜0.8 / 初期 0.2
判定が通ってから画面外へ抜けるまで。0.15〜0.25sのease-outが「指の勢いの続き」に見える。0.5s超は操作が終わった後に待たされる。snapBack(戻る時間 s) — 範囲 0.1〜0.9 / 初期 0.4
しきい値に届かなかったときに元へ戻る時間。飛び去りより長くする(0.35〜0.5s)と「戻された」が読めて、消えたときとの差が付く。
04 — Vocab
dismiss threshold — 離した位置が消える側か戻る側かを分ける距離。px固定かカード幅の割合(25〜40%)で決める。
fling / velocity threshold — 速度による消しの判定。短く速い一払いを拾うための第二の入口で、距離判定とORで繋ぐ。
snap back — しきい値に届かず元の位置へ戻る動き。「操作は受け付けたが実行はしていない」を返す返事。
rubber banding — 消せない方向へ引いたときに減衰をかけて追従を鈍らせる手法。1/(1.5+|d|/20)のような減衰率を掛ける。
setPointerCapture — ドラッグ開始時にポインタを要素へ固定する。指がカードの外へ出ても pointermove が届き続ける。
touch-action: none — ブラウザ既定のスクロール・ズームを止めて横ドラッグを自分で扱う宣言。これが無いとスマホで追従が奪われる。
05 — NG → OK examples
NG
言い方: 「「カードをスワイプで消せるようにして」」
なぜNG: しきい値が決まらないので「少しでも動かすと消える」誤爆だらけの実装か、逆に画面端まで引かないと消えない実装が返ってくる。速い一払いで消えない(速度判定が無い)のが特に多く、指に追従せずクリック扱いで消すだけの版も来る。
OK
言い方: 「「swipe to dismissを実装。pointermoveでtranslateX(dx)に1:1追従+rotateは最大6deg。離したら|dx|>=45pxか直近80msの速度>110px/sで判定し、通れば0.2s ease-outで幅+80px先へ飛ばしてopacity 0、通らなければ0.4sで0へ戻す。transformのみ、reduced-motionでは即時」」
なぜOK: 追従区間・判定・飛び去り・戻りの4区間を分けて数値で指定している。「直近80msの速度」と「距離OR速度の二重判定」を書いた点が効いていて、この1行が有る無しで手触りが変わる。
