Make cleanup idempotent
When pointerdown starts a drag, store the active pointerId and the object or action it owns. Both pointerup and pointercancel should end that interaction and clear its state. Write cleanup so calling it after an already-ended action is harmless; this simplifies handling capture loss, window changes and repeated defensive cleanup.
If using pointer capture, listen for lostpointercapture as another signal that the interaction no longer owns the pointer. Do not interpret cancellation as a successful drop unless the game explicitly defines that result. A canceled drag might return an object to its start position, keep the last valid position or cancel the move; choose one rule and communicate it through feedback.
Test browser gesture takeover
Try a drag that begins on the game surface and continues toward the screen edge, a vertical page scroll that starts over the surface, rotation during a hold, and a second finger touching elsewhere. Confirm that no character keeps moving and no button remains visually pressed after cancellation.
The touch-action property influences which gestures the browser handles. MDN explains that browsers can dispatch pointercancel when taking over panning or zooming. Treat cancellation as a normal outcome your interaction model must handle.
Questions about pointer cancellation in games
Is pointercancel a failed pointerup?
It is a separate signal that the pointer will no longer continue the current interaction. Run cleanup and apply the game’s cancellation rule rather than assuming the action completed.
Can touch-action prevent every pointer cancellation?
No. It guides browser handling of touch gestures, but other conditions can still end pointer delivery. Keep cancellation handling even when the game surface has custom gesture rules.