Skip to content
Create a Draggable Point

Create a Draggable Point

A draggable point rendered as a GeoJSON circle layer is more customizable than a Marker because you control the appearance entirely through layer paint properties. The interaction is built by listening to mousedown on the layer, then tracking mousemove on the map to update the source coordinates, and releasing on mouseup. Use this approach when you need a draggable point that matches your map’s visual style or needs to interact with other GeoJSON features.

const API_KEY = 'YOUR_API_KEY';

    const map = new maptoolkit.Map({
        container: 'map',
        apiKey: API_KEY,
        style: `https://styles.maptoolkit.net/maptoolkit/maptoolkit.summer.json?api_key=${API_KEY}`,
        center: [11.39085, 47.27574],
        zoom: 12,
        attributionControl: { compact: false }
    });

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

    const geojson = {
        type: 'FeatureCollection',
        features: [{
            type: 'Feature',
            geometry: { type: 'Point', coordinates: [11.39085, 47.27574] }
        }]
    };

    map.on('load', () => {
        map.addSource('point', { type: 'geojson', data: geojson });

        map.addLayer({
            id: 'point',
            type: 'circle',
            source: 'point',
            paint: { 'circle-radius': 10, 'circle-color': '#3887be' }
        });

        let isDragging = false;

        map.on('mousedown', 'point', (e) => {
            e.preventDefault();
            isDragging = true;
            map.getCanvas().style.cursor = 'grabbing';
        });

        map.on('mousemove', (e) => {
            if (!isDragging) return;
            geojson.features[0].geometry.coordinates = [e.lngLat.lng, e.lngLat.lat];
            map.getSource('point').setData(geojson);
            document.getElementById('coords').textContent = `${e.lngLat.lng.toFixed(5)}, ${e.lngLat.lat.toFixed(5)}`;
        });

        map.on('mouseup', () => {
            if (!isDragging) return;
            isDragging = false;
            map.getCanvas().style.cursor = '';
        });

        map.on('mouseleave', 'point', () => {
            if (!isDragging) map.getCanvas().style.cursor = '';
        });

        map.on('mouseenter', 'point', () => {
            if (!isDragging) map.getCanvas().style.cursor = 'grab';
        });
    });
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Create a Draggable Point - Maptoolkit Maps JS</title>
    <meta property="og:description" content="Create a draggable GeoJSON point on a map layer." />
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://unpkg.com/@maptoolkit/[email protected]/dist/maptoolkit.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/@maptoolkit/[email protected]/dist/maptoolkit.css" />
    <style>
        html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
        #map { width: 100%; height: 100%; }
        #coords {
            position: absolute;
            bottom: 30px;
            left: 10px;
            background: white;
            padding: 8px 14px;
            border-radius: .4rem;
            font-family: sans-serif;
            font-size: 13px;
        }
    </style>
</head>
<body>
<div id="map"></div>
<div id="coords">Drag the point</div>
<script>
    const API_KEY = 'YOUR_API_KEY';

    const map = new maptoolkit.Map({
        container: 'map',
        apiKey: API_KEY,
        style: `https://styles.maptoolkit.net/maptoolkit/maptoolkit.summer.json?api_key=${API_KEY}`,
        center: [11.39085, 47.27574],
        zoom: 12,
        attributionControl: { compact: false }
    });

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

    const geojson = {
        type: 'FeatureCollection',
        features: [{
            type: 'Feature',
            geometry: { type: 'Point', coordinates: [11.39085, 47.27574] }
        }]
    };

    map.on('load', () => {
        map.addSource('point', { type: 'geojson', data: geojson });

        map.addLayer({
            id: 'point',
            type: 'circle',
            source: 'point',
            paint: { 'circle-radius': 10, 'circle-color': '#3887be' }
        });

        let isDragging = false;

        map.on('mousedown', 'point', (e) => {
            e.preventDefault();
            isDragging = true;
            map.getCanvas().style.cursor = 'grabbing';
        });

        map.on('mousemove', (e) => {
            if (!isDragging) return;
            geojson.features[0].geometry.coordinates = [e.lngLat.lng, e.lngLat.lat];
            map.getSource('point').setData(geojson);
            document.getElementById('coords').textContent = `${e.lngLat.lng.toFixed(5)}, ${e.lngLat.lat.toFixed(5)}`;
        });

        map.on('mouseup', () => {
            if (!isDragging) return;
            isDragging = false;
            map.getCanvas().style.cursor = '';
        });

        map.on('mouseleave', 'point', () => {
            if (!isDragging) map.getCanvas().style.cursor = '';
        });

        map.on('mouseenter', 'point', () => {
            if (!isDragging) map.getCanvas().style.cursor = 'grab';
        });
    });
</script>
</body>
</html>

Use the prompt below with any LLM to get the same result. Make sure the Maptoolkit MCP server is connected first — check out AI Integration & MCP to get started.

Use the Maptoolkit Connector. Create an interactive map with zoom level 12, centered around [11.39085, 47.27574]. Add a draggable GeoJSON point that displays its coordinates, updating as it is dragged.