6

I have setup a draggable marker on my map with Leaflet API. Its working fine. But the problem is when I am trying to drag it to the border area the map is not moving. I want a panning map with Marker dragging. Please let me also know how can able to control the map panning when dragging the marker.

Thanks

13

you can use map.panTo():

function onMapClick(e) {
  marker = new L.marker(e.latlng, {draggable:'true'});
  marker.on('dragend', function(event){
    var marker = event.target;
    var position = marker.getLatLng();
    marker.setLatLng(new L.LatLng(position.lat, position.lng),{draggable:'true'});
    map.panTo(new L.LatLng(position.lat, position.lng))
  });
  map.addLayer(marker);
};

map.on('click', onMapClick);

Complete html with inline js (minus cloudmade api):

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.css" />
<!--[if lte IE 8]>
 <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.ie.css" />
<![endif]-->
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.js"></script>

<div id="map" style="width: 600px; height: 600px;"></div>

<script>

var map = L.map('map').setView([51.505, -0.09], 13);

L.tileLayer('http://{s}.tile.cloudmade.com/API-KEY/997/256/{z}/{x}/{y}.png', {
  attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery ©     <a href="http://cloudmade.com">CloudMade</a>',
  maxZoom: 18
}).addTo(map);

function onMapClick(e) {
  marker = new L.marker(e.latlng, {draggable:'true'});
  marker.on('dragend', function(event){
    var marker = event.target;
    var position = marker.getLatLng();
    marker.setLatLng(new L.LatLng(position.lat, position.lng),{draggable:'true'});
    map.panTo(new L.LatLng(position.lat, position.lng))
  });
  map.addLayer(marker);
};

map.on('click', onMapClick);

</script>
| improve this answer | |
  • Thanks for your answer. But probably you didn't get my point. In your solution when the marker is released at that time map is panning. But I need something like at the time of grabbing the marker I can pan left right or up down. In simple word I want a real-time pan when grab the draggable marker. – Devils Dream Dec 13 '13 at 13:33
7

In case someone else stumbles upon this and needs a live pan, too.

Just remove the click event like so:

var marker = new L.marker([lat,lon],{
    draggable: true
}).addTo(map);

marker.on("drag", function(e) {
    var marker = e.target;
    var position = marker.getLatLng();
    map.panTo(new L.LatLng(position.lat, position.lng));
});

I wished it would be even more real time, it lags a little behind the mouse.

| improve this answer | |
6

Leaflet now provides this as an option with creating a marker, so there is no need to attach a drag event to pan the map.

Link to docs: https://leafletjs.com/reference-1.3.4.html#marker-autopan

Code sample:

var marker = new L.marker([lat,lon],{
    draggable: true,
    autoPan: true
}).addTo(map);
| improve this answer | |
1

A little different approach here. This will pan the map to where the mouse position is every 1 second. It is pretty smooth though.

This is typescript:

        var mapContainer = $(".detail-bottom-wrap .map-container");
        var mapWidth = -1;
        var mapHeight = -1;
        var mapPosition = null;
        var panPositionThreshold = this.shared.isTablet ? 100 : 60;

        this.draggableMarker.on("drag", (e: any) => {
            var pointerEvents = e.originalEvent.touches;
            if (pointerEvents.length != 1)
                return;

            //Only set on first time drag happens
            if (mapWidth == -1) {
                mapPosition = mapContainer.offset();
                mapWidth = mapContainer.width();
                mapHeight = mapContainer.height();
            }

            //Check left and right boundaries
            this.panningMapEvent = e.originalEvent;
            var mouseX = e.originalEvent.x
            var mouseY = e.originalEvent.y;

            if (mouseX < mapPosition.left + panPositionThreshold) {
                //Dragging to left
                this.togglePanningMode(true);
            }
            else if (mouseX > mapPosition.left + mapWidth - panPositionThreshold) {
                //Dragging to right
                this.togglePanningMode(true);
            }
            else {
                this.togglePanningMode(false);
            }

        });
        this.draggableMarker.on("dragend", (e: any) => {
            mapWidth = -1;
            this.togglePanningMode(false);
        });

 private togglePanningMode(active: boolean) {
    this.draggableMarker.setLatLng(this.map.mouseEventToLatLng(this.panningMapEvent));

    if (active) {
        //Only start interval if it's been stopped
        if (this.panningActiveId == -1) {
            window.clearInterval(this.panningActiveId);
            this.panningActiveId = window.setInterval(() => {
                //Convert mouse position to lat lng, and pan marker
                var mousePositionLatLng: L.LatLng = this.map.mouseEventToLatLng(this.panningMapEvent);
                this.map.panTo(mousePositionLatLng, { animate: true });
                this.draggableMarker.setLatLng(mousePositionLatLng);
                this.map.once("moveend zoomend", () => {
                    this.draggableMarker.setLatLng(this.map.mouseEventToLatLng(this.panningMapEvent));
                });
            }, 1000);
        }
    }
    else {
        window.clearInterval(this.panningActiveId);
        this.panningActiveId = -1;
    }
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.