Подтвердить что ты не робот

Обнаружение инициированных пользователем операций панорамирования/масштабирования в Листовке

У меня есть карта 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());
}
4b9b3361

Ответ 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 - по крайней мере, для панорамирования карты. Для масштабирования карты нет такого эквивалента, я думаю.

Ответ 4

Это старый вопрос, но, как я нашел его недавно, я думаю, что он все еще достаточно уместен, что решение стоит давать.

Я следил за этим решением: Пользовательские триггерные события с листами

который должен использовать:

map.on('dragstart', function (e) {
    if (e.hard) {
        // moved by bounds
    } else {
       // moved by drag/keyboard
    }
});

Недокументированная часть e.hard - это решение здесь; комментарии говорят сами за себя.

Альтернативно, вы можете использовать moveend вместо dragstart