diff --git a/examples/deckgl-overlay/src/app.tsx b/examples/deckgl-overlay/src/app.tsx index 1c0046c99..8934443ae 100644 --- a/examples/deckgl-overlay/src/app.tsx +++ b/examples/deckgl-overlay/src/app.tsx @@ -1,34 +1,40 @@ import * as React from 'react'; import {render} from 'react-dom'; -import DeckGL, {ArcLayer} from 'deck.gl'; -import Map from 'react-map-gl'; +import {ArcLayer} from 'deck.gl'; +import {MapboxLayer} from '@deck.gl/mapbox'; +import Map, {Layer} from 'react-map-gl'; +import ControlPanel from './control-panel'; const TOKEN = ''; // Set your mapbox token here export default function App() { - const arcLayer = new ArcLayer({ - data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-segments.json', - getSourcePosition: d => d.from.coordinates, - getTargetPosition: d => d.to.coordinates, - getSourceColor: [255, 200, 0], - getTargetColor: [0, 140, 255], - getWidth: 12 - }); + const [overLabels, setOverLabels] = React.useState(true); + const layer = React.useMemo(() => { + return new MapboxLayer({ + id: 'arcs', + type: ArcLayer, + data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-segments.json', + getSourcePosition: d => d.from.coordinates, + getTargetPosition: d => d.to.coordinates, + getSourceColor: [255, 200, 0], + getTargetColor: [0, 140, 255], + getWidth: 12 + }); + }, []); return ( - - - + <> + + + + + ); } diff --git a/examples/deckgl-overlay/src/control-panel.tsx b/examples/deckgl-overlay/src/control-panel.tsx new file mode 100644 index 000000000..48d1f1e96 --- /dev/null +++ b/examples/deckgl-overlay/src/control-panel.tsx @@ -0,0 +1,32 @@ +import React from 'react'; + +function Checkbox({name, value, onChange}) { + return ( +
+ + onChange(name, evt.target.checked)} /> +
+ ); +} + +function ControlPanel({ + overLabels, + setOverLabels +}: { + overLabels: boolean; + setOverLabels: (v: boolean) => void; +}) { + return ( +
+

Deck.gl layer

+

A deck.gl overlay can be used and inserted inside the Mapbox layers.

+ setOverLabels(v)} + /> +
+ ); +} + +export default ControlPanel; diff --git a/src/components/layer.ts b/src/components/layer.ts index 5c17c224e..ea624c271 100644 --- a/src/components/layer.ts +++ b/src/components/layer.ts @@ -12,19 +12,26 @@ export type LayerProps = AnyLayer & { }; /* eslint-disable complexity, max-statements */ -function updateLayer(map: MapboxMap, id: string, props: LayerProps, prevProps: LayerProps) { +function updateLayer( + map: MapboxMap, + id: string, + props: LayerProps, + prevProps: LayerProps, + beforeId?: string +) { assert(props.id === prevProps.id, 'layer id changed'); assert(props.type === prevProps.type, 'layer type changed'); + if (beforeId !== prevProps.beforeId) { + map.moveLayer(id, beforeId); + } + if (props.type === 'custom' || prevProps.type === 'custom') { return; } - const {layout = {}, paint = {}, filter, minzoom, maxzoom, beforeId} = props; + const {layout = {}, paint = {}, filter, minzoom, maxzoom} = props; - if (beforeId !== prevProps.beforeId) { - map.moveLayer(id, beforeId); - } if (layout !== prevProps.layout) { const prevLayout = prevProps.layout || {}; for (const key in layout) { @@ -59,14 +66,11 @@ function updateLayer(map: MapboxMap, id: string, props: LayerProps, prevProps: L } } -function createLayer(map: MapboxMap, id: string, props: LayerProps) { +function createLayer(map: MapboxMap, id: string, props: LayerProps, beforeId: string) { // @ts-ignore if (map.style && map.style._loaded && (!('source' in props) || map.getSource(props.source))) { - const options: LayerProps = {...props, id}; - delete options.beforeId; - // @ts-ignore - map.addLayer(options, props.beforeId); + map.addLayer(props, beforeId); } } @@ -74,12 +78,23 @@ function createLayer(map: MapboxMap, id: string, props: LayerProps) { let layerCounter = 0; -function Layer(props: LayerProps) { +function Layer(props: LayerProps & {layer?: LayerProps}) { const map: MapboxMap = useContext(MapContext).map.getMap(); - const propsRef = useRef(props); + + const layerProps = useMemo(() => { + if (props.layer) { + return props.layer; + } + const res = {...props}; + delete res.beforeId; + return res; + }, [props.layer, props]); + + const layerPropsRef = useRef(layerProps); const [, setStyleLoaded] = useState(0); + const beforeId = props.beforeId; - const id = useMemo(() => props.id || `jsx-layer-${layerCounter++}`, []); + const id = useMemo(() => layerProps.id || `jsx-layer-${layerCounter++}`, []); useEffect(() => { if (map) { @@ -102,16 +117,16 @@ function Layer(props: LayerProps) { const layer = map && map.style && map.getLayer(id); if (layer) { try { - updateLayer(map, id, props, propsRef.current); + updateLayer(map, id, layerProps, layerPropsRef.current, beforeId); } catch (error) { console.warn(error); // eslint-disable-line } } else { - createLayer(map, id, props); + createLayer(map, id, layerProps, beforeId); } // Store last rendered props - propsRef.current = props; + layerPropsRef.current = layerProps; return null; }