Skip to content

Commit

Permalink
Better solution
Browse files Browse the repository at this point in the history
  • Loading branch information
easbar committed May 20, 2021
1 parent f683542 commit 933e958
Showing 1 changed file with 19 additions and 19 deletions.
38 changes: 19 additions & 19 deletions src/map/Map.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { QueryPoint } from '@/stores/QueryStore'
import React, { useEffect, useRef, useState } from 'react'
import styles from '@/map/Map.module.css'
import Mapbox from '@/map/Mapbox'
import Mapbox, { ViewPort } from '@/map/Mapbox'
import Dispatcher from '@/stores/Dispatcher'
import { MapIsLoaded } from '@/actions/Actions'
import { Bbox, Path } from '@/api/graphhopper'
Expand All @@ -18,39 +18,39 @@ type MapProps = {
export default function({ selectedPath, paths, queryPoints, bbox, mapStyle }: MapProps) {
const mapContainerRef: React.RefObject<HTMLDivElement> = useRef(null)
const [map, setMap] = useState<Mapbox | null>(null)
// we need to keep track of the latest bbox so it is available in the onMapReady callback by the time the Mapbox
// instance is loaded
const prevBbox = useRef<Bbox>()
useEffect(() => {
prevBbox.current = bbox
}, [bbox])
const prevViewPort = useRef<ViewPort | null>(null)
prevViewPort.current = null

useEffect(() => {
// as long as we re-create the Mapbox instance when changing the mapStyle we need to make sure the viewport
// state is preserved
const prevViewPort = map?.getViewPort()
if (map) map.remove()
if (map) {
map.remove()
// save the current view port so we can set it after re-creating the Mapbox instance when we change mapStyle
prevViewPort.current = map.getViewPort()
}

const mapWrapper = new Mapbox(
mapContainerRef.current!,
mapStyle,
() => {
setMap(mapWrapper)
if (!prevViewPort)
mapWrapper.fitBounds(prevBbox.current!)
Dispatcher.dispatch(new MapIsLoaded())
}
)
if (prevViewPort)
mapWrapper.setViewPort(prevViewPort)
if (prevViewPort.current)
mapWrapper.setViewPort(prevViewPort.current)
return () => map?.remove()
}, [mapStyle, prevBbox])
}, [mapStyle])
useEffect(() => map?.drawPaths(paths, selectedPath), [paths, selectedPath, map])
useEffect(() => map?.showPathDetails(selectedPath), [selectedPath, map])
useEffect(() => map?.drawMarkers(queryPoints), [queryPoints, map])
// no dependency on map here, because in case changed the viewport manually we do not want to go back to the bbox
// after a style change onMapReady
useEffect(() => map?.fitBounds(bbox), [bbox])
useEffect(() => {
// previous view port takes precedence if it was set. for example when we just changed the mapStyle we do
// not want to go back to the bbox
if (prevViewPort.current)
map?.setViewPort(prevViewPort.current)
else
map?.fitBounds(bbox)
}, [bbox, map, prevViewPort])

return <div className={styles.map} ref={mapContainerRef} />
}

0 comments on commit 933e958

Please sign in to comment.