Add support for animated panning, with most of the work done by Pierre, thx pierre! panTo method now animates when moving. (Closes #110)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@6111 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
crschmidt
2008-02-08 16:28:11 +00:00
parent 3f7bbdfa9c
commit bb26a2601d
9 changed files with 174 additions and 29 deletions

View File

@@ -0,0 +1,85 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Animated Panning of the Map via map.panTo</title>
<style type="text/css">
#map {
width: 512px;
height: 256px;
border: 1px solid black;
}
</style>
<script src="../lib/OpenLayers.js"></script>
<script type="text/javascript">
var map, layer, running = false;
OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {
defaultHandlerOptions: {
'single': true,
'delay': 200
},
initialize: function(options) {
this.handlerOptions = OpenLayers.Util.extend(
{}, this.defaultHandlerOptions
);
OpenLayers.Control.prototype.initialize.apply(
this, arguments
);
this.handler = new OpenLayers.Handler.Click(
this, {
'click': this.onClick
}, this.handlerOptions
);
},
onClick: function(evt) {
map.panTo(map.getLonLatFromPixel(evt.xy));
}
});
function init(){
map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} );
map.addLayer(layer);
map.zoomToMaxExtent();
var click = new OpenLayers.Control.Click();
map.addControl(click);
click.activate();
map.addControl(new OpenLayers.Control.OverviewMap());
}
function setCenterInterval() {
if (!running) {
setCenter();
running = setInterval('setCenter()', 500);
} else {
clearInterval(running);
running = false;
}
}
function setCenter() {
var lon = Math.random() * 360 - 180;
var lat = Math.random() * 180 - 90;
var lonlat = new OpenLayers.LonLat(lon, lat);
map.panTo(lonlat);
}
</script>
</head>
<body onload="init()">
<h1 id="title">map.panTo Example</h1>
<div id="tags">map.panTo</div>
<div id="shortdesc">Show animated panning effects in the map</div>
<div id="map"></div>
<div id="docs">
This is an example of transition effects. If the new random center is in the current extent, the map will pan smoothly. <br />
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.
</div>
<button onclick="setCenterInterval()">Start/stop random recenter</button>
</body>
</html>

View File

