feat(core): support pointer-anchored zoom in GlobeView - #10385
feat(core): support pointer-anchored zoom in GlobeView#10385charlieforward9 wants to merge 17 commits into
Conversation
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.
c29d36e to
4b98253
Compare
…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.
ibgreen-openai
left a comment
There was a problem hiding this comment.
I wonder if this could be split into stacked PR, one that adds general things like zoomStart, zoomEnd and other plumbing, and then the globe specific feature could be a much smaller, easier review on top of that?
chrisgervang
left a comment
There was a problem hiding this comment.
Agree with @ibgreen, since this changes a lot of core functionality I'd prefer to split the PRs up and test each of them in the stack
…ared-zoom # Conflicts: # docs/api-reference/core/globe-controller.md # modules/core/src/controllers/controller.ts # test/modules/core/controllers/controllers.spec.ts
Greptile SummaryThis PR adds pointer-anchored zoom support to GlobeView through the generic controller, viewport, constraint, and transition contracts.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| modules/core/src/controllers/globe-controller.ts | Integrates Globe zoom anchoring with generic constraint handling and falls back to center anchoring for off-globe pointers. |
| modules/core/src/viewports/globe-viewport.ts | Adds shared ray geometry, anchor-strength damping, wrapped longitude correction, and descriptive parameter names while preserving drag behavior. |
| modules/core/src/transitions/linear-interpolator.ts | Removes the Globe-specific exclusion so transition anchoring uses the common viewport contract. |
| test/modules/core/viewports/globe-viewport.spec.ts | Covers on-globe stability, limb behavior, off-globe fallback, and antimeridian wrapping. |
| test/apps/globe/app.js | Updates the Globe demo with shared Map/Globe and pointer/center controls and corrects the point-radius accessor. |
Sequence Diagram
sequenceDiagram
participant Input as Pointer input
participant Controller as GlobeController
participant State as GlobeState
participant Viewport as GlobeViewport
Input->>Controller: wheel/pinch/double-click at screen position
Controller->>Viewport: getZoomAnchorStrength(position)
alt Pointer can anchor globe
Controller->>State: zoom around pointer
State->>Viewport: panByPosition(anchor, screenPosition)
Viewport-->>State: corrected longitude and latitude
else Pointer is far off globe
Controller->>State: zoom around projected center
State->>Viewport: panByPosition(center, centerPixel)
Viewport-->>State: unchanged longitude and latitude
end
Reviews (6): Last reviewed commit: "fix(core): center globe zoom outside vis..." | Re-trigger Greptile
# Conflicts: # test/modules/core/controllers/controllers.spec.ts
|
@ibgreen-openai @chrisgervang I made the physical split you asked for.
The stacked #10385 diff is now 8 files. Fresh post-stack focused tests are 90/90; the unchanged source tree also passed build, lint, test-website, and live Globe pointer/center plus Map pointer verification. |
|
I stress-tested this against the exact stacked head today and found one real Globe edge case before asking for review: an off-globe pixel could still be unprojected into a phantom anchor once the target zoom made the sphere larger. Fixed in
The regression test fails on the previous head with a Local gates are green: 92/92 focused tests, |
Goal
Add stable pointer-anchored zoom to GlobeView through the same controller and transition contracts used by the other views, without Globe-specific branches in shared controller code.
This PR is the Globe-specific half of the maintainer-requested stack:
zoomAroundcontroller option across Map, Orbit, Orthographic, and FirstPerson, including padded viewport-center handlingSupersedes the fork-based #10307.
Changes
GlobeViewport.panByPositionto preserve a geographic anchor during zoom using spherical ray mathGlobeStateconstraints andLinearInterpolatoranchoring through the generic viewport contractpanByPositionintactsettings-control.js, with the same pointer/center control operating in both Globe and Map viewsValidation
LinearInterpolator, andGlobeViewport1.25738°longitude shift and passes on this headyarnyarn buildyarn lintyarn test-headless: 216/217 files and 985 tests passed; the only failure is the unrelatedloading-widget.spec.tsspinner assertion, reproduced identically on the untouched feat(core): configure zoom anchors across controllers #10595 base8d771b0cdb; GitHub Actions had not created a run for the synchronized SHA at the latest check84°and zoom72.6e-12pxand Globe anchor error was0.41px