Skip to content

feat(slider): implement infinity dragging using PointerLock API#206

Open
claygeo wants to merge 1 commit intopascalorg:mainfrom
claygeo:feat/slider-infinity-dragging
Open

feat(slider): implement infinity dragging using PointerLock API#206
claygeo wants to merge 1 commit intopascalorg:mainfrom
claygeo:feat/slider-infinity-dragging

Conversation

@claygeo
Copy link
Copy Markdown

@claygeo claygeo commented Apr 1, 2026

Summary

Closes #204

Saw this was on your radar @Aymericr — figured I'd take a crack at it since the PointerLock pattern already exists in first-person-controls.tsx.

Slider controls now use the Pointer Lock API for drag interactions. When dragging a slider label, the cursor locks and movement continues infinitely past the screen edge, matching the behavior in Unity3D and other professional 3D editors.

Changes

packages/editor/src/components/ui/controls/slider-control.tsx — 1 file, ~40 lines changed

Before After
setPointerCapture + e.clientX requestPointerLock + e.movementX
Drag stops at screen edge Drag continues infinitely
Cursor visible during drag Cursor hidden (locked)

How it works

  1. Pointer downrequestPointerLock() locks the cursor and hides it
  2. Pointer move → accumulates e.movementX (relative delta, not viewport-bound)
  3. Pointer updocument.exitPointerLock(), cursor reappears at original position
  4. Escape keypointerlockchange listener cleans up drag state gracefully

Edge cases handled

  • PointerLock denied: falls back to setPointerCapture (existing behavior)
  • Escape during drag: pointerlockchange listener catches this, commits the value, resumes undo tracking
  • Shift/Ctrl modifiers: still work (10x / 0.1x step multiplier)
  • Undo/redo: temporal state paused/resumed correctly on all exit paths

Reference

Adapted from the existing PointerLock usage in first-person-controls.tsx (lines 50-64) which uses the same API for camera mouse look.

Test plan

  • Drag slider label past screen edge — value keeps changing
  • Release mouse — cursor reappears, value commits
  • Press Escape during drag — drag cancels cleanly
  • Shift+drag — 10x step multiplier still works
  • Ctrl+drag — 0.1x step multiplier still works
  • Click value to edit — text input still works (not affected)
  • Scroll wheel on label — still works (not affected)

Slider controls now use the PointerLock API for drag interactions,
allowing users to drag values past the screen edge without the cursor
stopping. This matches the behavior of sliders in Unity3D and other
professional 3D editors.

When a user drags a slider label, the cursor locks and hides while
movementX accumulates the total drag distance. Releasing or pressing
Escape exits the lock cleanly with proper undo/redo tracking.

Falls back to setPointerCapture for browsers that don't support
PointerLock. Adapts the existing pattern from first-person-controls.tsx.

Closes pascalorg#204
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The slider-control should be infinity dragging

1 participant