Visitar URL original
fix(core): let GlobeController zoom past level 12 by dchaudhari7177 · Pull Request #10737 · visgl/deck.gl · GitHub
Skip to content

fix(core): let GlobeController zoom past level 12 - #10737

Merged
chrisgervang merged 7 commits into
visgl:masterfrom
dchaudhari7177:fix/10736-globe-zoom-past-12
Oct 24, 2026
Merged

chrisgervang merged 7 commits into
visgl:masterfrom
dchaudhari7177:fix/10736-globe-zoom-past-12

Conversation

@dchaudhari7177

@dchaudhari7177 dchaudhari7177 commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Closes #10736

Background

Above zoom 12, GlobeView renders with a WebMercatorViewport. That class has no getZoomAnchorStrength, so a pointer-anchored wheel zoom threw in GlobeController.applyConstraints, and the view couldn't zoom in any further. Now only a GlobeViewport is asked for its anchor strength. A WebMercatorViewport's map covers the whole screen, so the anchor holds at full strength there.

Change List

  • GlobeController.applyConstraints: check instanceof GlobeViewport before calling getZoomAnchorStrength
  • Unit tests: a wheel zoom from 12.5 zooms in and keeps the pointer's coordinate (to 4 decimals). Without the fix it fails with viewport.getZoomAnchorStrength is not a function.

Checked locally: controllers.spec.ts (86 tests) passes, tsc --noEmit -p modules/core passes, and prettier is clean. The spec normally runs in the headless project, but I don't have Playwright's Chromium on this machine, so I ran it through the node project from a temporary *.node.spec.ts copy. CI will run it in headless.


Note

Low Risk
Localized interaction fix in globe zoom anchoring with regression tests; no auth, data, or API surface changes.

Overview
Fixes pointer-anchored wheel zoom on GlobeView above zoom level 12, where the view switches to a WebMercatorViewport that does not implement getZoomAnchorStrength (closes #10736).

GlobeController.getZoomPosition now only calls getZoomAnchorStrength when the active viewport is a GlobeViewport; for WebMercatorViewport it treats the map as full-screen and keeps the pointer anchor. New controller tests cover zooming from 12.5+ and a single wheel gesture that crosses the zoom-12 handoff while preserving the coordinate under the cursor.

Reviewed by Cursor Bugbot for commit 5a79ec3. Bugbot is set up for automated code reviews on this repo. Configure here.

Above zoom 12 GlobeView renders with a WebMercatorViewport, which has no
getZoomAnchorStrength, so a pointer-anchored wheel zoom threw
'viewport.getZoomAnchorStrength is not a function' and the view could not
zoom in any further. Only ask a GlobeViewport for its anchor strength; a
WebMercatorViewport's map covers the screen, so anchor at full strength.

Fixes visgl#10736
@greptile-apps

greptile-apps Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Low impact] The PR appears safe to merge; no actionable issues remain.

Summary

Fixes pointer-anchored zoom above level 12 by calling getZoomAnchorStrength only on GlobeViewport.

  • GlobeView keeps wheel zoom anchored to the pointer above level 12.

Review used the full PR diff because the previous and current heads have different merge bases with the target commit. Tests were inspected, not run.

Reviews (6) · Last reviewed commit: "Merge branch 'master' into fix/10736-glo..." · Reviewed by Greptile

@dchaudhari7177

Copy link
Copy Markdown
Contributor Author

Heads-up: #10713, merged on 09-28, reverted #10598. That revert removed the getZoomAnchorStrength call this PR guarded. GlobeState.applyConstraints on master now does viewport.panByPosition(...), and both GlobeViewport and WebMercatorViewport have that method. So the #10736 crash (n.getZoomAnchorStrength is not a function) should no longer reproduce on master, and this branch now conflicts with code that no longer exists.

