29

I want center my marker on popup open.. and centering map not in marker latlng, but on center of marker and popup! The problem is that popup has dinamic content(loaded on click).

The map size is full display size in a mobile device! I'm just used autoPanPadding option in popup but not sufficient

Refer to follow picture:

popup centered in leaflet map

Kadir Şahbaz
  • 418
  • 7
  • 21
stefcud
  • 2,220
  • 4
  • 27
  • 37

5 Answers5

58

Using fitzpaddy's answer I was able to make this code which works and is much more flexible.

map.on('popupopen', function(e) {
    var px = map.project(e.target._popup._latlng); // find the pixel location on the map where the popup anchor is
    px.y -= e.target._popup._container.clientHeight/2; // find the height of the popup container, divide by 2, subtract from the Y axis of marker location
    map.panTo(map.unproject(px),{animate: true}); // pan to new center
});
wlarcheveque
  • 894
  • 1
  • 10
  • 28
Dan Mandle
  • 5,608
  • 3
  • 23
  • 26
8

Ciao Stefano,

This is untested pseudocode, but Leaflet project/unproject functions should provide assistance.

i.e;

// Obtain latlng from mouse event
var latlng;
// Convert latlng to pixels
var px = project(latlng);
// Add pixel height offset to converted pixels (screen origin is top left)
px.y -= mypopup.height/2
// Convert back to coordinates
latlng = unproject(px);
// Pan map
map.panTo(latlng,{animate: true});

This depends on zoom scale being constant during calculation, so you might be required to pan the map and then calculate the pan offset to update correctly (using animation, this will only be a gentle transition).

Good luck!

fitzpaddy
  • 491
  • 3
  • 10
6

Here's an easy solution:

First you center the map to your marker.

map.setView(marker.latLng);

Then you open the popup.

var popup.openOn(map); = L.popup()
    .setLatLng(marker.latLng)
    .setContent(dynamic-content)
    .openOn(map);

Leaflet will automatically pan the map so the popup fits on the map. To make it look more beautiful you can add a margin-top to the popup with CSS.

Titsjmen
  • 789
  • 6
  • 15
  • Thanks so much! Was looking for an automatic answer like this. The other answers that calculated the popup height weren't working for me. – Chris Dolphin Jul 22 '15 at 00:09
  • The problem with this solution is that it doesn't center the popup and marker. It will only make sure that the popup is inside of the visible map. – Dan Mandle Jun 08 '16 at 15:22
  • @DanMandle I think that if you would add top: 50%; translate: transformY(-50%); in the CSS it would actually be in the center of the map. – Titsjmen Jun 10 '16 at 09:41
0

My very simple solution keeps the current zoom level as well for better usability.

map.on('popupopen', function (e) {
    map.setView(e.target._popup._latlng, e.target._zoom);
});
Rami Alloush
  • 2,308
  • 2
  • 27
  • 33
0

I took the chance to make a refactoring on @dan-mandle's reply using only public methods since his answer (correct answer) is using many private attributes and it is not the best practice:

    map.on("popupopen", (event) => {
      const popupPixelCoords = map.project(event.popup.getLatLng());
      const popupHeight = event.popup.getElement().clientHeight;
      popupPixelCoords.y -= popupHeight / 2; // move the popup vertical axis location down (distance: half of popup height)
      map.panTo(map.unproject(popupPixelCoords), { animate: true }); // pan to calculated location
    });
rafaels88
  • 839
  • 1
  • 6
  • 19