Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leaflet: adjust popup to picture size

I'm trying to include pictures in my leaflet popups, but the popup-size doesn't adjust to the picture size. I found a solution to this on github:

https://github.com/Leaflet/Leaflet/issues/724

While that solution fixes the size of the popup, the result is shifted and the popup doesn't show up centered over the icon/marker... Any way to change that?

.leaflet-popup-content { 
     width:auto !important; 
}

screenshot from 2016-07-03 14 19 25

Also the other proposed solution (setting the maxWidth on the popup) doesn't help in my case. The popup width keeps on being the default width of 300px...

function pop_Fotos(feature, layer) {
     var popupContent = '<img style="max-height:500px;max-width:500px;" src="...");
     layer.bindPopup(popupContent, {maxWidth: 500, closeOnClick: true});
}

screenshot from 2016-07-03 14 49 15

like image 435
Klaster Avatar asked Jul 03 '16 13:07

Klaster


4 Answers

Simply specifying maxWidth: "auto" option on the popup seems enough…

layer.bindPopup(popupContent, {
  maxWidth: "auto"
});

Demo: http://jsfiddle.net/3v7hd2vx/29/


EDIT

Unfortunately, if the image is not loaded yet in browser cache, the popup will open right away with default size, and adjust its size but not its position once the image is fully loaded and displayed. As a result, the popup is shifted and its arrow is misplaced compared to the marker it is bound to.

A simple workaround is to listen to the image "load" event and to re-open the popup at that moment:

popupContent = document.createElement("img");
popupContent.onload = function () {
  layer.openPopup();
};
popupContent.src = "path/to/image";
layer.bindPopup(popupContent, {
  maxWidth: "auto"
});

Updated demo: http://jsfiddle.net/3v7hd2vx/32/


EDIT 2

Here is a more general solution: capture the <IMG>'s "load" event on all Leaflet popups and force them to update() every time.

document.querySelector(".leaflet-popup-pane").addEventListener("load", function (event) {
  var tagName = event.target.tagName,
      popup = map._popup; // Currently open popup, if any.

  if (tagName === "IMG" && popup) {
    popup.update();
  }
}, true); // Capture the load event, because it does not bubble.

Demo: https://jsfiddle.net/3v7hd2vx/277/

Reference: Leaflet issue #5484 (comment)

like image 100
ghybs Avatar answered Oct 14 '22 01:10

ghybs


  • There is an update function for popups (which the doc says is for just this purpose): http://leafletjs.com/reference.html#popup-update .

  • Also, an event for when a pop up is opened: http://leafletjs.com/reference.html#path-popupopen .

  • And the event passed to the event handler identifies the popup: http://leafletjs.com/reference.html#popup-event-popup

My pop up content was a bit more varied than just a simple image, but the width was, of course, still affected by any the load time for images in the content (and was ok once the image was in the browser cache).

So when I hit this problem, in summary what I did using jQuery:

function addpopup(mymarker, mycontent) {
    var myid = "thismarker"; // or whatever
    mymarker.bindPopup("<div id='"+myid+"'>" + mycontent + "</div>",
      {maxWidth: "auto"});
    mymap.on("popupopen", function(e){
        $("#"+myid+" img").one("load", function(){ e.popup.update(); });
    });
}
like image 45
frankieandshadow Avatar answered Oct 14 '22 03:10

frankieandshadow


None of the before added answers worked for me, but I came upon a quite simple solution (the link of which I can no longer find). Just wrap your image in a div:

    <div class='ppcont'><img src='yourimg.jpg' /></div>

And add a simple css rule that corresponds to the image width:

    .ppcont{width:100px;}

Now the popup should load correctly and it solves the need for updates or closing/opening again.

like image 20
sharkondero Avatar answered Oct 14 '22 03:10

sharkondero


A more general and simple solution is to use html classes and the function update from popup class

On every image inside the popup add a specific class

<img class="img-in-popup" src="/path/to/img.jpg">

Then just update the popup when any image therein is fully loaded.

var map = L.map('map', mapOptions)
// add layers, etc

map.on('popupopen', function (e) {
  $('img.img-in-popup').on('load', function () {
    e.popup.update()
  })
})

Note that popup.update() will trigger several times if several images are inside the same popup, but that is not actually a problem.

like image 2
João Pimentel Ferreira Avatar answered Oct 14 '22 02:10

João Pimentel Ferreira