Modifica della posizione popup sull'indicatore Leaflet?


13

Voglio aprire un popup nella parte inferiore della mia icona marcatore in Leaflet.

il mio codice:

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();

Quindi ottengo un popup in cima al mio marker.

Voglio ottenere un popup in basso come:

inserisci qui la descrizione dell'immagine


Dai un'occhiata a questo Q / A, stackoverflow.com/questions/27144334/...
— artwork21

sul tuo link non c'è soluzione funzionante. Forse il commento è vero: "quello che potresti fare è agganciare il clic del marcatore e disegnare il tuo popup con il codice personalizzato" Nessun modo semplice per il popup in basso?
— Gerd,

1
La situazione attuale è la stessa del link al commento di artwork21, riguardo alla tua domanda per il popup sotto il marcatore. Si veda la risposta di FranceImage ( stackoverflow.com/a/27144900/5108796 ) con il plugin proposto. È possibile utilizzare quel plug-in o trarne ispirazione per creare il proprio popup personalizzato.
— ghybs

Non possiamo farlo nel posizionamento CSS del popup stesso? Perché, per impostazione predefinita, fa riferimento alla parte inferiore, se passiamo alla parte superiore, sarà corretto [fino a un offset fisso] indipendentemente dai caratteri / dimensioni dei caratteri / altezza delle linee scelti e numero di righe di testo? Probabilmente sto trascurando qualcosa.
— user3445853

Risposte:


4

Puoi specificare gli offset usando le popupAnchoropzioni, ma non dove ti aspetteresti. Innanzitutto, è necessario specificare un'icona come questa:

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

È quindi possibile utilizzare questa icona nelle opzioni dei marker:

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

Ora il tuo popup si apre 30 px sopra il tuo marker. Questo non è esattamente quello che hai chiesto in quanto devi anche posizionare il piccolo triangolo a forma di freccia in cima al tuo popup, ma penso che valga la pena menzionarlo.


Stesso problema con la risposta più recente del 29 agosto 2019 di @Johannes: questo offset è sbagliato tanto velocemente quanto c'è una seconda o ulteriore riga di testo nel popup; o modifiche nel CSS (font-size, font, line-height, padding, margin, popup size, ...). Da qui la risposta originale "non esiste una soluzione nativa".
— user3445853


2

So che questa è una vecchia domanda, ma non è necessario prendere la deviazione @Robert descritta nella sua risposta.

Come Popuperedita da DivOverlay, è possibile impostare direttamente l'opzione offset quando si inizializza Popup:

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

Leggi i documenti: https://leafletjs.com/reference-1.5.0.html#popup


Il problema con questo approccio è che hai numeri magici per l'offset: se la dimensione del carattere o il carattere o anche l'altezza della linea cambiano, l'offset è negativo. Più problematicamente, se alcuni popup contengono una seconda (o terza, ecc.) Riga di testo, ora sono a una linea intera (o due, ecc.) Troppo alta e probabilmente si sovrappongono completamente al marcatore e al suo vicinato. Probabilmente dovrai misurare l'altezza del testo all'interno del popup e cambiare l'offset in modo dinamico e spostarlo usando JS durante / dopo il rendering; o avere CSS molto fissi e calcolarlo durante la mappa del volantino prima di aggiungere l'indicatore.
— user3445853

1

Questo sembra essere possibile solo nei CSS. Di seguito sovrascrivo (con !important) solo tre elementi CSS e aggiungo uno :beforepseudo-elemento. In sostanza, per prima cosa sto allineando il popup con la parte superiore anziché inferiore , dove 55px dipende solo dal marker scelto e dal gusto personale.

Sposto quindi la "punta" del popup in modo simile dal basso verso top:0px, e scopro che non è stato realizzato usando il trucco "normale" (ovvero: prima posizione sul bordo della bolla uno pseudo-elemento di dimensioni 0x0 con un bordo trasparente spesso, quindi colora quello bordo opposto dell'elemento rispetto al punto in cui si desidera puntare; nel nostro caso, il bordo inferiore). Invece sembra essere fatto da un rettangolo ruotato da qualche parte in alto a sinistra (forse: perché forza il browser a usare la GPU e quindi accelera tutto?) E non capisco abbastanza bene il punto (scusate il gioco di parole) ( il mio consiglio è nel posto giusto ma invisibile); quindi rimuovo solo l'ombra della scatola che ora è nel posto sbagliato e lascio tutto così com'è --- chiunque capisca il "vecchio consiglio", per favore, aggiusta quello.

Quindi invece faccio il mio suggerimento, con il processo "normale" (se non sei sicuro, cambio i quattro colori del bordo in basso, invece di 3x trasparenti e 1x bianco --- ad es 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;
}

Come dimostra questo JSFiddle , nessun problema con diverse dimensioni di popup (diversa larghezza, diversa altezza del testo) se provi entrambi i marcatori.

Tutto sommato, questo sembra robusto rispetto agli aggiornamenti in Leaflet poiché gli elementi che sto sovrascrivendo non sembrano cambiare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.