Add an option to make the map's maxBounds non-bouncy. Fixes #1673.
This commit is contained in:
parent
bd1b88c1dd
commit
8a352fbbbf
52
debug/map/max-bounds-bouncy.html
Normal file
52
debug/map/max-bounds-bouncy.html
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Leaflet debug page</title>
|
||||||
|
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../../dist/leaflet.css" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="../css/mobile.css" />
|
||||||
|
|
||||||
|
<script type="text/javascript" src="../../build/deps.js"></script>
|
||||||
|
<script src="../leaflet-include.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Left: Bouncy maxBounds. Right: Not bouncy.</h1>
|
||||||
|
|
||||||
|
<div id="map1" style="float: left; width:45%; height: 80%;"></div>
|
||||||
|
<div id="map2" style="float: left; width:45%; height: 80%;"></div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||||
|
osmAttrib = '© <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
||||||
|
osm1 = L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib}),
|
||||||
|
osm2 = L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib}),
|
||||||
|
bounds = new L.LatLngBounds(new L.LatLng(49.5, -11.3), new L.LatLng(61.2, 2.5));
|
||||||
|
|
||||||
|
var map1 = new L.Map('map1', {
|
||||||
|
center: bounds.getCenter(),
|
||||||
|
zoom: 5,
|
||||||
|
layers: [osm1],
|
||||||
|
maxBounds: bounds,
|
||||||
|
maxBoundsViscosity: 0.75
|
||||||
|
});
|
||||||
|
|
||||||
|
var map2 = new L.Map('map2', {
|
||||||
|
center: bounds.getCenter(),
|
||||||
|
zoom: 5,
|
||||||
|
layers: [osm2],
|
||||||
|
maxBounds: bounds,
|
||||||
|
maxBoundsViscosity: 1.0
|
||||||
|
});
|
||||||
|
|
||||||
|
var latlngs = L.rectangle(bounds).getLatLngs();
|
||||||
|
L.polyline(latlngs.concat([latlngs[0]])).addTo(map1);
|
||||||
|
L.polyline(latlngs.concat([latlngs[0]])).addTo(map2);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -15,7 +15,8 @@ L.Map = L.Evented.extend({
|
|||||||
|
|
||||||
fadeAnimation: true,
|
fadeAnimation: true,
|
||||||
trackResize: true,
|
trackResize: true,
|
||||||
markerZoomAnimation: true
|
markerZoomAnimation: true,
|
||||||
|
maxBoundsViscosity: 0.0
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function (id, options) { // (HTMLElement or String, Object)
|
initialize: function (id, options) { // (HTMLElement or String, Object)
|
||||||
|
@ -28,8 +28,9 @@ L.Map.Drag = L.Handler.extend({
|
|||||||
dragend: this._onDragEnd
|
dragend: this._onDragEnd
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this._draggable.on('predrag', this._onPreDragLimit, this);
|
||||||
if (map.options.worldCopyJump) {
|
if (map.options.worldCopyJump) {
|
||||||
this._draggable.on('predrag', this._onPreDrag, this);
|
this._draggable.on('predrag', this._onPreDragWrap, this);
|
||||||
map.on('viewreset', this._onViewReset, this);
|
map.on('viewreset', this._onViewReset, this);
|
||||||
|
|
||||||
map.whenReady(this._onViewReset, this);
|
map.whenReady(this._onViewReset, this);
|
||||||
@ -55,6 +56,19 @@ L.Map.Drag = L.Handler.extend({
|
|||||||
_onDragStart: function () {
|
_onDragStart: function () {
|
||||||
var map = this._map;
|
var map = this._map;
|
||||||
|
|
||||||
|
if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) {
|
||||||
|
var bounds = L.latLngBounds(this._map.options.maxBounds);
|
||||||
|
|
||||||
|
this._offsetLimit = L.bounds(
|
||||||
|
this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1),
|
||||||
|
this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1)
|
||||||
|
.add(this._map.getSize()));
|
||||||
|
|
||||||
|
this._viscosity = Math.min(1.0, Math.max(0.0, this._map.options.maxBoundsViscosity));
|
||||||
|
} else {
|
||||||
|
this._offsetLimit = null;
|
||||||
|
}
|
||||||
|
|
||||||
map
|
map
|
||||||
.fire('movestart')
|
.fire('movestart')
|
||||||
.fire('dragstart');
|
.fire('dragstart');
|
||||||
@ -92,7 +106,25 @@ L.Map.Drag = L.Handler.extend({
|
|||||||
this._worldWidth = this._map.getPixelWorldBounds().getSize().x;
|
this._worldWidth = this._map.getPixelWorldBounds().getSize().x;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onPreDrag: function () {
|
_viscousLimit: function(value, threshold) {
|
||||||
|
return value - (value - threshold) * this._viscosity;
|
||||||
|
},
|
||||||
|
|
||||||
|
_onPreDragLimit: function () {
|
||||||
|
if (!this._viscosity || !this._offsetLimit) { return; }
|
||||||
|
|
||||||
|
var offset = this._draggable._newPos.subtract(this._draggable._startPos);
|
||||||
|
|
||||||
|
var limit = this._offsetLimit;
|
||||||
|
if (offset.x < limit.min.x) { offset.x = this._viscousLimit(offset.x, limit.min.x); }
|
||||||
|
if (offset.y < limit.min.y) { offset.y = this._viscousLimit(offset.y, limit.min.y); }
|
||||||
|
if (offset.x > limit.max.x) { offset.x = this._viscousLimit(offset.x, limit.max.x); }
|
||||||
|
if (offset.y > limit.max.y) { offset.y = this._viscousLimit(offset.y, limit.max.y); }
|
||||||
|
|
||||||
|
this._draggable._newPos = this._draggable._startPos.add(offset);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onPreDragWrap: function () {
|
||||||
// TODO refactor to be able to adjust map pane position after zoom
|
// TODO refactor to be able to adjust map pane position after zoom
|
||||||
var worldWidth = this._worldWidth,
|
var worldWidth = this._worldWidth,
|
||||||
halfWidth = Math.round(worldWidth / 2),
|
halfWidth = Math.round(worldWidth / 2),
|
||||||
|
Loading…
Reference in New Issue
Block a user