useDrag
要素の上のポインタのドラッグを追跡し、どれだけ動いたかを報告します。
Sourceこの hook は ref callback を返します。ドラッグの起点になる要素に付ければ、あとはハンドラが受け取ります。持つべき state も、後片付けもありません。
Loading...
function App() { const [position, setPosition] = useState({ x: 0, y: 0 }) const [delta, setDelta] = useState({ x: 0, y: 0 }) const [dragging, setDragging] = useState(false) const dragRef = useDrag<HTMLDivElement>({ cursor: 'grabbing', onDragStart: () => setDragging(true), onDragEnd: () => setDragging(false), onDrag: (x, y, deltaX, deltaY) => { setPosition({ x, y }) setDelta({ x: deltaX, y: deltaY }) }, }) return ( <div style={{ userSelect: 'none' }}> <div ref={dragRef} style={{ padding: '2rem', marginBottom: '0.5rem', border: '1px solid currentColor', borderRadius: 8, textAlign: 'center', touchAction: 'none', }} > Drag here </div> <div>dragging: {String(dragging)}</div> <div> x: {position.x}, y: {position.y} </div> <div> deltaX: {delta.x}, deltaY: {delta.y} </div> </div> ) }
インポート
import { useDrag } from '@tremolo-ui/react'
この hook が引き受けること
ポインタを捕捉するので、要素の外へ出てもドラッグは続きます。 ボックスの外、ウィンドウの外、ページの外へ出ても報告は続き、離したところで終わります。要素自身で pointermove を購読すると、ポインタが出た時点で終わってしまいます。
threshold が、クリックをドラッグとして数えないようにします。 クリックでもポインタは 1〜2 ピクセル動くので、しきい値が無いとダブルクリックの 2 回の押下の間がドラッグとして報告されます。しきい値に満たない移動は捨てずに次へ繰り越すので、ゆっくりしたドラッグも積み上がれば報告されます。
onDragStart は pointerdown ではなく、ドラッグが始まった時点で呼ばれます。 しきい値を超えた瞬間で、cursor が当たるのも同じタイミングです。
CSS で要素に touch-action: none を付けてください。付けないと、ブラウザがドラッグを通す代わりにページをスクロールします。
修飾キーを読む
どのハンドラも最後の引数に DragState 全体を受け取り、その中にポインタイベントが入っています。修飾キーはそこにあります。
useDrag({
onDrag: (x, y, deltaX, deltaY, state) => {
const step = state.event.shiftKey ? 0.1 : 1
},
})
ポインタではなく値を動かす
useDrag が報告するのはピクセルです。範囲・step・スケールを持つ数値が欲しいときは useDragValue を使ってください。この hook の上に作られていて、マッピングまで面倒を見ます。
オプション
| Prop | 型 | 既定値 |
|---|---|---|
threshold | number | 1 |
cursor | string | — |
pointerLock | boolean | false |
onDrag | (x: number, y: number, deltaX: number, deltaY: number, state: DragState) => void | — |
onDragStart | (state: DragState) => void | — |
onDragEnd | (state: DragState) => void | — |
すべての説明: UseDragOptions