UNPKG

@deck.gl/core

Version:

deck.gl core library

110 lines 3.98 kB
// deck.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors /** A small wrapper that turns mapbox-gl or maplibre-gl Map into a stateless component */ export class MapWrapper { constructor(props) { this.map = null; this.width = 0; this.height = 0; this.props = { ...props }; this._initialize(this.props); } finalize() { this.map?.remove(); this.map = null; } setProps(props) { const oldProps = this.props; const newProps = { ...this.props, ...props }; this.props = newProps; if (!this.map) { return; } const needsRedraw = this._update(oldProps, newProps); if (needsRedraw) { this.redraw(); } } // Force redraw the map now. Typically resize() and jumpTo() is reflected in the next // render cycle, which is managed by Mapbox's animation loop. // This removes the synchronization issue caused by requestAnimationFrame. redraw() { const map = this.map; // map._render will throw error if style does not exist // https://github.com/mapbox/mapbox-gl-js/blob/fb9fc316da14e99ff4368f3e4faa3888fb43c513 // /src/ui/map.js#L1834 if (map.style) { // cancel the scheduled update if (map._frame) { map._frame.cancel(); map._frame = null; } // the order is important - render() may schedule another update map._render(); } } // External apps can access map this way getMap() { return this.map; } _initialize(props) { const { mapLib, container } = props; // Creation only props mapLib.accessToken = props.mapboxApiAccessToken || ''; this.map = new props.mapLib.Map({ container, maxZoom: 24, ...props.mapOptions, ...viewStateToMapboxProps(props.viewState), style: props.mapStyle, interactive: false, trackResize: false }); // Hijack dimension properties // This eliminates the timing issue between calling resize() and DOM update /* eslint-disable accessor-pairs */ Object.defineProperty(container, 'offsetWidth', { get: () => this.width }); Object.defineProperty(container, 'clientWidth', { get: () => this.width }); Object.defineProperty(container, 'offsetHeight', { get: () => this.height }); Object.defineProperty(container, 'clientHeight', { get: () => this.height }); this.map.resize(); } _update(oldProps, newProps) { const styleChanged = oldProps.mapStyle !== newProps.mapStyle; if (styleChanged) { this.map.setStyle(newProps.mapStyle); } const sizeChanged = oldProps.width !== newProps.width || oldProps.height !== newProps.height; if (sizeChanged) { this.width = newProps.width; this.height = newProps.height; this.map.resize(); } const oldViewState = oldProps.viewState; const newViewState = newProps.viewState; const viewportChanged = newViewState.latitude !== oldViewState.latitude || newViewState.longitude !== oldViewState.longitude || newViewState.zoom !== oldViewState.zoom || newViewState.pitch !== oldViewState.pitch || newViewState.bearing !== oldViewState.bearing; if (viewportChanged) { this.map.jumpTo(viewStateToMapboxProps(newViewState)); } return sizeChanged || viewportChanged; } } function viewStateToMapboxProps(viewState) { return { center: [viewState.longitude, viewState.latitude], zoom: viewState.zoom, bearing: viewState.bearing ?? 0, pitch: viewState.pitch ?? 0 }; } //# sourceMappingURL=map-wrapper.js.map