Skip to content

feat(explorer): WASD keyboard navigation; 3D lines show through dimmed terms - #68

Merged
CMaintz merged 7 commits into
mainfrom
feat/explorer-wasd-3d-depth
Sep 26, 2026
Merged

CMaintz merged 7 commits into
mainfrom
feat/explorer-wasd-3d-depth

Conversation

@CMaintz

@CMaintz CMaintz commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Owner requests: 3D links vanishing behind dimmed terms, and WASD keyboard navigation in 2D and 3D. Decision note: A97 (A96 is taken by open PR #64).

3D: lines behind receded terms

All spheres are transparent (nodeOpacity 0.95), so three.js sorted each one against the single merged web by distance. A receded (dimmed) sphere that happened to draw first wrote depth and erased every line behind it. Only comets and glow showed through.

The fix is a fixed renderOrder: glow, then solid spheres (these still write depth and occlude), then lines (the web plus the focused link objects), then receded spheres (depthWrite=false below EXPLORER.three.solidOpacity), then comets. The sphere materials belong to 3d-force-graph and it swaps them on its own schedule, so a scene.onBeforeRender pass applies the order every frame.

Verified with headless screenshots: with a term selected and the camera zoomed in on receded spheres, the lines now pass through them. Before the fix they stopped at the sphere's edge.

Keyboard navigation (explorer-keys.ts + tests)

  • 2D: W A S D and the arrows pan. Q/E and -/+ zoom about the centre of the clear area.
  • 3D: W/S move forward and back, closing in on the orbit centre and pushing it ahead once near. A/D move sideways. Q/E move down and up (Space also moves up). The arrows orbit.
  • Shift triples the speed in both views.
  • The OrbitControls target stays in sync, so mouse orbit still works afterwards.
  • Movement is velocity-based with an exponential ease, so it doesn't depend on frame rate. Under reduced motion there is no easing.
  • Letters and arrows are read by physical key. + and - are read by character, so they work on a Danish layout.
  • Scope: keys only act when focus is inside the map host, or when nothing has focus and the pointer is over the map. They never fire with Alt/Ctrl/Cmd held, and never in fields, the bar, popovers or the term panel, so the panel's ←/→ still step through connections.
  • Map host: tabindex=0, role="application", and an aria-label with a "use W A S D" hint. The open legend ends with a one-line key hint for the current view (EN + DA).
  • Ctrl as "down" is left out: Ctrl+W closes the tab and Ctrl+drag pans.

Checks

  • mise run fix && mise run gate: exit 0.
  • fps (headless Edge, 2x CPU throttle), before / after:
View Pan Zoom Orbit Hover
2D 46 / 49 46 / 54 – 59 / 59
3D – – 49 / 60 59 / 54

The 3D hover drop is within run-to-run noise.

Do not merge without the owner.

…-depth

# Conflicts:
#	app/src/lib/explorer-2d.ts
#	design/AUTONOMOUS_DECISIONS.md
@CMaintz
CMaintz merged commit 20011f4 into main Sep 26, 2026
1 check passed
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