Skip to content

Instantly share code, notes, and snippets.

@fronterior
Last active February 25, 2022 22:37
Show Gist options
  • Save fronterior/08b8a1cf80e37787f93ccda00e15f726 to your computer and use it in GitHub Desktop.
Save fronterior/08b8a1cf80e37787f93ccda00e15f726 to your computer and use it in GitHub Desktop.
import { useEffect, useRef } from "react";
const useDragHook = <T extends HTMLElement>(
{
down,
move,
up,
}: {
down?(ev: PointerEvent, extra: { ox: number; oy: number }): void;
move?(
ev: PointerEvent,
extra: { dx: number; dy: number; tx: number; ty: number }
): void;
up?(
ev: PointerEvent,
extra: { dx: number; dy: number; tx: number; ty: number }
): void;
},
{ available, delay }: { available: boolean; delay: number }
) => {
const ref = useRef<T>(null);
useEffect(() => {
if (!available) return;
let prevX: number;
let prevY: number;
let tx: number;
let ty: number;
const downHandler = (ev: PointerEvent) => {
const { clientX, clientY } = ev;
document.addEventListener("pointermove", moveHandler);
document.addEventListener("pointerup", upHandler);
tx = prevX = clientX;
ty = prevY = clientY;
down?.(ev, { ox: prevX, oy: prevY });
};
const moveHandler = (ev: PointerEvent) => {
const { clientX, clientY } = ev;
const dx = clientX - prevX;
const dy = clientY - prevY;
prevX = clientX;
prevY = clientY;
move?.(ev, { dx, dy, tx: clientX - tx, ty: clientY - ty });
};
const upHandler = (ev: PointerEvent) => {
const { clientX, clientY } = ev;
const dx = clientX - prevX;
const dy = clientY - prevY;
prevX = clientX;
prevY = clientY;
document.removeEventListener("pointermove", moveHandler);
document.removeEventListener("pointerup", upHandler);
up?.(ev, { dx, dy, tx: clientX - tx, ty: clientY - ty });
};
ref.current?.addEventListener("pointerdown", downHandler);
return () => {
ref.current?.removeEventListener("pointerdown", downHandler);
document.removeEventListener("pointermove", moveHandler);
document.removeEventListener("pointerup", upHandler);
};
}, [available]);
return ref;
};
export default useDragHook;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment