Skip to content

feat(core): GlobeView pitch, bearing, and cursor-anchored zoom#10243

Closed
charlieforward9 wants to merge 1 commit intovisgl:masterfrom
NEW-HEAT:feat/globe-camera
Closed

feat(core): GlobeView pitch, bearing, and cursor-anchored zoom#10243
charlieforward9 wants to merge 1 commit intovisgl:masterfrom
NEW-HEAT:feat/globe-camera

Conversation

@charlieforward9
Copy link
Copy Markdown
Collaborator

@charlieforward9 charlieforward9 commented Apr 19, 2026

Summary

Brings GlobeView to feature parity with MapView for camera interaction. Three related changes:

  • Pitch and bearing: GlobeView now accepts pitch, bearing, minPitch, maxPitch view-state props. GlobeViewport composes them into a lookAt-based view matrix that keeps the target lng/lat fixed at screen center through tilt and rotation — matching the Google Maps/Earth interaction model. GlobeController wires up dragRotate and touchRotate and enforces the pitch constraints.
  • Cursor-anchored zoom: scroll-wheel zoom now targets the mouse cursor (consistent with MapView) instead of always zooming toward screen center.
  • Pan consistency with MapView: GlobeState inherits pan from MapState, so the grabbed lng/lat stays under the cursor through a drag. The previous delta-pan produced the wrong on-screen speed at zoom > 12 where WebMercatorViewport takes over rendering.

Includes a ray/sphere-miss fallback in unproject so off-globe interactions don't return null.

Why

Pitch + bearing + zoom-toward-cursor are the camera affordances users already expect from MapView. Without them, GlobeView-based apps can't offer the same 3D tilt/orbit UX that MapView has supported for years — which makes it hard to build a projection-toggling app where the camera feels the same on both projections.

Test plan

  • New unit tests in test/modules/core/viewports/globe-viewport.spec.ts for pitch/bearing viewport math
  • New unit tests in test/modules/core/controllers/view-states.spec.ts for pitch/bearing transitions
  • test/apps/globe/app.js updated with sliders to exercise the new view-state props interactively

Companion PRs

This PR is standalone. Two follow-up PRs build on it to bring terrain rendering to GlobeView:

Add camera tilt (pitch) and rotation (bearing) to GlobeView, matching the
Google Maps/Earth interaction model. Uses a lookAt-based view matrix that
composes pitch and bearing rotations while keeping the target lng/lat at
screen center.

Scroll-wheel zoom now targets the mouse cursor position instead of screen
center (matching MapView). Pan reuses MapState's grabbed-lng/lat logic so
the point under the cursor stays under the cursor through the drag —
previously GlobeState's delta-pan produced wrong on-screen speed and
yanked the center at zoom > 12 where WebMercatorViewport takes over
rendering. Unproject for rays that miss the globe surface returns a
plausible fallback rather than null.

Changes:
- GlobeViewport: lookAt view matrix with pitch/bearing, cursor-anchored
  zoom, ray/sphere miss fallback
- GlobeController: dragRotate/touchRotate, pitch/bearing constraints,
  inherits pan from MapState
- GlobeView: pitch/bearing/minPitch/maxPitch view state props
- Tests for pitch/bearing transitions and viewport math
@charlieforward9
Copy link
Copy Markdown
Collaborator Author

Superseded by #10249 (same branch re-opened under cr/ prefix, pushed directly to visgl/deck.gl).

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