I see two options:

  1. Close this PR and close [Bug] GlobeView can not zoom in past 12 zoom - n.getZoomAnchorStrength is not a function #10736 as fixed by the revert, or
  2. Rescope it to a regression test only. It would keep the wheel-zoom-above-12 case and add the zoom-12 handoff case Greptile asked for (start at 11.9, cross 12, assert the pointer's lng/lat stay put), so a later re-land of fix(core): rotate GlobeView like a ball through poles #10598 can't bring the crash back.

I'm happy to do either. Let me know which you'd prefer. If I don't hear back, I'll close it in a few days rather than leave a stale conflict.

@chrisgervang

Copy link
Copy Markdown
Collaborator

Hey @dchaudhari7177, thanks for working on this and re-evaluating after we reverted #10598. I'm in favor of adding the regression tests you've described and re-purposing this PR for that.

Please let me know when the tests are up and I'll review.

@chrisgervang chrisgervang self-assigned this Oct 10, 2026
@chrisgervang chrisgervang added this to the v9.4 patch releases milestone Oct 10, 2026
Resolve conflicts with the visgl#10713 revert: the getZoomAnchorStrength call now
lives in GlobeController.getZoomPosition, so guard it there.
@coveralls

coveralls commented Oct 11, 2026 •

Copy link
Copy Markdown

Coverage Status

coverage: 84.149% (+0.001%) from 84.148% — dchaudhari7177:fix/10736-globe-zoom-past-12 into visgl:master

chrisgervang and others added 3 commits October 11, 2026 13:22
Adds the zoom-12 handoff case asked for in visgl#10737 review: a wheel gesture
that starts at zoom 11.9 on a GlobeViewport and lands above 12 on a
WebMercatorViewport keeps the coordinate under the pointer.

@chrisgervang chrisgervang left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @dchaudhari7177, I asked Claude to take a closer look here at both the effectiveness of the regression tests and whether or not to keep the guard


I checked the premise and it goes the other way: the crash is still live on master, so option 2 (test only) isn't available.

Option 3 is a better long term solution: keep the two-line guard and keep both regression tests, which is where the branch now sits.

Why the crash didn't go away. #10598 is not what introduced the call this PR guards. GlobeController.getZoomPosition came from #10385, and #10598 moved it; reverting #10598 in #10713 therefore restored the unguarded call rather than removing it. git log -S "protected getZoomPosition" on master shows all three commits in that order. On master today:

  • modules/core/src/controllers/globe-controller.ts:307 — if (viewport.getZoomAnchorStrength(zoomPosition) > 0), with the viewport cast as GlobeViewport
  • modules/core/src/views/globe-view.ts:59 — return viewState.zoom > 12 ? WebMercatorViewport : GlobeViewport;

So above zoom 12 the call throws, exactly as in #10736. I verified it with master's globe-controller.ts checked out and only these tests applied, controllers.spec.ts gives 78 passed / 1 failed —

TypeError: viewport.getZoomAnchorStrength is not a function
 ❯ GlobeController.getZoomPosition modules/core/src/controllers/globe-controller.ts:307:17
 ❯ GlobeController._onWheel modules/core/src/controllers/controller.ts:730:30
 ❯ GlobeController.handleEvent modules/core/src/controllers/controller.ts:296:20

With the guard restored, 79/79 pass, tsc --noEmit -p modules/core is clean, and so is the linter.

What I pushed. I added the zoom-12 handoff case you proposed (start at 11.9, cross 12, assert the pointer's lng/lat hold), merged master in, and left your fix and your original test untouched. One honest caveat, which I wrote into the test as a comment: the handoff case passes with and without the guard, because the anchor is resolved against the pre-gesture viewport, which is still a GlobeViewport at 11.9. It documents handoff continuity; the zoom-12.5 case is the one that actually pins #10736. Both are worth keeping.

Nothing further needed from you — this is ready to merge from my side once CI finishes.

The zoom 12 handoff case compared to 1 digit (0.05 degrees), which passed
even with pointer anchoring broken. Both cases now compare to 5 digits:
the measured residual is ~1e-6 degrees, a center-anchored zoom is ~5e-3.
@chrisgervang chrisgervang mentioned this pull request Oct 22, 2026
53 of 66 tasks
@greptile-apps

greptile-apps Bot commented Oct 23, 2026

Copy link
Copy Markdown

Want your agent to iterate on Greptile's feedback? Try greploops.

@chrisgervang
chrisgervang merged commit c782203 into visgl:master Oct 24, 2026
8 checks passed
@chrisgervang

Copy link
Copy Markdown
Collaborator

Released in deck.gl 9.4.1. Thanks @dchaudhari7177!

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.

[Bug] GlobeView can not zoom in past 12 zoom - n.getZoomAnchorStrength is not a function

3 participants