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() {
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:
* 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,11 +1263,56 @@ OpenLayers.Map = OpenLayers.Class({
// only call setCenter if there has been a change
if (!newCenterPx.equals(centerPx)) {
var newCenterLonLat = this.getLonLatFromViewPortPx(newCenterPx);
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
*
@@ -1303,6 +1353,10 @@ OpenLayers.Map = OpenLayers.Class({
// 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();
}

View File

@@ -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();
});
}
</script>

View File

@@ -61,6 +61,7 @@
wnd.mapper.events.register("dblclick", mapper, setFlag);
simulateClick(wnd, wnd.control.buttons[0]);
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");
@@ -69,6 +70,7 @@
resetFlags();
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);

View File

@@ -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");
}

View File

@@ -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");
}

View File

@@ -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();

View File

@@ -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");
}