У меня была такая же проблема. Вот то, что я наконец получил, работая над решением некоторых проблем, которые у меня были с другими решениями.
* Правильно применяет границы независимо от того, используете ли вы мышь или клавиши со стрелками
* Не останавливается ближе к краю, если удерживать клавиши со стрелками, из-за ускорения панорамирования, которое заставляет его «перескочить» край за один шаг, поэтому вместо этого он останавливается (попробуйте удерживать клавишу со стрелкой в одном направление, пока вы не дойдете до края, затем отпустите и нажмите его снова, и с некоторыми решениями он будет прокручиваться немного больше)
* Не "приходит в норму", когда достигает края
* Правильно применяет границы при изменении масштаба
РЕДАКТИРОВАТЬ: Хорошо, это работает, когда вы изменяете масштаб с помощью колеса прокрутки, но не с помощью элемента управления масштабированием. Позвольте мне немного поиграть с этим, и я посмотрю, смогу ли я заставить это работать тоже ...
РЕДАКТИРОВАТЬ 2: Оказывается, проблема была в том, что я удалил элемент управления панорамированием. Пока присутствует элемент управления панорамированием, он отлично работает как с колесом прокрутки, так и с элементом управления масштабированием.
РЕДАКТИРОВАТЬ 3: Нет ... это не так. Я обновил код для обработки управления масштабированием.
// bounds of the desired area
var allowedBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(-64, -64),
new google.maps.LatLng(64, 64)
);
var zoomChanged = false;
google.maps.event.addListener(map, 'center_changed', function() {
var mapBounds = map.getBounds();
if(mapBounds.getNorthEast().lat() > allowedBounds.getNorthEast().lat()) {
var newCenter = new google.maps.LatLng(map.getCenter().lat() -
(mapBounds.getNorthEast().lat() -
allowedBounds.getNorthEast().lat()),
map.getCenter().lng(), true);
map.panTo(newCenter);
return;
}
if(mapBounds.getNorthEast().lng() > allowedBounds.getNorthEast().lng()) {
var newCenter = new google.maps.LatLng(map.getCenter().lat(),
map.getCenter().lng() -
(mapBounds.getNorthEast().lng() -
allowedBounds.getNorthEast().lng()), true);
map.panTo(newCenter);
return;
}
if(mapBounds.getSouthWest().lat() < allowedBounds.getSouthWest().lat()) {
var newCenter = new google.maps.LatLng(map.getCenter().lat() +
(allowedBounds.getSouthWest().lat() -
mapBounds.getSouthWest().lat()),
map.getCenter().lng(), true);
map.panTo(newCenter);
return;
}
if(mapBounds.getSouthWest().lng() < allowedBounds.getSouthWest().lng()) {
var newCenter = new google.maps.LatLng(map.getCenter().lat(),
map.getCenter().lng() +
(allowedBounds.getSouthWest().lng() -
mapBounds.getSouthWest().lng()), true);
map.panTo(newCenter);
return;
}
}, this);
google.maps.event.addListener(map, 'zoom_changed', function() {
zoomChanged = true;
}, this);
google.maps.event.addListener(map, 'bounds_changed', function() {
if(zoomChanged) {
var mapBounds = map.getBounds();
if(mapBounds.getNorthEast().lat() > allowedBounds.getNorthEast().lat()) {
var newCenter = new google.maps.LatLng(map.getCenter().lat() -
(mapBounds.getNorthEast().lat() -
allowedBounds.getNorthEast().lat()),
map.getCenter().lng(), true);
map.panTo(newCenter);
return;
}
if(mapBounds.getNorthEast().lng() > allowedBounds.getNorthEast().lng()) {
var newCenter = new google.maps.LatLng(map.getCenter().lat(),
map.getCenter().lng() -
(mapBounds.getNorthEast().lng() -
allowedBounds.getNorthEast().lng()), true);
map.panTo(newCenter);
return;
}
if(mapBounds.getSouthWest().lat() < allowedBounds.getSouthWest().lat()) {
var newCenter = new google.maps.LatLng(map.getCenter().lat() +
(allowedBounds.getSouthWest().lat() -
mapBounds.getSouthWest().lat()),
map.getCenter().lng(), true);
map.panTo(newCenter);
return;
}
if(mapBounds.getSouthWest().lng() < allowedBounds.getSouthWest().lng()) {
var newCenter = new google.maps.LatLng(map.getCenter().lat(),
map.getCenter().lng() +
(allowedBounds.getSouthWest().lng() -
mapBounds.getSouthWest().lng()), true);
map.panTo(newCenter);
return;
}
zoomChanged = false;
}
}, this);