Предотвращение Перемещения Карт Google После Отображения Infowindow
Я пытаюсь отобразить infowindow на картах Google. Он отображает perfect, когда вы наводите курсор на маркер, он загружает infowindow, но карта прыгает, чтобы поместиться в окне. Я не хочу, чтобы карта перемещалась, а скорее infowindow установил ее положение в соответствии с картой. Booking.com есть что-то вроде этого.
EDIT: добавил мой код
вот урезанная версия моего кода. Я получаю всю информацию от служба AJAX и этот сервис возвращает response
(который также содержит дополнительную информацию).
$.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;
});
}
}
});
Как вы можете видеть ниже, первое изображение показывает infowindow отображается в нижней части маркера, а второй показывает infowindow отображается в верхней части маркера. Карта не перемещается, но infowindow устанавливает свое положение в пределах границ карты.
2 ответов
в вашей декларации для установки параметров информационного окна infowindow.setOptions
, добавьте следующую опцию, чтобы отключить панорамирование карты при отображении infowindow,disableAutoPan : true
.
однако это также будет означать, что вам нужно будет рассчитать недвижимость, которую вы имеете в распоряжении, чтобы отобразить infowindow на вашей карте и дать ему позицию с помощью . В противном случае не будет гарантировано, что ваше infowindow будет полностью видимым на карта.
https://developers.google.com/maps/documentation/javascript/reference#InfoWindowOptions
EDIT:Как рассчитать экран недвижимости
Я понимаю, что я был довольно расплывчатым с моим предложением рассчитать экранную недвижимость, доступную для установки позиции вашего infowindow, когда часть вашего вопроса заключалась в том, чтобы фактически установить позицию infowindow. Так что я обновление моего ответа на как вы можете рассчитать экран недвижимости и настроить положение вашего infowindow.
ключ состоит в том, чтобы сначала преобразовать ваши точки из LatLng в пиксели и узнать пиксельную координату маркера на карте по отношению к пиксельной координате центра карты. Следующий фрагмент демонстрирует, как это можно сделать.
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;
}
как только вы получите свои пиксельные координаты, вам нужно будет узнать, какой квадрант карты canvas маркер в настоящее время проживающего в. Это достигается путем сравнения координат X и Y маркера с картой, например:
quadrant += (point.y > center.y) ? "b" : "t";
quadrant += (point.x < center.x) ? "l" : "r";
здесь я определяю, находится ли точка в нижнем правом, нижнем левом, верхнем правом или верхнем левом квадранте карты на основе ее относительного положения к центру карты. Имейте в виду, что именно поэтому мы используем пиксели в отличие от значений LatLng, потому что значения LatLng всегда будут давать один и тот же результат - но реальность такова, что маркер может быть в любом квадранте холста карты в зависимости от сдвига.
как только вы узнаете, в каком квадранте находится маркер, вы можете дать значения смещения infowindow, чтобы расположить его так, чтобы он был виден на карте-например:
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
как только значение смещения определено, вы можете просто настроить pixelOffset
вашего infowindow на любом слушателе, которого вы вызываете infoWindow.open()
метод. Это делается с помощью setOptions()
метод infowindows:
infowindow.setOptions({pixelOffset : self.getInfowindowOffset(self.map, marker)});
вот работает JSFiddle пример решения, описанного выше.
Примечание: вы заметите раздражающую "стрелку" на infowindow, отображающую desbite положение вашего infowindow, это часть настройки карты Google по умолчанию для infowindows, и я не мог найти правильный способ избавиться от него. Было предложение здесь, но я не мог заставить его работать. В качестве альтернативы вы можете использовать библиотека infobox или infobubble библиотека - что дает вам больше вариантов стиля.
ответ Суви Виньяраджи отличный, что мне не понравилось, так это то, насколько непредсказуемо положение окна вблизи краев.
Я настроил его так, что пузырь приклеивается к стене, как и следовало ожидать:http://jsfiddle.net/z5NaG/5/
единственное условие заключается в том, что вы должны знать width
& height
из infoWindow, вы можете расположить его довольно красиво. Вы бы поняли это через пиксели карт. Если вы не знаете, что вы могли инициализируйте InfoWindow за пределами экрана, получите его размер и продолжайте открывать его снова в нужном месте. Некрасиво, но сработает.
сначала инициализируйте наложение во время инициализации карты, запустив эту функцию:
ourOverlay:null,
createOverlay:function(){
this.ourOverlay = new google.maps.OverlayView();
this.ourOverlay.draw = function() {};
this.ourOverlay.setMap(this.map);
},
затем на open
событие отрегулируйте смещение так:
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);
},
и результат довольно приятный, но этот треугольник кажется неуместным сейчас.
можно использовать InfoBox чтобы удалить заостренную стрелку на дно:
GmapsManager.infowindow = new InfoBox({
content:'',
alignBottom: true,
closeBoxURL: "",
});
и стиль пузырь со следующим кодом:
.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;
}