检测用户在传单上发起的平移/缩放操作

Detect user-initiated pan/zoom operations on Leaflet

本文关键字:操作 缩放 用户 检测      更新时间:2023-09-26

我有一个用于位置共享的传单地图。当用户共享其位置时,地图上会添加显示其位置的标记,供所有其他用户查看。它会自动适配地图,以便在添加、移动或删除标记时显示所有标记。我还添加了一个自定义控件,可以切换自动适配行为的开关。这一切都很好,但我也想让地图足够智能,自动关闭自动适配行为,如果用户平移或缩放地图。

这是相当困难的,因为我找不到一个好方法来区分平移/缩放操作是由用户发起还是由自动适配。我最初是在听panstart和zoomstart事件,但这些事件也由auto-fit触发。我想我可以设置一个标志来告诉它,当缩放/平移是由自动适配引起时,不要关闭自动适配。在响应panstart和zoomstart关闭自动适配之前,我首先检查此标志,然后在收到panend和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());
}

我最终在我的fitBoundssetView呼叫周围设置了一个标志,例如:

isProgramaticZoom = true
map.fitBounds(new L.featureGroup(markers).getBounds());
isProgramaticZoom = false

关闭auto-fit的代码:

map.on('zoomstart', function() {
  if (!isProgramaticZoom) {
    //turn off auto-fit
  }
})
map.on('dragstart', function() {
  //turn off auto-fit
})

不幸的是,仍然不是理想的,但应该可以做到

EDIT: 这显然已被删除,不再工作

这是一个古老的问题,但正如我最近发现的,我认为它仍然足够相关,值得给出一个解决方案。

我遵循了这个解决方案:传单用户触发事件

使用:

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

未记录的e.c hard部分是这里的解决方案;注释不言自明。

或者,您可能希望使用moveend而不是dragstart

您可以使用拖拽,拖起,拖结束-至少对于地图平移。对于地图缩放,我想没有类似的

传单参考说明它有zoomstart, zoomendzoomlevelschange事件。