Skip to content

feat(core): GlobeView pointer-anchored zoom (wheel + transitions)#10385

Open
charlieforward9 wants to merge 8 commits into
masterfrom
codex/globe-anchored-zoom
Open

feat(core): GlobeView pointer-anchored zoom (wheel + transitions)#10385
charlieforward9 wants to merge 8 commits into
masterfrom
codex/globe-anchored-zoom

Conversation

@charlieforward9

Copy link
Copy Markdown
Collaborator

Summary

Adds opt-in pointer-anchored zoom for GlobeView, keeping the existing center-anchored behavior as the default.

Moved to an upstream branch (visgl:codex/globe-anchored-zoom); supersedes the fork-based #10307.

Changes

  • Adds zoomAround?: 'center' | 'pointer' to controller options.
  • GlobeViewport.panByGlobeAnchor — spherical (ray-to-sphere) pointer anchoring, with edge damping near the limb and a grace band so anchors don't snap when the cursor grazes the globe's edge.
  • In-gesture anchor recovery: if zoomStart misses the globe and leaves the anchor empty, pointer mode recovers an anchor from the current event and persists it for the rest of the gesture (fixes a sporadic fallback to center-anchoring).
  • LinearInterpolator transitions anchored on GlobeViewport, so animated zooms respect the pointer anchor.

Tests

  • controllers.spec, view-states.spec, globe-viewport.spec, linear-interpolator.spec — anchor math, gesture recovery, and transition anchoring.

Follow-up

  • Anchor precision at very high zoom (globe nearly filling the viewport) can be tightened further; current behavior is stable but not pixel-perfect at the extreme.

Replace the `log.warn('around not supported in GlobeView')` no-op
with real spherical anchoring, mirroring the existing planar branch:
- `initializeProps`: when the start viewport is a GlobeViewport and the
  screen anchor falls on the globe (`isPointOnGlobe`), unproject it to
  lng/lat and stash it as `aroundLngLat`.
- `interpolateProps`: each frame, call `panByGlobeAnchor(aroundLngLat,
  lerp(start.around, end.around, t))` so the geographic point stays
  pinned under the anchor screen point during the transition.

This makes the `_onDoubleClick` zoom transition (`_getTransitionProps
({around: pos})`) actually anchor on GlobeView. Previously the warn
fired and the LERP ran without anchor maintenance, which read as a
center-anchored zoom-in regardless of where the user tapped.

Tests cover the on-globe anchored path and the off-globe fall-through.
- Consolidate stray imports at the top of the file.
- Document the two GLOBE_ZOOM_ANCHOR_* constants so the empirical
  damping behavior (start damping at 0.75 of the limb, never below
  35% strength) is self-explanatory.
- Add a JSDoc to _getRayToGlobe explaining it as the shared ray/sphere
  math helper for unproject + isPointOnGlobe + panByGlobeAnchor.
@charlieforward9 charlieforward9 force-pushed the codex/globe-anchored-zoom branch from c29d36e to 4b98253 Compare June 16, 2026 17:36
…pout)

Per #10307 review: zoomAround is a config option that always needs a value,
unlike the transient gesture anchors guarded the same way. The !== undefined
guard let a partial-props / HMR reconstruction drop the key, so
_shouldZoomAroundPointer() saw undefined and silently reverted to center zoom.
@coveralls

coveralls commented Jun 16, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 83.467% (+0.04%) from 83.424% — codex/globe-anchored-zoom into master

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.

2 participants