1- import React , { useMemo , useContext , useRef , useCallback } from "react" ;
1+ import React , { useMemo , useContext , useRef , useState , useEffect } from "react" ;
22import { MapView , Camera } from "@maplibre/maplibre-react-native" ;
33import { MapContext } from "./MapProvider.js" ;
44import { withWQ } from "@wq/react" ;
55import { useBasemapStyle } from "../hooks.js" ;
66import PropTypes from "prop-types" ;
77
8- function Map ( {
9- name,
10- initBounds,
11- children,
12- containerStyle,
13- basemap,
14- ...mapProps
15- } ) {
8+ function Map ( { initBounds, children, containerStyle, basemap, ...mapProps } ) {
169 const { setInstance } = useContext ( MapContext ) ,
1710 fitBounds = useMemo ( ( ) => {
11+ if ( ! initBounds ) {
12+ return null ;
13+ }
1814 const [ [ xmin , ymin ] , [ xmax , ymax ] ] = initBounds ;
1915 return { sw : [ xmin , ymin ] , ne : [ xmax , ymax ] } ;
2016 } , [ initBounds ] ) ,
@@ -29,27 +25,12 @@ function Map({
2925
3026 const mapRef = useRef ( ) ,
3127 cameraRef = useRef ( ) ,
32- mapInstance = useMemo ( ( ) => createMapInstance ( mapRef , cameraRef ) , [ ] ) ,
33- onInit = useCallback (
34- ( ) => setInstance ( mapInstance , name ) ,
35- [ setInstance , mapInstance ]
36- ) ,
37- onPress = useCallback (
38- ( e ) => {
39- if ( mapInstance . handlers . click ) {
40- mapInstance . handlers . click ( e ) ;
41- }
42- } ,
43- [ mapInstance ]
28+ [ cameraProps , setCameraProps ] = useState ( { } ) ,
29+ mapInstance = useMemo (
30+ ( ) => createMapInstance ( mapRef , cameraRef , setCameraProps ) ,
31+ [ ]
4432 ) ,
45- onMove = useCallback (
46- ( e ) => {
47- if ( mapInstance . handlers . move ) {
48- mapInstance . handlers . move ( e ) ;
49- }
50- } ,
51- [ mapInstance ]
52- ) ;
33+ { handleClick, handleMove } = mapInstance ;
5334
5435 let rotateEnabled , pitchEnabled ;
5536 if ( mapProps . rotateEnabled !== undefined ) {
@@ -67,6 +48,11 @@ function Map({
6748 pitchEnabled = rotateEnabled ;
6849 }
6950
51+ useEffect ( ( ) => {
52+ setInstance ( mapInstance ) ;
53+ return ( ) => setInstance ( null ) ;
54+ } , [ mapRef . current ] ) ;
55+
7056 return (
7157 < MapView
7258 ref = { mapRef }
@@ -76,12 +62,17 @@ function Map({
7662 attributionEnabled = { false }
7763 logoEnabled = { false }
7864 style = { style }
79- onPress = { onPress }
80- onWillStartLoadingMap = { onInit }
81- onRegionDidChange = { onMove }
65+ onPress = { handleClick }
66+ onRegionDidChange = { handleMove }
8267 { ...mapProps }
8368 >
84- < Camera ref = { cameraRef } bounds = { fitBounds } animationDuration = { 0 } />
69+ < Camera
70+ ref = { cameraRef }
71+ defaultSettings = { {
72+ bounds : fitBounds ,
73+ } }
74+ { ...cameraProps }
75+ />
8576 { children }
8677 </ MapView >
8778 ) ;
@@ -98,17 +89,36 @@ Map.propTypes = {
9889export default withWQ ( Map ) ;
9990
10091// Mimic some functions from maplibre-gl-js & react-map-gl
101- export function createMapInstance ( mapRef , cameraRef ) {
102- return {
103- handlers : { } ,
92+ export function createMapInstance ( mapRef , cameraRef , setCameraProps ) {
93+ const instance = {
94+ handlers : {
95+ click : [ ] ,
96+ move : [ ] ,
97+ } ,
10498 on ( event , handler ) {
105- if ( ! [ "click" , "move" ] . includes ( event ) ) {
99+ if ( ! ( event in this . handlers ) ) {
106100 console . warn ( "Unsupported event: " + event ) ;
107101 }
108- this . handlers [ event ] = handler ;
102+ this . handlers [ event ] . push ( handler ) ;
109103 } ,
110- off ( event ) {
111- delete this . handlers [ event ] ;
104+ off ( event , handler ) {
105+ if ( ! ( event in this . handlers ) ) {
106+ console . warn ( "Unsupported event: " + event ) ;
107+ }
108+ this . handlers [ event ] = this . handlers [ event ] . filter (
109+ ( h ) => h !== handler
110+ ) ;
111+ } ,
112+ _runHandlers ( event , e ) {
113+ for ( const handler of this . handlers [ event ] ) {
114+ handler ( e ) ;
115+ }
116+ } ,
117+ handleClick ( e ) {
118+ this . _runHandlers ( "click" , e ) ;
119+ } ,
120+ handleMove ( e ) {
121+ this . _runHandlers ( "move" , e ) ;
112122 } ,
113123 flyTo ( { center, zoom } ) {
114124 this . getCamera ( ) ?. flyTo ( center , zoom ) ;
@@ -130,5 +140,11 @@ export function createMapInstance(mapRef, cameraRef) {
130140 getCamera ( ) {
131141 return cameraRef . current ;
132142 } ,
143+ setCameraProps,
133144 } ;
145+
146+ instance . handleClick = instance . handleClick . bind ( instance ) ;
147+ instance . handleMove = instance . handleMove . bind ( instance ) ;
148+
149+ return instance ;
134150}
0 commit comments