pointerdown
pointermove
pointerup
pointercancel
elem.setPointerCapture(pointerId)
Locks all subsequent pointermove/up events to elem, even if the pointer leaves the element.
elem.releasePointerCapture(pointerId)
Releases the capture.
pointerdown, record starting position (startX, startY) and call setPointerCapture.pointermove, calculate delta (dx = event.clientX – startX, etc.) and update element position (e.g. via style.transform).pointerup or pointercancel, release capture and finalize state (e.g. drop logic).const box = document.getElementById('box');
let startX, startY;
box.addEventListener('pointerdown', e => {
startX = e.clientX - box.offsetLeft;
startY = e.clientY - box.offsetTop;
box.setPointerCapture(e.pointerId);
});
box.addEventListener('pointermove', e => {
if (e.pressure === 0) return; // no contact
const x = e.clientX - startX;
const y = e.clientY - startY;
box.style.transform = `translate(${x}px, ${y}px)`;
});
box.addEventListener('pointerup', e => {
box.releasePointerCapture(e.pointerId);
// Optionally: snap to grid, trigger drop event, etc.
});
box.addEventListener('pointercancel', e => {
box.releasePointerCapture(e.pointerId);
// Handle cancellation if needed
});
setPointerCapture in pointerdown to ensure smooth dragging.event.clientX/Y for coordinates relative to viewport.