diff --git a/examples/animated_panning.html b/examples/animated_panning.html
new file mode 100644
index 0000000000..b897bd6f28
--- /dev/null
+++ b/examples/animated_panning.html
@@ -0,0 +1,85 @@
+
+
+ Animated Panning of the Map via map.panTo
+
+
+
+
+
+
map.panTo Example
+
map.panTo
+
Show animated panning effects in the map
+
+
+ This is an example of transition effects. If the new random center is in the current extent, the map will pan smoothly.
+ The random selection will continue until you press it again. Additionally, you can single click in the map to pan smoothly
+ to that area, or use the pan control to pan smoothly.
+
+
+
+
+
diff --git a/lib/OpenLayers/Control/OverviewMap.js b/lib/OpenLayers/Control/OverviewMap.js
index cbad34c044..a5cce99886 100644
--- a/lib/OpenLayers/Control/OverviewMap.js
+++ b/lib/OpenLayers/Control/OverviewMap.js
@@ -511,7 +511,7 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
*/
updateMapToRect: function() {
var lonLatBounds = this.getMapBoundsFromRectBounds(this.rectPxBounds);
- this.map.setCenter(lonLatBounds.getCenterLonLat(), this.map.zoom);
+ this.map.panTo(lonLatBounds.getCenterLonLat());
},
/**
diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js
index 4fc3386618..a4341f7221 100644
--- a/lib/OpenLayers/Map.js
+++ b/lib/OpenLayers/Map.js
@@ -1246,9 +1246,14 @@ OpenLayers.Map = OpenLayers.Class({
* Parameters:
* dx - {Integer}
* dy - {Integer}
+ * options - {Object} Only one at this time: "animate", which uses
+ * panTo instead of setCenter. Default is true.
*/
- pan: function(dx, dy) {
-
+ pan: function(dx, dy, options) {
+
+ if (!options) {
+ options = {}
+ }
// getCenter
var centerPx = this.getViewPortPxFromLonLat(this.getCenter());
@@ -1258,10 +1263,55 @@ OpenLayers.Map = OpenLayers.Class({
// only call setCenter if there has been a change
if (!newCenterPx.equals(centerPx)) {
var newCenterLonLat = this.getLonLatFromViewPortPx(newCenterPx);
- this.setCenter(newCenterLonLat);
+ if (options.animate) {
+ this.panTo(newCenterLonLat);
+ } else {
+ this.setCenter(newCenterLonLat);
+ }
}
},
+
+ /**
+ * APIMethod: panTo
+ * Allows user to pan to a new lonlat
+ * If the new lonlat is in the current extent the map will slide smoothly
+ *
+ * Parameters:
+ * lonlat - {}
+ */
+ panTo: function(lonlat) {
+ if (this.getExtent().containsLonLat(lonlat)) {
+ if (!this.panTween) {
+ this.panTween = new OpenLayers.Tween(OpenLayers.Easing.Expo.easeOut);
+ }
+ var center = this.getCenter();
+ var from = {
+ lon: center.lon,
+ lat: center.lat
+ };
+ var to = {
+ lon: lonlat.lon,
+ lat: lonlat.lat
+ };
+ this.panTween.start(from, to, 50, {
+ callbacks: {
+ start: OpenLayers.Function.bind(function(lonlat) {
+ this.events.triggerEvent("movestart");
+ }, this),
+ eachStep: OpenLayers.Function.bind(function(lonlat) {
+ var lonlat = new OpenLayers.LonLat(lonlat.lon, lonlat.lat);
+ this.moveTo(lonlat, this.zoom, true);
+ }, this),
+ done: OpenLayers.Function.bind(function(lonlat) {
+ this.events.triggerEvent("moveend");
+ }, this)
+ }
+ });
+ } else {
+ this.setCenter(lonlat);
+ }
+ },
/**
* APIMethod: setCenter
@@ -1302,6 +1352,10 @@ OpenLayers.Map = OpenLayers.Class({
var forceZoomChange = options.forceZoomChange;
// noEvent is false by default
var noEvent = options.noEvent;
+
+ if (this.panTween && options.caller == "setCenter") {
+ this.panTween.stop();
+ }
if (!this.center && !this.isValidLonLat(lonlat)) {
lonlat = this.maxExtent.getCenterLonLat();
diff --git a/tests/Control/test_OverviewMap.html b/tests/Control/test_OverviewMap.html
index 0caa0e03be..b263f8a290 100644
--- a/tests/Control/test_OverviewMap.html
+++ b/tests/Control/test_OverviewMap.html
@@ -38,7 +38,7 @@
var centerLL = new OpenLayers.LonLat(-71,42);
map.setCenter(centerLL, 11);
-
+ t.delay_call(1, function() {
var overviewCenter = control.ovmap.getCenter();
var overviewZoom = control.ovmap.getZoom();
t.eq(overviewCenter.lon, -71, "Overviewmap center lon correct");
@@ -46,7 +46,7 @@
t.eq(overviewZoom, 8, "Overviewmap zoomcorrect");
control.mapDivClick({'xy':new OpenLayers.Pixel(5,5)});
-
+ }, 2, function() {
var cent = map.getCenter();
t.eq(cent.lon, -71.3515625, "Clicking on the Overview Map has the correct effect on map lon");
t.eq(cent.lat, 42.17578125, "Clicking on the Overview Map has the correct effect on map lat");
@@ -57,7 +57,7 @@
};
control.rectDrag(new OpenLayers.Pixel(15, 15));
control.updateMapToRect();
-
+ }, 2, function() {
var cent = map.getCenter();
t.eq(cent.lon, -71.2734375, "Dragging on the Overview Map has the correct effect on map lon");
t.eq(cent.lat, 42.09765625, "Dragging on the Overview Map has the correct effect on map lat");
@@ -68,9 +68,8 @@
t.eq(overviewCenter.lon, 0, "Overviewmap center lon correct -- second zoom");
t.eq(overviewCenter.lat, 0, "Overviewmap center lat correct -- second zoom");
t.eq(overviewZoom, 0, "Overviewmap zoomcorrect -- second zoom");
-
map.destroy();
-
+ });
}
diff --git a/tests/Control/test_PanZoom.html b/tests/Control/test_PanZoom.html
index 82af048f4e..793ae7f7de 100644
--- a/tests/Control/test_PanZoom.html
+++ b/tests/Control/test_PanZoom.html
@@ -61,14 +61,16 @@
wnd.mapper.events.register("dblclick", mapper, setFlag);
simulateClick(wnd, wnd.control.buttons[0]);
- t.ok( wnd.mapper.getCenter().lat > wnd.centerLL.lat, "Pan up works correctly" );
- t.ok(!flag.mousedown, "mousedown does not get to the map");
- t.ok(flag.mouseup, "mouseup does get to the map");
- t.ok(!flag.click, "click does not get to the map");
- t.ok(!flag.dblclick, "dblclick does not get to the map");
- resetFlags();
+ t.delay_call(2, function() {
+ t.ok( wnd.mapper.getCenter().lat > wnd.centerLL.lat, "Pan up works correctly" );
+ t.ok(!flag.mousedown, "mousedown does not get to the map");
+ t.ok(flag.mouseup, "mouseup does get to the map");
+ t.ok(!flag.click, "click does not get to the map");
+ t.ok(!flag.dblclick, "dblclick does not get to the map");
+ resetFlags();
- simulateClick(wnd, wnd.control.buttons[1]);
+ simulateClick(wnd, wnd.control.buttons[1]);
+ }, 2, function() {
t.ok( wnd.mapper.getCenter().lon < wnd.centerLL.lon, "Pan left works correctly" );
t.ok(!flag.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map");
@@ -77,6 +79,7 @@
resetFlags();
simulateClick(wnd, wnd.control.buttons[2]);
+ }, 2, function() {
t.ok( wnd.mapper.getCenter().lon == wnd.centerLL.lon, "Pan right works correctly" );
t.ok(!flag.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map");
@@ -85,6 +88,7 @@
resetFlags();
simulateClick(wnd, wnd.control.buttons[3]);
+ }, 2, function() {
t.ok( wnd.mapper.getCenter().lat == wnd.centerLL.lat, "Pan down works correctly" );
t.ok(!flag.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map");
@@ -93,6 +97,7 @@
resetFlags();
simulateClick(wnd, wnd.control.buttons[4]);
+ }, 2, function() {
t.eq( wnd.mapper.getZoom(), 6, "zoomin works correctly" );
t.ok(!flag.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map");
@@ -101,6 +106,7 @@
resetFlags();
simulateClick(wnd, wnd.control.buttons[6]);
+ }, 2, function() {
t.eq( wnd.mapper.getZoom(), 5, "zoomout works correctly" );
t.ok(!flag.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map");
@@ -109,13 +115,14 @@
resetFlags();
simulateClick(wnd, wnd.control.buttons[5]);
+ }, 2, function() {
t.eq( wnd.mapper.getZoom(), 2, "zoomworld works correctly" );
t.ok(!flag.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map");
t.ok(!flag.click, "click does not get to the map");
t.ok(!flag.dblclick, "dblclick does not get to the map");
resetFlags();
-
+ });
});
});
}
@@ -146,8 +153,8 @@
var layer = new OpenLayers.Layer.WMS("Test Layer",
- "http://octo.metacarta.com/cgi-bin/mapserv?",
- {map: "/mapdata/vmap_wms.map", layers: "basic"});
+ "http://labs.metacarta.com/wms-c/Basic.py?",
+ {layers: "basic"});
mapper.addLayer(layer);
centerLL = new OpenLayers.LonLat(0,0);
diff --git a/tests/Control/test_Permalink.html b/tests/Control/test_Permalink.html
index d31b044c28..f2492e9146 100644
--- a/tests/Control/test_Permalink.html
+++ b/tests/Control/test_Permalink.html
@@ -38,7 +38,7 @@
layer.setVisibility(true);
if (!map.getCenter()) map.zoomToMaxExtent();
map.addControl(control);
- map.pan(5, 0);
+ map.pan(5, 0, {animate:false});
t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+"?zoom=2&lat=0&lon=1.75781&layers=BT"), 'pan sets permalink');
map.layers[1].setVisibility(false);
@@ -55,7 +55,7 @@
map.addLayer(layer);
if (!map.getCenter()) map.zoomToMaxExtent();
map.addControl(control);
- map.pan(5, 0);
+ map.pan(5, 0, {animate:false});
OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B';
t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base");
}
@@ -76,20 +76,20 @@
map.addLayer(layer);
if (!map.getCenter()) map.zoomToMaxExtent();
map.addControl(control);
- map.pan(5, 0);
+ map.pan(5, 0, {animate:false});
OpenLayers.Util.getElement('edit_permalink').href = './edit.html?foo=bar&zoom=2&lat=0&lon=1.75781&layers=B';
t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base and querystring");
control = new OpenLayers.Control.Permalink('permalink', "./edit.html?foo=bar&" );
map.addControl(control);
- map.pan(0, 0);
+ map.pan(0, 0, {animate:false});
t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base and querystring ending with '&'");
control = new OpenLayers.Control.Permalink('permalink', "./edit.html?" );
OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B';
map.addControl(control);
- map.pan(5, 0);
- map.pan(-5, 0);
+ map.pan(5, 0, {animate:false});
+ map.pan(-5, 0, {animate:false});
t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base and querystring ending with '?'");
}
@@ -104,7 +104,7 @@
map.addLayer(layer);
if (!map.getCenter()) map.zoomToMaxExtent();
map.addControl(control);
- map.pan(5, 0);
+ map.pan(5, 0, {animate:false});
OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B';
t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with existing zoom in base");
}
diff --git a/tests/Layer/test_Grid.html b/tests/Layer/test_Grid.html
index 11acc54a95..d7f75d998d 100644
--- a/tests/Layer/test_Grid.html
+++ b/tests/Layer/test_Grid.html
@@ -542,7 +542,7 @@
map.zoomIn();
var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));
t.eq(bounds.toBBOX(), "-180,-90,0,90", "get tile bounds returns correct bounds");
- map.pan(200,0);
+ map.pan(200,0, {animate:false});
var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));
t.eq(bounds.toBBOX(), "0,-90,180,90", "get tile bounds returns correct bounds after pan");
}
diff --git a/tests/Layer/test_KaMap.html b/tests/Layer/test_KaMap.html
index 8818fda996..823478d259 100644
--- a/tests/Layer/test_KaMap.html
+++ b/tests/Layer/test_KaMap.html
@@ -245,7 +245,7 @@
map.zoomIn();
var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));
t.eq(bounds.toBBOX(), "-180,0,0,180", "get tile bounds returns correct bounds");
- map.pan(200,0);
+ map.pan(200,0,{animate:false});
var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));
t.eq(bounds.toBBOX(), "0,0,180,180", "get tile bounds returns correct bounds after pan");
map.destroy();
diff --git a/tests/test_Map.html b/tests/test_Map.html
index 7354958d5e..135c4b19d7 100644
--- a/tests/test_Map.html
+++ b/tests/test_Map.html
@@ -681,7 +681,7 @@
map.zoomToMaxExtent();
map.setBaseLayer(tmsLayer);
map.zoomIn();
- map.pan(0, -200);
+ map.pan(0, -200, {animate:false});
map.setBaseLayer(wmsLayer);
t.eq(map.layerContainerDiv.style.top, "0px", "layerContainer is recentered after setBaseLayer");
}