Обнаружение инициированных пользователем операций панорамирования/масштабирования в Листовке
У меня есть карта Leaflet, которая используется для совместного использования местоположения. Когда пользователь делится своим местоположением, маркер, отображающий свое местоположение, добавляется к карте для просмотра всеми другими пользователями. Он автоматически сопоставляет карту, чтобы отображать все маркеры всякий раз, когда она добавляется, перемещается или удаляется. Я также добавил настраиваемый элемент управления, который может включать и отключать автоматическое поведение. Все это прекрасно работает, но я также хотел бы сделать карту достаточно умной, чтобы автоматически отключать поведение автоматической установки, если пользователь нажимает или масштабирует карту.
Это оказывается довольно сложным, потому что я не могу найти хороший способ отличить, запускается ли пользователем действие панорамирования/масштабирования пользователем или автоподгон. Сначала я слушал события panstart и zoomstart, но они также срабатывали автоматически. Я решил, что могу установить флаг, чтобы он не отключил автоподгонку, когда зум/панорама вызвана автоматической установкой. Я сначала проверяю этот флаг, прежде чем отключать автоподстановку в ответ на panstart и zoomstart, а затем очищать его при получении панорамы и масштабирования.
Кажется, что он работает нормально до тех пор, пока не произойдет автоматическая подгонка, которая не приведет к панорамированию или масштабированию. Предположим, что у нас есть большое автоматическое монтирование кластеров маркеров, и один из них посередине удален. Поскольку связанный блок не изменяется, не запускается панорама или масштабирование, поэтому флаг, указывающий, что он не отключает автоподгонку, никогда не очищается. В следующий раз, когда пользователь нажимает или масштабирует карту, он не отключает автоподборку, как должен, потому что он считает, что он все еще находится в середине операции автоматической установки.
Как сделать так, чтобы я мог надежно отключить автоматическую настройку, когда пользователь нажимает или масштабирует карту напрямую, но оставьте ее включенной, когда она подкрашена или увеличена другими способами?
Вот соответствующий код:
var markers = []; // Map markers are stored in this array.
var autoFit = true; // Whether auto-fit is turned on
var lockAutoFit = false; // Temporarily lock auto-fit if true
var map; // Leaflet map object
function initMap() {
// Leaflet map initialized here
map.on('movestart zoomstart', function() {
if (!lockAutoFit) {
autoFit = false;
}
});
map.on('moveend zoomend', function() {
lockAutoFit = false;
});
}
function toggleAutoFit() {
autoFit = !autoFit;
if (autoFit) {
lockAutoFit = true;
fitMap();
}
}
function addOrUpdateMarker(marker, coords) {
lockAutoFit = true;
// do the marker update here
fitMap();
}
function removeMarker(marker) {
lockAutoFit = true;
// remove the marker here
fitMap();
}
// Pans and zooms the map so that all markers fit in the map view.
// Invoked whenever a marker is added, moved or deleted, or when
// the user turns on auto-fit.
function fitMap() {
if (!autoFit || !markers.length) {
return;
}
map.fitBounds(new L.featureGroup(markers).getBounds());
}
Ответы
Ответ 1
Я установил флаг вокруг моих вызовов fitBounds
и setView
, например.:
isProgramaticZoom = true
map.fitBounds(new L.featureGroup(markers).getBounds());
isProgramaticZoom = false
Затем код для отключения автоматической установки:
map.on('zoomstart', function() {
if (!isProgramaticZoom) {
//turn off auto-fit
}
})
map.on('dragstart', function() {
//turn off auto-fit
})
К сожалению, все же не идеальный, но должен сделать трюк
Ответ 2
Вы можете использовать drag, dragstart, dragend - по крайней мере, для панорамирования карты. Для масштабирования карты нет такого эквивалента, я думаю.
Ответ 3
Справочная информация указывает, что она имеет события zoomstart
, zoomend
и zoomlevelschange
.
Ответ 4
Это старый вопрос, но, как я нашел его недавно, я думаю, что он все еще достаточно уместен, что решение стоит давать.
Я следил за этим решением: Пользовательские триггерные события с листами
который должен использовать:
map.on('dragstart', function (e) {
if (e.hard) {
// moved by bounds
} else {
// moved by drag/keyboard
}
});
Недокументированная часть e.hard - это решение здесь; комментарии говорят сами за себя.
Альтернативно, вы можете использовать moveend
вместо dragstart