@@ -511,7 +511,7 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
*/ */
updateMapToRect: function() { updateMapToRect: function() {
var lonLatBounds = this.getMapBoundsFromRectBounds(this.rectPxBounds); var lonLatBounds = this.getMapBoundsFromRectBounds(this.rectPxBounds);
this.map.setCenter(lonLatBounds.getCenterLonLat(), this.map.zoom); this.map.panTo(lonLatBounds.getCenterLonLat());
}, },
/** /**

View File

@@ -1246,9 +1246,14 @@ OpenLayers.Map = OpenLayers.Class({
* Parameters: * Parameters:
* dx - {Integer} * dx - {Integer}
* dy - {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 // getCenter
var centerPx = this.getViewPortPxFromLonLat(this.getCenter()); var centerPx = this.getViewPortPxFromLonLat(this.getCenter());
@@ -1258,11 +1263,56 @@ OpenLayers.Map = OpenLayers.Class({
// only call setCenter if there has been a change // only call setCenter if there has been a change
if (!newCenterPx.equals(centerPx)) { if (!newCenterPx.equals(centerPx)) {
var newCenterLonLat = this.getLonLatFromViewPortPx(newCenterPx); 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 - {<OpenLayers.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 * APIMethod: setCenter
* *
@@ -1303,6 +1353,10 @@ OpenLayers.Map = OpenLayers.Class({
// noEvent is false by default // noEvent is false by default
var noEvent = options.noEvent; var noEvent = options.noEvent;
if (this.panTween && options.caller == "setCenter") {
this.panTween.stop();
}
if (!this.center && !this.isValidLonLat(lonlat)) { if (!this.center && !this.isValidLonLat(lonlat)) {
lonlat = this.maxExtent.getCenterLonLat(); lonlat = this.maxExtent.getCenterLonLat();
} }

View File

@@ -38,7 +38,7 @@
var centerLL = new OpenLayers.LonLat(-71,42); var centerLL = new OpenLayers.LonLat(-71,42);
map.setCenter(centerLL, 11); map.setCenter(centerLL, 11);
t.delay_call(1, function() {
var overviewCenter = control.ovmap.getCenter(); var overviewCenter = control.ovmap.getCenter();
var overviewZoom = control.ovmap.getZoom(); var overviewZoom = control.ovmap.getZoom();
t.eq(overviewCenter.lon, -71, "Overviewmap center lon correct"); t.eq(overviewCenter.lon, -71, "Overviewmap center lon correct");
@@ -46,7 +46,7 @@
t.eq(overviewZoom, 8, "Overviewmap zoomcorrect"); t.eq(overviewZoom, 8, "Overviewmap zoomcorrect");
control.mapDivClick({'xy':new OpenLayers.Pixel(5,5)}); control.mapDivClick({'xy':new OpenLayers.Pixel(5,5)});
}, 2, function() {
var cent = map.getCenter(); 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.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"); 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.rectDrag(new OpenLayers.Pixel(15, 15));
control.updateMapToRect(); control.updateMapToRect();
}, 2, function() {
var cent = map.getCenter(); 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.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"); 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.lon, 0, "Overviewmap center lon correct -- second zoom");
t.eq(overviewCenter.lat, 0, "Overviewmap center lat correct -- second zoom"); t.eq(overviewCenter.lat, 0, "Overviewmap center lat correct -- second zoom");
t.eq(overviewZoom, 0, "Overviewmap zoomcorrect -- second zoom"); t.eq(overviewZoom, 0, "Overviewmap zoomcorrect -- second zoom");
map.destroy(); map.destroy();
});
} }
</script> </script>

View File

@@ -61,14 +61,16 @@
wnd.mapper.events.register("dblclick", mapper, setFlag); wnd.mapper.events.register("dblclick", mapper, setFlag);
simulateClick(wnd, wnd.control.buttons[0]); simulateClick(wnd, wnd.control.buttons[0]);
t.ok( wnd.mapper.getCenter().lat > wnd.centerLL.lat, "Pan up works correctly" ); t.delay_call(2, function() {
t.ok(!flag.mousedown, "mousedown does not get to the map"); t.ok( wnd.mapper.getCenter().lat > wnd.centerLL.lat, "Pan up works correctly" );
t.ok(flag.mouseup, "mouseup does get to the map"); t.ok(!flag.mousedown, "mousedown does not get to the map");
t.ok(!flag.click, "click does not get to the map"); t.ok(flag.mouseup, "mouseup does get to the map");
t.ok(!flag.dblclick, "dblclick does not get to the map"); t.ok(!flag.click, "click does not get to the map");
resetFlags(); 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( 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.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map"); t.ok(flag.mouseup, "mouseup does get to the map");
@@ -77,6 +79,7 @@
resetFlags(); resetFlags();
simulateClick(wnd, wnd.control.buttons[2]); simulateClick(wnd, wnd.control.buttons[2]);
}, 2, function() {
t.ok( wnd.mapper.getCenter().lon == wnd.centerLL.lon, "Pan right works correctly" ); 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.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map"); t.ok(flag.mouseup, "mouseup does get to the map");
@@ -85,6 +88,7 @@
resetFlags(); resetFlags();
simulateClick(wnd, wnd.control.buttons[3]); simulateClick(wnd, wnd.control.buttons[3]);
}, 2, function() {
t.ok( wnd.mapper.getCenter().lat == wnd.centerLL.lat, "Pan down works correctly" ); 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.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map"); t.ok(flag.mouseup, "mouseup does get to the map");
@@ -93,6 +97,7 @@
resetFlags(); resetFlags();
simulateClick(wnd, wnd.control.buttons[4]); simulateClick(wnd, wnd.control.buttons[4]);
}, 2, function() {
t.eq( wnd.mapper.getZoom(), 6, "zoomin works correctly" ); t.eq( wnd.mapper.getZoom(), 6, "zoomin works correctly" );
t.ok(!flag.mousedown, "mousedown does not get to the map"); t.ok(!flag.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map"); t.ok(flag.mouseup, "mouseup does get to the map");
@@ -101,6 +106,7 @@
resetFlags(); resetFlags();
simulateClick(wnd, wnd.control.buttons[6]); simulateClick(wnd, wnd.control.buttons[6]);
}, 2, function() {
t.eq( wnd.mapper.getZoom(), 5, "zoomout works correctly" ); t.eq( wnd.mapper.getZoom(), 5, "zoomout works correctly" );
t.ok(!flag.mousedown, "mousedown does not get to the map"); t.ok(!flag.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does get to the map"); t.ok(flag.mouseup, "mouseup does get to the map");
@@ -109,13 +115,14 @@
resetFlags(); resetFlags();
simulateClick(wnd, wnd.control.buttons[5]); simulateClick(wnd, wnd.control.buttons[5]);
}, 2, function() {
t.eq( wnd.mapper.getZoom(), 2, "zoomworld works correctly" ); t.eq( wnd.mapper.getZoom(), 2, "zoomworld works correctly" );
t.ok(!flag.mousedown, "mousedown does not get to the map"); t.ok(!flag.mousedown, "mousedown does not get to the map");
t.ok(flag.mouseup, "mouseup does 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.click, "click does not get to the map");
t.ok(!flag.dblclick, "dblclick does not get to the map"); t.ok(!flag.dblclick, "dblclick does not get to the map");
resetFlags(); resetFlags();
});
}); });
}); });
} }
@@ -146,8 +153,8 @@
var layer = new OpenLayers.Layer.WMS("Test Layer", var layer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?", "http://labs.metacarta.com/wms-c/Basic.py?",
{map: "/mapdata/vmap_wms.map", layers: "basic"}); {layers: "basic"});
mapper.addLayer(layer); mapper.addLayer(layer);
centerLL = new OpenLayers.LonLat(0,0); centerLL = new OpenLayers.LonLat(0,0);

View File

@@ -38,7 +38,7 @@
layer.setVisibility(true); layer.setVisibility(true);
if (!map.getCenter()) map.zoomToMaxExtent(); if (!map.getCenter()) map.zoomToMaxExtent();
map.addControl(control); 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'); 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); map.layers[1].setVisibility(false);
@@ -55,7 +55,7 @@
map.addLayer(layer); map.addLayer(layer);
if (!map.getCenter()) map.zoomToMaxExtent(); if (!map.getCenter()) map.zoomToMaxExtent();
map.addControl(control); 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'; 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"); 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); map.addLayer(layer);
if (!map.getCenter()) map.zoomToMaxExtent(); if (!map.getCenter()) map.zoomToMaxExtent();
map.addControl(control); 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'; 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"); 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&" ); control = new OpenLayers.Control.Permalink('permalink', "./edit.html?foo=bar&" );
map.addControl(control); 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 '&'"); 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?" ); 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'; OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B';
map.addControl(control); map.addControl(control);
map.pan(5, 0); map.pan(5, 0, {animate:false});
map.pan(-5, 0); 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 '?'"); 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); map.addLayer(layer);
if (!map.getCenter()) map.zoomToMaxExtent(); if (!map.getCenter()) map.zoomToMaxExtent();
map.addControl(control); 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'; 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"); t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with existing zoom in base");
} }

View File

@@ -542,7 +542,7 @@
map.zoomIn(); map.zoomIn();
var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200)); var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));
t.eq(bounds.toBBOX(), "-180,-90,0,90", "get tile bounds returns correct bounds"); 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)); 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"); t.eq(bounds.toBBOX(), "0,-90,180,90", "get tile bounds returns correct bounds after pan");
} }

View File

@@ -245,7 +245,7 @@
map.zoomIn(); map.zoomIn();
var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200)); var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));
t.eq(bounds.toBBOX(), "-180,0,0,180", "get tile bounds returns correct bounds"); 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)); 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"); t.eq(bounds.toBBOX(), "0,0,180,180", "get tile bounds returns correct bounds after pan");
map.destroy(); map.destroy();

View File

@@ -681,7 +681,7 @@
map.zoomToMaxExtent(); map.zoomToMaxExtent();
map.setBaseLayer(tmsLayer); map.setBaseLayer(tmsLayer);
map.zoomIn(); map.zoomIn();
map.pan(0, -200); map.pan(0, -200, {animate:false});
map.setBaseLayer(wmsLayer); map.setBaseLayer(wmsLayer);
t.eq(map.layerContainerDiv.style.top, "0px", "layerContainer is recentered after setBaseLayer"); t.eq(map.layerContainerDiv.style.top, "0px", "layerContainer is recentered after setBaseLayer");
} }