Skip to content

3D camera: fix orbit drift, fly-through dolly, shift-drag pan, click-vs-drag guard - #162

Merged
enjalot merged 1 commit into
mainfrom
feature/3d
Jul 11, 2026
Merged

3D camera: fix orbit drift, fly-through dolly, shift-drag pan, click-vs-drag guard#162
enjalot merged 1 commit into
mainfrom
feature/3d

Conversation

@enjalot

@enjalot enjalot commented Jul 11, 2026

Copy link
Copy Markdown
Owner

What

Interaction fixes for the 3D scatter and voxel views (follow-up to #154/#159), one shared camera recipe across both components:

  • Orbit-center drift fixeddollyToCursor slid the orbit target sideways on every wheel tick, so zoom-in → look around → zoom-out left the pivot far from where you started. Measured on that exact gesture: target drift 2.256 → 0.014 world units (~165× reduction).
  • Fly-through dollyinfinityDolly: true: the wheel carries the camera through the cloud instead of clamping at the pivot. WASD flies while the pointer is over the canvas (disabled whenever an input/textarea/select has focus, so it never fights search).
  • Shift+drag pans (truck) — camera-controls has no shift-modifier mapping, so a capture-phase pointerdown swaps the left-button action; right-drag also trucks. Touch gestures unchanged (one-finger orbit, pinch, two-finger pan, tap = drawer).
  • Drag-clicks no longer open details — point/voxel select fires on pointerup only if movement < 5px and < 400ms. The 2D map's d3-zoom click path is untouched (regression-verified: a 120px pan does not open detail).

Testing

  • Scripted the reported gesture in a real browser (Metal WebGL) and measured target positions before/after — numbers above.
  • Click/drag matrix verified on 3D points, voxels, and the 2D map; shift-pan verified (target trucked 1.13 units).
  • pytest 295 passed / 3 skipped; vitest 103 passed; production build green; eslint clean.
  • A DEV-only window.__ls3d debug handle (guarded by import.meta.env.DEV) supports the interaction harness; stripped from production builds.

🤖 Generated with Claude Code

Hands-on 3D use surfaced four camera/interaction problems in Scatter3D and
VoxelView. All four are addressed with one shared camera-controls recipe.

1. Orbit centre drifted after "zoom in, look around, zoom out". Cause was
   dollyToCursor:true, which slides the orbit target sideways toward the cursor
   on every wheel tick, leaving a stale off-centre pivot. Turned dollyToCursor
   OFF so the wheel dollies straight along the view ray. Measured on the
   dataisplural 3D scope (wheel-in 5 @ off-centre, rotate ~90 deg, wheel-out 5):
   orbit-target drift dropped from 2.256 world units to 0.014 (~165x).

2. "FPS fly-through" feel: infinityDolly:true so the wheel keeps moving the
   camera THROUGH the cloud once it reaches minDistance (target is pushed ahead
   instead of clamping), plus WASD fly (W/S along the view ray, A/D truck) while
   the pointer is over the canvas and no text field is focused.

3. Shift+drag now trucks (pans). camera-controls 3.x has no shift-modifier
   mapping, so a capture-phase pointerdown swaps mouseButtons.left between
   ROTATE and TRUCK based on the shift key; right-drag and two-finger touch pan
   still work.

4. Drag-clicks no longer open a detail/drawer. Select now fires on pointerup
   only when the pointer moved < 5px in < 400ms since pointerdown, for both
   Scatter3D point clicks and VoxelView cell clicks. Taps and dbl-click fly-to
   are unchanged; the 2D map (d3-zoom) was verified unaffected.

cluster fit-to-box, "Align to view", and the touch gestures are untouched.
Verified with a Playwright harness (drift numbers, click-vs-drag, shift-pan,
voxel select) plus pytest (295 passed), vitest (103 passed), and the production
build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@enjalot
enjalot merged commit 193de13 into main Jul 11, 2026
5 checks passed
enjalot added a commit that referenced this pull request Jul 11, 2026
…ken-maps

Both sides had wired MiniLM labels and fixed the taxonomy deep-link
independently; resolved to main's getSaeForModel registry style with the
token-scope additions on top (scope-declared SAEs resolve links/labels by the
SAE's own model repo via saeLabels). FeatureModal keeps the
activation-ranking fix alongside main's saeEntry link.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant