-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Add basemap-browser example application #9892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Comprehensive test application for deck.gl with multiple basemap providers - Supports Google Maps, Mapbox, MapLibre, and MapLibre Globe - Both Pure JS and React implementations for complete coverage - Interleaved mode toggle for testing shared vs separate GL contexts - Real-time metrics panel showing DPR, canvas dimensions, and drawing buffer - Complete isolation between Pure JS and React implementations - Fixed globe projection in interleaved mode (set projection before overlay) - Labels render above deck.gl layers in interleaved mode using beforeId/slot - TypeScript throughout with full type safety - Covers all 16 test scenarios from resize/DPR bug fix
- Pure JS code now mounts directly to DOM with no React wrapper - Control panel is separate React root that calls callback function - Map area is either Pure JS mount OR separate React root - Complete isolation between Pure JS and React implementations - Removed app.tsx, map-container.tsx, pure-js-container.tsx - Created control-panel.tsx standalone component - Created examples-react/ directory with separate components: - google-maps-component.tsx - mapbox-component.tsx - maplibre-component.tsx - Updated index.html with side-by-side layout (#controls and #map divs) - index.tsx orchestrates two separate React roots - No more React wrapping Pure JS code - true isolation achieved
| if (example) { | ||
| onExampleChange(example, interleaved); | ||
| } | ||
| }, []); // Only on mount |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Duplicate useEffect causes double initialization on mount
Two useEffect hooks both call onExampleChange on initial mount. In React, all useEffect hooks run on mount regardless of their dependency array. The first effect (lines 69-75) with empty deps runs on mount, but the second effect (lines 77-83) also runs on mount because useEffects always execute on initial render. This causes the example to be loaded twice when the component first mounts, potentially resulting in double API calls, visual flickering, or resource waste. The first useEffect is redundant since the second one already handles the initial mount.
Additional Locations (1)
| overlay.finalize(); | ||
| overlay = null; | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Race condition when cleanup called during async loading
The mount function starts an async operation via loadGoogleMapsAPI and returns a cleanup function immediately. The cleanup function only finalizes overlay, but overlay remains null until the promise resolves. If cleanup is called before the API finishes loading (e.g., user quickly switches examples), the cleanup does nothing, yet the async .then() callback continues and creates a map on the container which may now be in use by a different example. There's no cancellation flag to prevent the stale async operation from completing.
- Defer cleanup and remounting to next tick using setTimeout - Prevents synchronous unmount during React render phase - Fixes 'Attempted to synchronously unmount a root' warning - Fixes 'Failed to execute removeChild' error - Extracted mountExample function for cleaner separation
felixpalmer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Given that we have a screenshot widget now, would it be possible to somehow run through all the variants and display a set of thumbnails as a sort of smoke test? Alternatively, could we somehow include these in our automated tests?
I think this is sort of possible! We could add the line of code from the screenshot widget that captures the canvas, and collect screenshots. Similar to a render test it'd go one by one through the examples to collect the results. This would really only be applicable to interleaved renders since those can capture both basemap and deck. Additionally, we could add a maplibre-based render test for the globe and Mercator variants (the others would require API keys to run the tests, which doesn't sound great) |
Summary
This PR adds a comprehensive basemap-browser example application for testing deck.gl with multiple basemap providers across different frameworks and rendering modes.
Features
Use Case
This application makes it easy to test the resize/DPR bug fix across all 16+ test scenarios:
Architecture Highlights
.mount()functions, no React in call stackexamples-react/directoryTechnical Details
beforeId: 'watername_ocean'for MapLibre andslot: 'middle'for MapboxNote
Introduces a TypeScript/React basemap-browser example to test deck.gl across Google Maps, Mapbox, and MapLibre (incl. globe) in Pure JS and React with interleaved toggle and live DPR/canvas metrics.
examples/basemap-browsersrc/control-panel.tsxadds example selector, interleaved toggle, and live metrics (DPR, canvas/client size, drawing buffer) with 100ms polling; layout defined inindex.html.src/examples-pure-js/{google-maps,mapbox,maplibre}.tsmount/unmount helpers; MapLibre globe projection support; Mapbox/Google Maps token handling.src/examples-react/{google-maps-component,mapbox-component,maplibre-component}.tsxwithMapboxOverlay/GoogleMapsOverlayintegration and globe projection ordering.src/examples/index.tsdefines provider×framework configs (Google Maps, Mapbox, MapLibre, MapLibre Globe) matching get-started setups.src/layers.tsprovides airport layers with interleaved placement (slot/beforeId);src/constants.tsexports shared URLs/styles.src/index.tsxmanages dual React roots (controls/map), switches examples with cleanup.package.json(vite start script, deps),tsconfig.json, andREADME.mdwith usage and env var notes.Written by Cursor Bugbot for commit 7255ab9. This will update automatically on new commits. Configure here.