【问题标题】:leaflet : Prevent marker to be dragged outside the map container传单:防止标记被拖到地图容器之外
【发布时间】:2015-06-26 12:44:19
【问题描述】:

请考虑以下代码http://jsfiddle.net/franckl/311bcbc8/

var southWest = L.latLng(-90, -180),
    northEast = L.latLng(90, 180);
var bounds = L.latLngBounds(southWest, northEast);

var map = L.map('map', {
    minZoom: 2,
    zoomControl: false,
    attributionControl: false,
    maxBounds: bounds
});

// Using cartoDB basemap
L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png', {
    minZoom: 2,
    subdomains: 'abcd',
    detectRetina: true,
    attribution: ''
}).addTo(map);

map.fitBounds(bounds);

var newMarker0 = L.marker(map.getCenter(), {
    icon: new L.Icon.Default(),
    zIndexOffset: 10000,
    draggable: true
});

newMarker0.addTo(map);

html

<div id="mycontainer">
    <div id="map"></div>
</div>

css

body {
    margin:0;
    padding:0;
}
#map {
    position:absolute;
    top:0;
    bottom:0;
    width:300px;
}

#mycontainer {
    top: 10px;
    width: 600px;
    height: 250px;
    position: relative;
}

如果您将标记拖到右侧,它会离开地图的可见区域。 如何防止用户将标记拖到地图外?

谢谢!

【问题讨论】:

    标签: leaflet mapbox cartodb


    【解决方案1】:

    回答我自己的问题,以防它帮助任何人。 我们检测地图容器大小并通过将其纬度/经度坐标转换为容器点来检查标记是否超出可见区域(map.containerPointToLatLng(markerContainerPosition))

    作为奖励,当用户移动地图时,此代码将标记保留在相对于地图容器的相同位置。它确保标记永远不会超出可见区域(即使在缩放时)

    var southWest = L.latLng(-90, -180),
        northEast = L.latLng(90, 180);
    var bounds = L.latLngBounds(southWest, northEast);
    
    var map = L.map('map', {
        minZoom: 2,
        zoomControl: false,
        attributionControl: false,
        maxBounds: bounds
    });
    
    // Using cartoDB basemap
    L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png', {
        minZoom: 2,
        subdomains: 'abcd',
        detectRetina: true,
        attribution: ''
    }).addTo(map);
    
    map.fitBounds(bounds);
    
    var newMarker0 = L.marker(map.getCenter(), {
        icon: new L.Icon.Default(),
        zIndexOffset: 10000,
        draggable: true
    });
    
    newMarker0.addTo(map);
    
    var mapSize = map.getSize();
    var markerContainerPosition = map.latLngToContainerPoint(newMarker0.getLatLng());
    
    function mapMove() {
        newMarker0.setLatLng(map.containerPointToLatLng(markerContainerPosition));
    }
    
    function markerDrag(e) {
        var mTempContainerPos = map.latLngToContainerPoint(newMarker0.getLatLng());
        var newPos;
    
        if (mTempContainerPos.x < 20) {
            if (mTempContainerPos.y < 45) {
                newPos = L.point(20, 45);
            } else if (mTempContainerPos.y > (mapSize.y - 20)) {
                newPos = L.point(20, mapSize.y - 20);
            } else {
                newPos = L.point(20, mTempContainerPos.y);
            }
        } else if (mTempContainerPos.x > mapSize.x - 20) {
            if (mTempContainerPos.y < 45) {
                newPos = L.point(mapSize.x - 20, 45);
            } else if (mTempContainerPos.y > (mapSize.y - 20)) {
                newPos = L.point(mapSize.x - 20, mapSize.y - 20);
            } else {
                newPos = L.point(mapSize.x - 20, mTempContainerPos.y);
            }
        } else {
            if (mTempContainerPos.y < 45) {
                newPos = L.point(mTempContainerPos.x, 45);
            } else if (mTempContainerPos.y > (mapSize.y - 20)) {
                newPos = L.point(mTempContainerPos.x, mapSize.y - 20);
            }
        }
    
        if (newPos) {
            markerContainerPosition = newPos;
            newMarker0.setLatLng(map.containerPointToLatLng(newPos));
        } else {
            markerContainerPosition = mTempContainerPos;
        }
    }
    
    map.on('move', mapMove);
    newMarker0.on('drag', markerDrag); 
    

    【讨论】:

      【解决方案2】:

      具有更通用代码的解决方案,并针对拖动标记而不是地图而量身定制,但源自@Franckl's:

      onMarkerDrag: function (event) {
      
          // keep dragged marker within map bounds
      
          var containerPoint = this.map.latLngToContainerPoint(event.target.getLatLng()),
              clampX = null,
              clampY = null,
              MARKER_MARGIN = 10;
      
          if (containerPoint.x - MARKER_MARGIN < 0) {
              clampX = MARKER_MARGIN;
          } else if (containerPoint.x + MARKER_MARGIN > this.mapContainerBounds.width) {
              clampX = this.mapContainerBounds.width - MARKER_MARGIN;
          }
      
          if (containerPoint.y - MARKER_MARGIN < 0) {
              clampY = MARKER_MARGIN;
          } else if (containerPoint.y + MARKER_MARGIN > this.mapContainerBounds.height) {
              clampY = this.mapContainerBounds.height - MARKER_MARGIN;
          }
      
          if (clampX !== null || clampY !== null) {
              if (clampX !== null) { containerPoint.x = clampX; }
              if (clampY !== null) { containerPoint.y = clampY; }
              marker.setLatLng(this.map.containerPointToLatLng(containerPoint));
          }
      
      },
      

      我在地图初始化时派生一次this.mapContainerBounds,而不是每次拖动处理程序触发时(我的地图不会改变大小),如下所示:

      this.mapContainerBounds = mapDOMNode.getBoundingClientRect();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-14
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 2010-10-24
        • 1970-01-01
        相关资源
        最近更新 更多