2013-08-23 8 views
9

Sto tentando di visualizzare una finestra in basso su un Google Maps. Si mostra perfetto, quando si passa con il mouse su un marker si carica in una finestra di apertura, ma la mappa salta per adattarsi alla finestra. Non voglio che la mappa si muova, ma piuttosto la finestra di partenza imposta la sua posizione secondo la mappa. Booking.com ha qualcosa di simile.Prevenire spostamento di Google Maps dopo la visualizzazione Infowindow

EDIT: aggiunto il mio codice

Ecco la versione ridotta del mio codice. Ricevo tutte le informazioni da un servizio AJAX e questo servizio restituisce response (che contiene anche altre informazioni).

$.ajax({ 
    url: 'URL', 
    dataType: "json", 
    type: "GET", 
    success: function(response) { 
     // delete all markers 
     clearOverlays(); 

     var infowindow = new google.maps.InfoWindow(); 

     for (var i = 0; i < response.length; i++) { 
      item = response[i]; 

      var marker = new google.maps.Marker({ 
       position: new google.maps.LatLng(item.lat, item.lng), 
       map: map, 
       url: item.detail_url 
      }); 

      markersArray.push(marker); 

      // display infowindow 
      google.maps.event.addListener(marker, "mouseover", (function(marker, item) { 
       return function() { 
        infowindow.setOptions({ 
         content: 'SOME CONTENT HERE FOR INFOWINDOW' 
        }); 

        infowindow.open(map, marker); 
       } 
      })(marker, item)); 

      // remove infowindow 
      google.maps.event.addListener(marker, 'mouseout', function() { 
       infowindow.close(); 
      }); 

      // marker click 
      google.maps.event.addListener(marker, 'click', function() { 
       window.location.href = marker.url; 
      }); 
     } 
    } 
}); 

Come potete vedere qui sotto, la prima immagine mostra l'infowindow visualizzata nella parte inferiore del marcatore, mentre seconda mostra l'infowindow visualizzate sulla parte superiore del marcatore. La mappa non si muove, ma la prima finestra imposta la sua posizione entro i limiti della mappa.

Infowindow bottom of marker Infowindow on top of marker

+0

cosa fa il tuo codice per implementare questo sguardo funzionalità come? – geocodezip

+0

Aggiunto il mio codice Javascript. –

risposta

30

Nella vostra dichiarazione per impostare le opzioni di informazioni della finestra infowindow.setOptions, aggiungere la seguente opzione per disabilitare il panning della mappa quando viene visualizzato l'infowindow, disableAutoPan : true.

Tuttavia, ciò significa anche che dovrai calcolare gli immobili che hai a disposizione per visualizzare la finestra di navigazione sulla mappa e assegnargli una posizione utilizzando l'opzione position. Altrimenti non sarà garantito che il tuo infowindow sarà completamente visibile sulla mappa.

https://developers.google.com/maps/documentation/javascript/reference#InfoWindowOptions

EDIT: Come calcolare bene immobile dello schermo

mi rendo conto che ero piuttosto vago con il mio suggerimento per calcolare il bene immobile dello schermo a disposizione per impostare la posizione del vostro infowindow, quando parte della tua domanda era di impostare effettivamente la posizione dell'infinito. Quindi ho fornito un aggiornamento alla mia risposta su come è possibile calcolare lo spazio reale sullo schermo e regolare la posizione dell'infinito.

La chiave è innanzitutto convertire i punti da LatLng in pixel e individuare la coordinata di pixel dell'indicatore sulla mappa in relazione alla coordinata di pixel del centro della mappa. Il seguente frammento mostra come questo può essere fatto.

getPixelFromLatLng: function (latLng) { 
    var projection = this.map.getProjection(); 
    //refer to the google.maps.Projection object in the Maps API reference 
    var point = projection.fromLatLngToPoint(latLng); 
    return point; 
} 

Una volta che hai le coordinate dei pixel, è necessario scoprire quale quadrante della carta di tela il marcatore è attualmente residente a. Questo risultato è ottenuto confrontando le coordinate X e Y del marcatore la mappa, in questo modo:

quadrant += (point.y > center.y) ? "b" : "t"; 
quadrant += (point.x < center.x) ? "l" : "r"; 

qui, sono determinare se il punto è in basso a destra, in basso a sinistra, in alto a destra o in alto quadrante sinistro della mappa basa su di essa la posizione rispetto al centro della mappa. Tieni presente che questo è il motivo per cui utilizziamo i pixel al contrario dei valori di LatLng, perché i valori di LatLng generano sempre lo stesso risultato, ma la realtà è che il marcatore può trovarsi in qualsiasi quadrante dell'area di disegno della mappa a seconda del panning.

Una volta che sai quale quadrante il marcatore è in, si può dare valori di offset al infowindow per posizionarlo in modo che sia visibile sulla mappa - in questo modo:

