I have created a map with leaflet and have an array of 3 locations and for each location, I am creating a marker with a popup window.
Now I want to know how can I change the center of the map when I click on each map marker. Currently, the value is hardcoded but I want it to be dynamic.
How can something like this be accomplished?
import L from "leaflet";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
import parse from "html-react-parser";
import logoFFB from "@/images/ffb.svg";
const Map = () => {
const coordinates = [
{
id: 1,
popup: `
<div>
<a href="#" target="_blank" >
<img src=${logoFFB} alt="Friends For Brands" />
</a>
<h4 >Lorem Ipsum</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean cursus ligula sapien, dignissim pretium nisl pharetra id.</p>
<p>Maecenas venenatis blandit risus, eu faucibus lorem vehicula at. Aliquam finibus magna tellus, eu pharetra nibh vehicula sed.</p>
</div>
`,
lat: 51.91662,
lng: 4.4727,
},
{
id: 2,
popup: `
<div>
<a href="https://mediamarkt.nl" target="_blank" >
<img src="https://upload.wikimedia.org/wikipedia/commons/f/f0/Media_Markt_logo.svg" alt="Mediamarkt" />
</a>
<h4 >Lorem Ipsum</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean cursus ligula sapien, dignissim pretium nisl pharetra id.</p>
<p>Maecenas venenatis blandit risus, eu faucibus lorem vehicula at. Aliquam finibus magna tellus, eu pharetra nibh vehicula sed.</p>
</div>
`,
lat: 51.92019,
lng: 4.48006,
},
{
id: 3,
popup: `
<div>
<a href="https://www.erasmusmc.nl" target="_blank" >
<img src="https://www.erasmusmc.nl/-/media/erasmusmc/images/_platform/logos/full-colour-svg-sophia-kinderziekenhuis-sub-brand-3.svg?la=nl-NL&hash=738FF636E5026AE3B56EE1D79492BB50" alt="MC Sophia" />
</a>
<h4 >Lorem Ipsum</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean cursus ligula sapien, dignissim pretium nisl pharetra id.</p>
<p>Maecenas venenatis blandit risus, eu faucibus lorem vehicula at. Aliquam finibus magna tellus, eu pharetra nibh vehicula sed.</p>
</div>
`,
lat: 51.911781,
lng: 4.4696,
},
];
const CUSTOM_MARKER = `data:image/svg xml;utf8,${encodeURIComponent(`<?xml version="1.0" encoding="iso-8859-1"?>
<svg width="36px" height="36px" viewBox="-4 0 36 36" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Vivid.JS" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Vivid-Icons" transform="translate(-125.000000, -643.000000)">
<g id="Icons" transform="translate(37.000000, 169.000000)">
<g id="map-marker" transform="translate(78.000000, 468.000000)">
<g transform="translate(10.000000, 6.000000)">
<path d="M14,0 C21.732,0 28,5.641 28,12.6 C28,23.963 14,36 14,36 C14,36 0,24.064 0,12.6 C0,5.641 6.268,0 14,0 Z" id="Shape" fill="#FF6E6E"></path>
<circle id="Oval" fill="#0C0058" fill-rule="nonzero" cx="14" cy="14" r="7"></circle>
</g>
</g>
</g>
</g>
</g>
</svg>
`)}`;
return (
<MapContainer
id="map"
center={[51.91662, 4.4727]}
zoom={16}
scrollWheelZoom={false}
>
<TileLayer
attribution="© Friends For Brands"
url="https://tiles.stadiamaps.com/tiles/outdoors/{z}/{x}/{y}{r}.png"
/>
{coordinates.map((coordinate) => (
<Marker
key={coordinate.id}
position={[coordinate.lat, coordinate.lng]}
icon={L.icon({
iconUrl: CUSTOM_MARKER,
iconSize: [35, 35],
iconAnchor: [12, 12],
popupAnchor: [0, 0],
})}
>
<Popup className="text-md">{parse(coordinate.popup)}</Popup>
</Marker>
))}
</MapContainer>
);
};
export default Map;
CodePudding user response:
Add this entry to yout marker:
eventHandlers={{
click(e) {
const location = e.target.getLatLng();
map.flyToBounds([location]);
}
}}
EDIT
I thought you would guess how to pass the map :) Ok here you have all my code as I solved it.
import { useState } from 'react';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
import tileLayer from '../util/tileLayer';
const center = [52.22977, 21.01178];
const zoom = 18;
const points = [
{
lat: 52.230020586193795,
lng: 21.01083755493164,
title: 'point 1'
},
{
lat: 52.22924516170657,
lng: 21.011320352554325,
title: 'point 2'
},
{
lat: 52.229511304688444,
lng: 21.01270973682404,
title: 'point 3'
},
{
lat: 52.23040500771883,
lng: 21.012146472930908,
title: 'point 4'
},
];
const MyMarkers = ({ map, data }) => {
return data.map(({ lat, lng, title }, index) => (
<Marker
key={index}
position={{ lat, lng }}
eventHandlers={{
click(e) {
const location = e.target.getLatLng();
map.flyToBounds([location]);
}
}}
>
<Popup>{title}</Popup>
</Marker>
));
}
const MapWrapper = () => {
const [map, setMap] = useState(null)
return (
<MapContainer
whenCreated={setMap}
center={center}
zoom={zoom}
scrollWheelZoom={false}
>
<TileLayer {...tileLayer} />
<MyMarkers map={map} data={points} />
</MapContainer>
)
}
export default MapWrapper;
And here are some other examples to use.