Skip to content

Create a Draggable Marker

Create markers that users can drag to any location on the map, and capture the updated coordinates.

🔵 Drag the blue marker to see its new coordinates

How It Works

Pass draggable: true to the Marker constructor, then listen to drag and dragend events to get the new position.

Basic Draggable Marker

javascript
const marker = new mapmetricsgl.Marker({
  color: '#3b82f6',
  draggable: true      // Enable dragging
})
  .setLngLat([2.349902, 48.852966])
  .addTo(map);

// Get new position when drag ends
marker.on('dragend', () => {
  const { lng, lat } = marker.getLngLat();
  console.log(`Marker dropped at: ${lng}, ${lat}`);
});

Listen to All Drag Events

javascript
// Fires when drag starts
marker.on('dragstart', () => {
  console.log('Started dragging');
});

// Fires continuously while dragging
marker.on('drag', () => {
  const pos = marker.getLngLat();
  console.log(`Dragging: ${pos.lng}, ${pos.lat}`);
});

// Fires when drag ends
marker.on('dragend', () => {
  const pos = marker.getLngLat();
  console.log(`Dropped at: ${pos.lng}, ${pos.lat}`);
});

Use Case: Pick-up / Drop-off Points

javascript
const pickup = new mapmetricsgl.Marker({ color: '#22c55e', draggable: true })
  .setLngLat([2.34, 48.85])
  .addTo(map);

const dropoff = new mapmetricsgl.Marker({ color: '#ef4444', draggable: true })
  .setLngLat([2.36, 48.86])
  .addTo(map);

function getRoute() {
  const from = pickup.getLngLat();
  const to = dropoff.getLngLat();
  console.log('From:', from, 'To:', to);
  // Call Directions API with these coordinates
}

pickup.on('dragend', getRoute);
dropoff.on('dragend', getRoute);

Complete Example

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <link href="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.css" rel="stylesheet" />
    <script src="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.js"></script>
    <style>
      #map { height: 500px; width: 100%; }
      #info { margin-top: 8px; padding: 8px 12px; background: #1e293b; color: #e2e8f0; border-radius: 6px; font-family: monospace; }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <div id="info">🔵 Drag the marker to see coordinates</div>
    <script>
      const map = new mapmetricsgl.Map({
        container: 'map',
        style: '<StyleFile_URL_with_Token>',
        center: [2.349902, 48.852966],
        zoom: 11
      });

      map.addControl(new mapmetricsgl.NavigationControl(), 'top-right');

      const infoEl = document.getElementById('info');

      const marker = new mapmetricsgl.Marker({ color: '#3b82f6', draggable: true })
        .setLngLat([2.349902, 48.852966])
        .addTo(map);

      marker.on('drag', () => {
        const pos = marker.getLngLat();
        infoEl.textContent = `✋ Lng: ${pos.lng.toFixed(5)}  |  Lat: ${pos.lat.toFixed(5)}`;
      });

      marker.on('dragend', () => {
        const pos = marker.getLngLat();
        infoEl.innerHTML = `📍 Dropped at:  Lng: <strong>${pos.lng.toFixed(5)}</strong>  |  Lat: <strong>${pos.lat.toFixed(5)}</strong>`;
      });
    </script>
  </body>
</html>
jsx
import React, { useEffect, useRef, useState } from 'react';
import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';

const DraggableMarker = () => {
  const mapContainer = useRef(null);
  const map = useRef(null);
  const [position, setPosition] = useState(null);
  const [dragging, setDragging] = useState(false);

  useEffect(() => {
    if (map.current) return;

    map.current = new mapmetricsgl.Map({
      container: mapContainer.current,
      style: '<StyleFile_URL_with_Token>',
      center: [2.349902, 48.852966],
      zoom: 11
    });

    map.current.addControl(new mapmetricsgl.NavigationControl(), 'top-right');

    const marker = new mapmetricsgl.Marker({ color: '#3b82f6', draggable: true })
      .setLngLat([2.349902, 48.852966])
      .addTo(map.current);

    marker.on('dragstart', () => setDragging(true));

    marker.on('drag', () => {
      const pos = marker.getLngLat();
      setPosition({ lng: pos.lng.toFixed(5), lat: pos.lat.toFixed(5) });
    });

    marker.on('dragend', () => {
      setDragging(false);
      const pos = marker.getLngLat();
      setPosition({ lng: pos.lng.toFixed(5), lat: pos.lat.toFixed(5) });
    });

    return () => { map.current?.remove(); map.current = null; };
  }, []);

  return (
    <div>
      <div ref={mapContainer} style={{ height: '500px', width: '100%' }} />
      <div style={{ marginTop: '8px', padding: '8px 12px', background: '#1e293b', color: '#e2e8f0', borderRadius: '6px', fontFamily: 'monospace', fontSize: '14px' }}>
        {position
          ? <>{dragging ? '✋ Dragging...' : '📍 Dropped at:'} Lng: <strong>{position.lng}</strong> | Lat: <strong>{position.lat}</strong></>
          : '🔵 Drag the marker to see its coordinates'
        }
      </div>
    </div>
  );
};

export default DraggableMarker;

For more information, visit the MapMetrics GitHub repository.