if (quadrant == "tr") { 
    offset = new google.maps.Size(-70, 185); 
} else if (quadrant == "tl") { 
    offset = new google.maps.Size(70, 185); 
} else if (quadrant == "br") { 
    offset = new google.maps.Size(-70, 20); 
} else if (quadrant == "bl") { 
    offset = new google.maps.Size(70, 20); 
} 
//these values are subject to change based on map canvas size, infowindow size 

Una volta che il valore di offset viene determinato è possibile basta regolare lo pixelOffset della finestra di apertura su qualsiasi listener che abbia invocato il metodo infoWindow.open(). Questo viene fatto utilizzando il metodo setOptions() per infowindows:

infowindow.setOptions({pixelOffset : self.getInfowindowOffset(self.map, marker)}); 

Ecco un JSFiddle example lavoro della soluzione sopra descritta.

Nota: Si noterà la "freccia" fastidioso sulla infowindow visualizzazione desbite la posizione del vostro infowindow, questo fa parte del l'impostazione di Google Map per infowindows impostazione predefinita e non sono riuscito a trovare un modo corretto di sbarazzarsi di esso. C'era un suggerimento here, ma non riuscivo a farlo funzionare. In alternativa puoi usare infobox library o infobubble library - che ti offre più opzioni di stile.

+0

Grazie, Suvi Vignarajah. Sono a conoscenza di 'disableAutoPan' ma il problema è che non sono riuscito a calcolare gli immobili sulla mappa e dare una posizione a infowindow usando l'opzione' position'. –

+0

@BurakErdem Ho fornito un approccio che è possibile utilizzare per calcolare lo spazio su schermo per posizionare di conseguenza la finestra di flusso nella mia risposta modificata. Spero che questo ti dia qualcosa su cui lavorare. –

+1

La tua implementazione funziona alla grande. Ho appena aggiornato il tuo codice (http://jsfiddle.net/SJCNp/2/) per rimuovere la freccia in basso. So che non è la soluzione migliore ma funziona. Qualcuno potrebbe voler aggiungere un extra CSS per simulare la funzionalità di navigazione di Google Maps. Grazie. –

1

La risposta di Suvi Vignarajah è ottima, ciò che non mi è piaciuto è stata la sua imprevedibile posizione della finestra vicino ai bordi.

ho ottimizzato in modo che le colle bolla al muro come dovrebbe essere previsto: http://jsfiddle.net/z5NaG/5/

L'unica condizione è che è necessario conoscere il width & height del infowindow, è possibile posizionarlo abbastanza bene. Lo risolverebbe attraverso i pixel delle mappe. Se non lo conosci, potresti inizializzare lo schermo di InfoWindow, ottenere le sue dimensioni e procedere ad aprirlo di nuovo nel punto giusto. Brutto ma funzionerebbe.

Prima inizializzare sulla sovrapposizione al momento della mappa di inizializzazione eseguendo questa funzione:

ourOverlay:null, 
    createOverlay:function(){ 
     this.ourOverlay = new google.maps.OverlayView(); 
     this.ourOverlay.draw = function() {}; 
     this.ourOverlay.setMap(this.map); 
    }, 

Poi alla open evento regolare l'offset in questo modo:

getInfowindowOffset: function (map, marker) { 
    // Settings 
    var iwWidth = 240; // InfoWindow width 
    var iwHeight = 190; // InfoWindow Height 
    var xOffset = 0; 
    var yOffset = 0; 

    // Our point of interest 
    var location = this.ourOverlay.getProjection().fromLatLngToContainerPixel(marker.getPosition()); 

    // Get Edges of map in pixels: Sout West corner and North East corner 
    var swp = this.ourOverlay.getProjection().fromLatLngToContainerPixel(map.getBounds().getSouthWest()); 
    var nep = this.ourOverlay.getProjection().fromLatLngToContainerPixel(map.getBounds().getNorthEast()); 

    // Horizontal Adjustment 
    if(location.x<iwWidth/2){ 
     xOffset= iwWidth/2-location.x; 
    }else if(location.x>nep.x-iwWidth/2){ 
     xOffset = (nep.x-iwWidth/2)-location.x ; 
    } 

    // Vertical Adjustment 
    if(location.y<iwHeight){ 
     yOffset = location.y + iwHeight-(location.y-nep.y); 
    } 

    // Return it 
    return new google.maps.Size(xOffset, yOffset); 

}, 

e il risultato è molto bello, ma questo triangolo sembra fuori luogo ora.

È possibile utilizzare InfoBox per rimuovere la freccia punta in basso:

  GmapsManager.infowindow = new InfoBox({ 
      content:'', 
      alignBottom: true, 
      closeBoxURL: "", 
     }); 

e lo stile la bolla con il seguente codice:

.infobox-popup{ 
    background: #fff; 
    -webkit-border-radius: 3px; 
    border-radius: 3px; 
    padding: 5px; 
    margin-left: -100px; 
    margin-bottom: 30px; 
    width: 200px; 
    -webkit-box-shadow: 0 0 1px 0 #595959; 
    box-shadow: 0 0 1px 0 #595959; 
} 
+1

amico che hai salvato la mia giornata, se riesci a sistemare i link non funzionanti sarà fantastico (ho già risolto uno infobox) –