Changer la position du popup sur le marqueur Leaflet?

13

Je veux ouvrir une fenêtre contextuelle au bas de mon icône de marqueur dans Leaflet.

mon code:

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

L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw', {
    maxZoom: 18,
    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://mapbox.com">Mapbox</a>',
    id: 'mapbox.streets'
}).addTo(mymap);

var lati = 51.51;
var longi = -0.09;

var popupLocation1 = new L.LatLng(lati, longi);
var popupContent1 = 'This is a nice popup';

popup1 = new L.Popup();
popup1.setLatLng(popupLocation1);
popup1.setContent(popupContent1);

var m1 = L.marker([ lati, longi ]).addTo(mymap);

m1.bindPopup(popup1);

m1.openPopup();

Je reçois donc une fenêtre contextuelle au-dessus de mon marqueur.

Je veux obtenir un popup en bas comme:

entrez la description de l'image ici

Gerd
la source
Consultez ce Q / A, stackoverflow.com/questions/27144334/…
artwork21
sur votre lien n'est pas une solution de travail. Peut-être que le commentaire est vrai: "ce que vous pourriez faire, c'est vous accrocher au clic du marqueur et dessiner votre propre popup avec du code personnalisé" Pas de moyen simple pour le popup en bas?
Gerd
1
La situation actuelle est la même que dans le lien de commentaire de artwork21, concernant votre question pour le popup sous le marqueur. Voir la réponse de FranceImage ( stackoverflow.com/a/27144900/5108796 ) avec le plugin proposé. Vous pouvez utiliser ce plugin ou vous en inspirer pour créer votre propre popup personnalisé.
ghybs
Ne pouvons-nous pas le faire dans le positionnement CSS de la popup elle-même? Parce que par défaut, cela fait référence au bas, si nous basculons vers le haut, ce sera correct [jusqu'à un décalage fixe], quelles que soient les polices / tailles de police / hauteurs de ligne choisies et le nombre de lignes de texte? J'oublie probablement quelque chose.
user3445853

Réponses:

4

Vous pouvez spécifier les décalages à l'aide des popupAnchoroptions, mais pas là où vous vous y attendez. Tout d'abord, vous devez spécifier une icône comme celle-ci:

var myIcon = L.divIcon({ popupAnchor: [0, -30] });

Vous pouvez ensuite utiliser cette icône dans vos options de marqueur:

var marker = L.marker(location, {
                 icon: myIcon
             }).bindPopup(function (marker) {...}); //Shortened

Votre popup s'ouvre maintenant à 30 px au-dessus de votre marqueur. Ce n'est pas exactement ce que vous avez demandé car vous devez également placer le petit triangle fléché sur le dessus de votre fenêtre contextuelle, mais je pense que cela vaut la peine d'être mentionné.

Alex
la source
Même problème qu'avec la réponse la plus récente [29 août 2019] de @Johannes: Ce décalage est incorrect aussi vite qu'il y a une deuxième ligne ou plus de texte dans le popup; ou des changements dans CSS (taille de police, police, hauteur de ligne, remplissage, marge, taille de popup, ...). D'où la réponse originale "il n'y a pas de solution native".
user3445853
2

Je sais que c'est une vieille question, mais vous n'avez pas besoin de faire le détour @Robert décrit dans sa réponse.

Comme Popuphérité de DivOverlay, vous pouvez définir l'option de décalage directement lors de l'initialisation de Popup:

    var popup = L.popup({
        offset: [0, -30]
    })
      .setLatLng(location)
      .setContent("Test Text")
      .openOn(mapId);

Lisez les documents: https://leafletjs.com/reference-1.5.0.html#popup

Johannes
la source
Le problème avec cette approche est que vous avez des nombres magiques pour le décalage: si la taille de police ou la police ou même la hauteur de ligne change, le décalage est mauvais. Plus problématique, si certaines fenêtres contextuelles contiennent une deuxième (ou troisième, etc.) ligne de texte, elles ont maintenant une hauteur de ligne complète (ou deux, etc.) trop élevée et chevauchent probablement complètement le marqueur et son voisinage. Vous devrez probablement mesurer la hauteur du texte à l'intérieur de la fenêtre contextuelle et modifier dynamiquement le décalage et le déplacer à l'aide de JS pendant / après le rendu; ou avoir un CSS très fixe et le calculer pendant la carte de votre dépliant avant d'ajouter le marqueur.
user3445853
1

Cela semble possible uniquement en CSS. Ci-dessous, je remplace (avec !important) seulement trois éléments CSS et j'ajoute un :beforepseudo-élément. Je suis essentiellement en train d'aligner la fenêtre contextuelle avec le haut au lieu du bas , où cela 55px dépend simplement de votre marqueur choisi et de vos goûts personnels.

Je déplace ensuite la "pointe" de la fenêtre contextuelle de bas en haut top:0pxet découvre qu'elle n'est pas faite à l'aide de l'astuce "normale" (c'est-à-dire: positionnez d'abord sur le bord de la bulle un pseudo-élément de taille 0x0 avec une bordure transparente épaisse, puis colorez cette couleur frontière opposée de l'élément de l'endroit où vous voulez pointer; dans notre cas, la bordure inférieure). Au lieu de cela, il semble être fait à partir d'un rectangle tourné à partir de quelque part en haut à gauche (peut-être: parce qu'il force le navigateur à utiliser le GPU et accélère donc tout?) Et je ne comprends pas assez bien le point (pardonnez le jeu de mots) ( ma pointe est au bon endroit mais invisible); donc je supprime juste l'ombre de la boîte qui est maintenant au mauvais endroit et laisse le tout tel quel --- quiconque comprend la "vieille astuce" s'il vous plaît ajustez cela.

Donc, au lieu de cela, je fais ma propre astuce, avec le processus "normal" (si vous n'êtes pas sûr, changez les quatre couleurs de bordure ci-dessous, au lieu de 3x transparent et 1x blanc --- par exemple border-bottom-color: blue; border-left-color: green; border-top-color: yellow' border-right-color: red).

#map {
   position: absolute;
   top: 0;
   right: 0;
   left: 0;
   bottom: 0;
   z-index: 0;
}
.leaflet-popup {top: 55px !important;}
/* Here I move the "tip" to the right location, but didn't succeed in making it visible. So I just remove the box-shadow and leave it: */
.leaflet-popup-tip-container {
   top: 0px !important;
}
.leaflet-popup-tip {
   box-shadow: none !important;
}
.leaflet-popup:before 
    {
    content: "";
    position: absolute;
    border: 13px solid transparent;
    border-bottom-color: white;
    bottom: 0px;
    margin-left: -13px;
}

Comme le démontre ce JSFiddle , aucun problème avec différentes tailles de popup (largeur différente, hauteur de texte différente) si vous essayez les deux marqueurs.

Dans l'ensemble, cela semble robuste contre les mises à jour dans Leaflet car les éléments que je remplace ne semblent pas susceptibles de changer.

user3445853
la source