As the title says, I'm searching how to create a button to enable/disable zoom and pan for leaflet in javascript react. Actually creating a button is fine, but getting the effect I want on my map is not.
I am working on a react project and trying to implement a leaflet map that swiches between an "edit" mode and a "static" mode. Edit would display the map with leaflet-draw commands and allow the user to zoom and pan. Static would hide the whole draw interface and disallow zoom and pan, practically turning the map to a fix image.
I already implemented a leaflet map and a button that adds/remove a "hidden" class to the draw object in my component. Now I am trying to add something to the same button that would switch the zoom and pan between active and inactive.
I manually changed the properties "scrollWheelZoom" and "dragging" in my code and obtained the desired effects, so I guess I now need to change them with the button. I tried to use a querySelector to select my map and change the properties, but it didn't work (I guess the map is already rendered and is not going to change). Then I tried to set the parameter values equal to the boolean state that I use as my switch for the button, but I obtained the same results. Most exemples I saw on the web use a completely different way of creating the map, if I understand well that's because they were not using react in addition to leaflet.
Is there a way to update these properties of my map or to create the map in another way that would allow me to update the properies more easily ?
Here is the current version of the code. "scrollWheelZoom" is updated with the query method and "dragging" with the state method.
//css imports
import './Map.css';
import 'leaflet/dist/leaflet.css';
import 'leaflet-draw/dist/leaflet.draw.css';
//library imports
import React, { useRef, useEffect, useState } from 'react';
import { MapContainer, TileLayer, FeatureGroup } from 'react-leaflet';
import { EditControl } from 'react-leaflet-draw'
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
import L from 'leaflet';
//solution to the missing icon phenomenon in draw
delete L.Icon.Default.prototype._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
iconUrl: require('leaflet/dist/images/marker-icon.png'),
shadowUrl: require('leaflet/dist/images/marker-shadow.png')
});
//component proper
export default function Map(props) {
const [map, setMap] = useState(null) //state that will contain the map object
let [editState, setEditState] = useState(true); // state to toggle the edit buttons
//draw object that contains parameters for the drawing functions
let drawObject = useRef({
circlemarker: false
});
//handler for the edit button to hide/display the drawing tools
function editHandler(e) {
const $plc = e.target.closest('.placeholders');//select placeholder
const $editObjectDraw = $plc.querySelector('.leaflet-draw');//select target object
const $editObjectMap = $plc.querySelector('.mapContainer');
if (editState) {
$editObjectDraw.classList.add('visually-hidden');//update visual state
$editObjectMap.scrollWheelZoom = editState;
} else {
$editObjectDraw.classList.remove('visually-hidden');//update visual state
$editObjectMap.scrollWheelZoom = editState;
}
setEditState(!editState); //reverse boolean state to go from add to remove
}
return (
<div>
<MapContainer className="mapContainer" center={[45.5053, -73.6138]} zoom={1} scrollWheelZoom={true} dragging={editState} minZoom={0} maxZoom={18} ref={setMap}>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<FeatureGroup>
<EditControl
className='drawControl'
position='topright'
onEdited={_onChange}
onCreated={_onChange}
onDeleted={_onChange}
onMounted={_onChange}
onEditStart={_onChange}
onEditStop={_onChange}
onDeleteStart={_onChange}
onDeleteStop={_onChange}
draw={drawObject.current}
/>
</FeatureGroup>
</MapContainer>
<button className="mapControl" onClick={editHandler}>
<EditOutlinedIcon style={{ fill: "#FCF0E5" }} />
<span>Edit</span>
</button>
</div>
)
}
This is my first question here, I hope I didn't make any big mistake before posting it. Thank you in advance for the help.