[Pkg-javascript-commits] [leaflet] 251/301: reimplement max bounds with proper zooming

Jonas Smedegaard js at moszumanska.debian.org
Mon Jan 27 22:22:55 UTC 2014


This is an automated email from the git hooks/post-receive script.

js pushed a commit to branch master
in repository leaflet.

commit 80607c6044659f4f081fceea89cdde9f547d25b1
Author: Vladimir Agafonkin <agafonkin at gmail.com>
Date:   Thu Nov 14 17:45:47 2013 +0200

    reimplement max bounds with proper zooming
---
 spec/suites/map/MapSpec.js       | 19 ++++----
 src/map/Map.js                   | 97 +++++++++++++++++++---------------------
 src/map/anim/Map.PanAnimation.js |  2 +-
 src/map/handler/Map.Drag.js      |  2 +
 4 files changed, 59 insertions(+), 61 deletions(-)

diff --git a/spec/suites/map/MapSpec.js b/spec/suites/map/MapSpec.js
index 591abb8..122bba9 100644
--- a/spec/suites/map/MapSpec.js
+++ b/spec/suites/map/MapSpec.js
@@ -139,8 +139,8 @@ describe("Map", function () {
 		});
 	});
 
-	describe('#setMaxBounds', function() {
-		it("aligns pixel-wise map view center with maxBounds center if it cannot move view bounds inside maxBounds (#1908)", function() {
+	describe('#setMaxBounds', function () {
+		it("aligns pixel-wise map view center with maxBounds center if it cannot move view bounds inside maxBounds (#1908)", function () {
 			var container = map.getContainer();
 			// large view, cannot fit within maxBounds
 			container.style.width = container.style.height = "1000px";
@@ -151,12 +151,11 @@ describe("Map", function () {
 			// set view outside
 			map.setView(L.latLng([53.0, 0.15]), 12, {animate: false});
 			// get center of bounds in pixels
-			var boundsCenter = map.project(bounds.getCenter());
-			boundsCenter = {x: Math.round(boundsCenter.x), y: Math.round(boundsCenter.y)};
-			expect(map.project(map.getCenter())).to.eql(boundsCenter);
+			var boundsCenter = map.project(bounds.getCenter()).round();
+			expect(map.project(map.getCenter()).round()).to.eql(boundsCenter);
 			document.body.removeChild(container);
 		});
-		it("moves map view within maxBounds by changing one coordinate", function() {
+		it("moves map view within maxBounds by changing one coordinate", function () {
 			var container = map.getContainer();
 			// small view, can fit within maxBounds
 			container.style.width = container.style.height = "200px";
@@ -169,10 +168,10 @@ describe("Map", function () {
 			var initCenter = [53.0, 0.1];
 			map.setView(L.latLng(initCenter), 16, {animate: false});
 			// one pixel coordinate hasn't changed, the other has
-			var pixelCenter = map.project(map.getCenter());
-			var pixelInit = map.project(initCenter);
-			expect(pixelCenter.x).to.eql(Math.round(pixelInit.x));
-			expect(pixelCenter.y).not.to.eql(Math.round(pixelInit.y));
+			var pixelCenter = map.project(map.getCenter()).round();
+			var pixelInit = map.project(initCenter).round();
+			expect(pixelCenter.x).to.eql(pixelInit.x);
+			expect(pixelCenter.y).not.to.eql(pixelInit.y);
 			// the view is inside the bounds
 			expect(bounds.contains(map.getBounds())).to.be(true);
 			document.body.removeChild(container);
diff --git a/src/map/Map.js b/src/map/Map.js
index d9df8a0..ba9c6d4 100644
--- a/src/map/Map.js
+++ b/src/map/Map.js
@@ -117,7 +117,7 @@ L.Map = L.Class.extend({
 	},
 
 	panBy: function (offset) { // (Point)
-		// replaced with animated panBy in Map.Animation.js
+		// replaced with animated panBy in Map.PanAnimation.js
 		this.fire('movestart');
 
 		this._rawPanBy(L.point(offset));
@@ -126,63 +126,29 @@ L.Map = L.Class.extend({
 		return this.fire('moveend');
 	},
 
-	setMaxBounds: function (bounds, options) {
+	setMaxBounds: function (bounds) {
 		bounds = L.latLngBounds(bounds);
 
 		this.options.maxBounds = bounds;
 
 		if (!bounds) {
-			this.off('moveend', L.bind(this._panInsideMaxBounds, this, options), this);
-			return this;
+			return this.off('moveend', this._panInsideMaxBounds, this);
 		}
+
 		if (this._loaded) {
-			this.panInsideBounds(bounds, options);
+			this._panInsideMaxBounds();
 		}
 
-		this.on('moveend', L.bind(this._panInsideMaxBounds, this, options), this);
-	
-		return this;
+		return this.on('moveend', this._panInsideMaxBounds, this);
 	},
 
 	panInsideBounds: function (bounds, options) {
-		bounds = L.latLngBounds(bounds);
+		var center = this.getCenter(),
+			newCenter = this._limitCenter(center, this._zoom, bounds);
 
-		var viewBounds = this.getPixelBounds(),
-		    viewSw = viewBounds.getBottomLeft(),
-		    viewNe = viewBounds.getTopRight(),
-		    sw = this.project(bounds.getSouthWest()),
-		    ne = this.project(bounds.getNorthEast()),
-		    dx = 0, dy = 0;
-
-		function rebound(l, r) {
-			var s = l + r;
-			var h = s / 2;
-			var d = 0;
-			if (s >= 0) {
-				if (l < 0) {
-					d = l;
-				} else if (r < 0) {
-					d = -r;
-				}
-			} else {
-				if (l < h) {
-					d = l - h;
-				} else if (r < h) {
-					d = -r + h;
-				}
-			}
-			return Math.round(d);
-		}
-		// set signs so positive l, r means "in bound"
-		// and positive s + r means the view can fit inside the bounds
-		dx = rebound(ne.x - viewNe.x, -sw.x + viewSw.x);
-		dy = rebound(sw.y - viewSw.y, -ne.y + viewNe.y);
-		
-		if (dx || dy) {
-			return this.panBy([dx, dy], options);
-		}
+		if (center.equals(newCenter)) { return this; }
 
-		return this;
+		return this.panTo(newCenter, options);
 	},
 
 	addLayer: function (layer) {
@@ -267,10 +233,6 @@ L.Map = L.Class.extend({
 		this._sizeChanged = true;
 		this._initialCenter = null;
 
-		if (this.options.maxBounds) {
-			this.setMaxBounds(this.options.maxBounds);
-		}
-
 		if (!this._loaded) { return this; }
 
 		var newSize = this.getSize(),
@@ -658,8 +620,8 @@ L.Map = L.Class.extend({
 		}
 	},
 
-	_panInsideMaxBounds: function (options) {
-		this.panInsideBounds(this.options.maxBounds, options);
+	_panInsideMaxBounds: function () {
+		this.panInsideBounds(this.options.maxBounds);
 	},
 
 	_checkIfLoaded: function () {
@@ -795,6 +757,41 @@ L.Map = L.Class.extend({
 		return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint());
 	},
 
+	_limitCenter: function (center, zoom, bounds) {
+
+		if (!bounds) { return center; }
+
+		var centerPoint = this.project(center, zoom),
+		    viewHalf = this.getSize().divideBy(2),
+		    viewBounds = new L.Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)),
+		    offset = this._getBoundsOffset(viewBounds, bounds, zoom);
+
+		return this.unproject(centerPoint.add(offset), zoom);
+	},
+
+	_limitOffset: function (offset, bounds) {
+		if (!bounds) { return offset; }
+
+		var viewBounds = this.getPixelBounds(),
+			newBounds = new L.Bounds(viewBounds.min.add(offset), viewBounds.max.add(offset));
+
+		return offset.add(this._getBoundsOffset(newBounds, bounds));
+	},
+
+	_getBoundsOffset: function (pxBounds, maxBounds, zoom) {
+		var nwOffset = this.project(maxBounds.getNorthWest(), zoom).subtract(pxBounds.min),
+		    seOffset = this.project(maxBounds.getSouthEast(), zoom).subtract(pxBounds.max),
+
+		    dx = this._rebound(nwOffset.x, -seOffset.x),
+		    dy = this._rebound(nwOffset.y, -seOffset.y);
+
+		return new L.Point(dx, dy);
+	},
+
+	_rebound: function (left, right) {
+		return Math.round(left + right > 0 ? (left - right) / 2 : Math.max(0, left) - Math.max(0, right));
+	},
+
 	_limitZoom: function (zoom) {
 		var min = this.getMinZoom(),
 		    max = this.getMaxZoom();
diff --git a/src/map/anim/Map.PanAnimation.js b/src/map/anim/Map.PanAnimation.js
index 59b7e45..777ea7b 100644
--- a/src/map/anim/Map.PanAnimation.js
+++ b/src/map/anim/Map.PanAnimation.js
@@ -7,7 +7,7 @@ L.Map.include({
 	setView: function (center, zoom, options) {
 
 		zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom);
-		center = L.latLng(center);
+		center = this._limitCenter(L.latLng(center), zoom, this.options.maxBounds);
 		options = options || {};
 
 		if (this._panAnim) {
diff --git a/src/map/handler/Map.Drag.js b/src/map/handler/Map.Drag.js
index fc2b79d..af4eff6 100644
--- a/src/map/handler/Map.Drag.js
+++ b/src/map/handler/Map.Drag.js
@@ -135,6 +135,8 @@ L.Map.Drag = L.Handler.extend({
 				map.fire('moveend');
 
 			} else {
+				offset = map._limitOffset(offset, map.options.maxBounds);
+
 				L.Util.requestAnimFrame(function () {
 					map.panBy(offset, {
 						duration: decelerationDuration,

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/leaflet.git



More information about the Pkg-javascript-commits mailing list