Home > Mobile >  OnClick marker change map center position
OnClick marker change map center position

Time:09-21

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="&copy; 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.

  • Related