2

请考虑以下代码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;
}

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

谢谢 !

4

2 回答 2

3

回答我自己的问题,以防它帮助任何人。我们检测地图容器大小并通过将其纬度/经度坐标转换为容器点来检查标记是否超出可见区域 (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); 
于 2015-04-21T17:20:20.067 回答
0

A solution with slightly more generic code and tailored to dragging the marker rather than the map, but derivative of @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));
    }

},

I derive this.mapContainerBounds once on map init instead of every time the drag handler fires (my map does not change size), like this:

this.mapContainerBounds = mapDOMNode.getBoundingClientRect();
于 2015-08-27T19:58:00.563 回答