add a touch device-specific navigation control, p=bbinet, r=me (closes #3068)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@11208 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
44
examples/mobile-touchnavigation-control.html
Normal file
44
examples/mobile-touchnavigation-control.html
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<title>OpenLayers TouchNavigation Control</title>
|
||||||
|
<link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
|
||||||
|
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||||
|
<script src="../lib/OpenLayers.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var map, layer;
|
||||||
|
function init() {
|
||||||
|
map = new OpenLayers.Map( 'map', { controls: [
|
||||||
|
new OpenLayers.Control.TouchNavigation({
|
||||||
|
dragPanOptions: {
|
||||||
|
interval: 0 // non-zero kills performance on some mobile phones
|
||||||
|
}
|
||||||
|
})
|
||||||
|
] });
|
||||||
|
layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
|
||||||
|
"http://vmap0.tiles.osgeo.org/wms/vmap0",
|
||||||
|
{layers: 'basic'} );
|
||||||
|
map.addLayer(layer);
|
||||||
|
map.setCenter(new OpenLayers.LonLat(5, 40), 2);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="init()">
|
||||||
|
<h1 id="title">TouchNavigation Control</h1>
|
||||||
|
|
||||||
|
<div id="tags">
|
||||||
|
mobile, touch, drag, move, zoom, navigate
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="shortdesc">Demonstrate TouchNavigation Control features</div>
|
||||||
|
|
||||||
|
<div id="map" class="smallmap"></div>
|
||||||
|
<div id="docs">
|
||||||
|
This example demonstrates a couple features of the TouchNavigation
|
||||||
|
control. The TouchNavigation control controls most map dragging,
|
||||||
|
movement, zooming, etc, optimized for mobile devices.
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -180,6 +180,7 @@
|
|||||||
"OpenLayers/Control/ZoomToMaxExtent.js",
|
"OpenLayers/Control/ZoomToMaxExtent.js",
|
||||||
"OpenLayers/Control/DragPan.js",
|
"OpenLayers/Control/DragPan.js",
|
||||||
"OpenLayers/Control/Navigation.js",
|
"OpenLayers/Control/Navigation.js",
|
||||||
|
"OpenLayers/Control/TouchNavigation.js",
|
||||||
"OpenLayers/Control/MouseDefaults.js",
|
"OpenLayers/Control/MouseDefaults.js",
|
||||||
"OpenLayers/Control/MousePosition.js",
|
"OpenLayers/Control/MousePosition.js",
|
||||||
"OpenLayers/Control/OverviewMap.js",
|
"OpenLayers/Control/OverviewMap.js",
|
||||||
|
|||||||
148
lib/OpenLayers/Control/TouchNavigation.js
Normal file
148
lib/OpenLayers/Control/TouchNavigation.js
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
|
||||||
|
* full list of contributors). Published under the Clear BSD license.
|
||||||
|
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||||
|
* full text of the license. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires OpenLayers/Control/DragPan.js
|
||||||
|
* @requires OpenLayers/Handler/Click.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class: OpenLayers.Control.TouchNavigation
|
||||||
|
* The navigation control handles map browsing with touch events (dragging,
|
||||||
|
* double-tapping, and tap with two fingers). Create a new navigation
|
||||||
|
* control with the <OpenLayers.Control.TouchNavigation> control.
|
||||||
|
*
|
||||||
|
* Inherits:
|
||||||
|
* - <OpenLayers.Control>
|
||||||
|
*/
|
||||||
|
OpenLayers.Control.TouchNavigation = OpenLayers.Class(OpenLayers.Control, {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: dragPan
|
||||||
|
* {<OpenLayers.Control.DragPan>}
|
||||||
|
*/
|
||||||
|
dragPan: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIProprety: dragPanOptions
|
||||||
|
* {Object} Options passed to the DragPan control.
|
||||||
|
*/
|
||||||
|
dragPanOptions: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIProperty: documentDrag
|
||||||
|
* {Boolean} Allow panning of the map by dragging outside map viewport.
|
||||||
|
* Default is false.
|
||||||
|
*/
|
||||||
|
documentDrag: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIProperty: autoActivate
|
||||||
|
* {Boolean} Activate the control when it is added to a map. Default is
|
||||||
|
* true.
|
||||||
|
*/
|
||||||
|
autoActivate: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor: OpenLayers.Control.TouchNavigation
|
||||||
|
* Create a new navigation control
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* options - {Object} An optional object whose properties will be set on
|
||||||
|
* the control
|
||||||
|
*/
|
||||||
|
initialize: function(options) {
|
||||||
|
this.handlers = {};
|
||||||
|
OpenLayers.Control.prototype.initialize.apply(this, arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: destroy
|
||||||
|
* The destroy method is used to perform any clean up before the control
|
||||||
|
* is dereferenced. Typically this is where event listeners are removed
|
||||||
|
* to prevent memory leaks.
|
||||||
|
*/
|
||||||
|
destroy: function() {
|
||||||
|
this.deactivate();
|
||||||
|
if(this.dragPan) {
|
||||||
|
this.dragPan.destroy();
|
||||||
|
}
|
||||||
|
this.dragPan = null;
|
||||||
|
OpenLayers.Control.prototype.destroy.apply(this,arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: activate
|
||||||
|
*/
|
||||||
|
activate: function() {
|
||||||
|
if(OpenLayers.Control.prototype.activate.apply(this,arguments)) {
|
||||||
|
this.dragPan.activate();
|
||||||
|
this.handlers.click.activate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: deactivate
|
||||||
|
*/
|
||||||
|
deactivate: function() {
|
||||||
|
if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)) {
|
||||||
|
this.dragPan.deactivate();
|
||||||
|
this.handlers.click.deactivate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: draw
|
||||||
|
*/
|
||||||
|
draw: function() {
|
||||||
|
var clickCallbacks = {
|
||||||
|
'click': this.defaultClick,
|
||||||
|
'dblclick': this.defaultDblClick
|
||||||
|
};
|
||||||
|
var clickOptions = {
|
||||||
|
'double': true,
|
||||||
|
'stopDouble': true
|
||||||
|
};
|
||||||
|
this.handlers.click = new OpenLayers.Handler.Click(
|
||||||
|
this, clickCallbacks, clickOptions
|
||||||
|
);
|
||||||
|
this.dragPan = new OpenLayers.Control.DragPan(
|
||||||
|
OpenLayers.Util.extend({
|
||||||
|
map: this.map,
|
||||||
|
documentDrag: this.documentDrag
|
||||||
|
}, this.dragPanOptions)
|
||||||
|
);
|
||||||
|
this.dragPan.draw();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: defaultClick
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* evt - {Event}
|
||||||
|
*/
|
||||||
|
defaultClick: function (evt) {
|
||||||
|
if(evt.lasttouches && evt.lasttouches.length == 2) {
|
||||||
|
this.map.zoomOut();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: defaultDblClick
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* evt - {Event}
|
||||||
|
*/
|
||||||
|
defaultDblClick: function (evt) {
|
||||||
|
var newCenter = this.map.getLonLatFromViewPortPx(evt.xy);
|
||||||
|
this.map.setCenter(newCenter, this.map.zoom + 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
CLASS_NAME: "OpenLayers.Control.TouchNavigation"
|
||||||
|
});
|
||||||
109
tests/Control/TouchNavigation.html
Normal file
109
tests/Control/TouchNavigation.html
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="../OLLoader.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
function test_Control_TouchNavigation_constructor (t) {
|
||||||
|
t.plan( 2 );
|
||||||
|
var options = {bar: "foo"};
|
||||||
|
var temp = OpenLayers.Control.prototype.initialize;
|
||||||
|
OpenLayers.Control.prototype.initialize = function(opt) {
|
||||||
|
t.eq(opt, options,
|
||||||
|
"constructor calls parent with the correct options");
|
||||||
|
};
|
||||||
|
|
||||||
|
var control = new OpenLayers.Control.TouchNavigation(options);
|
||||||
|
t.ok(control instanceof OpenLayers.Control.TouchNavigation,
|
||||||
|
"new OpenLayers.Control returns object");
|
||||||
|
|
||||||
|
OpenLayers.Control.prototype.initialize = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_Control_TouchNavigation_destroy(t) {
|
||||||
|
t.plan(6);
|
||||||
|
|
||||||
|
var control = {
|
||||||
|
events: {
|
||||||
|
destroy: function() {
|
||||||
|
t.ok(true, "events destroyed");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deactivate: function() {
|
||||||
|
t.ok(true, "navigation control deactivated before being destroyed");
|
||||||
|
},
|
||||||
|
dragPan: {
|
||||||
|
destroy: function() {
|
||||||
|
t.ok(true, "dragPan destroyed");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handlers: {
|
||||||
|
click: {
|
||||||
|
destroy: function() {
|
||||||
|
t.ok(true, "clickHandler destroyed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//this will also trigger one test by calling OpenLayers.Control's destroy
|
||||||
|
// and three more for the destruction of dragPan, zoomBox, and wheelHandler
|
||||||
|
OpenLayers.Control.TouchNavigation.prototype.destroy.apply(control, []);
|
||||||
|
|
||||||
|
t.eq(control.dragPan, null, "'dragPan' set to null");
|
||||||
|
t.eq(control.handlers, null, "handlers set to null");
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_documentDrag(t) {
|
||||||
|
|
||||||
|
t.plan(2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These tests confirm that the documentDrag property is false by
|
||||||
|
* default and is passed on to the DragPan control. Tests of panning
|
||||||
|
* while dragging outside the viewport should go in the DragPan tests.
|
||||||
|
* Tests of the document events and appropriate callbacks from the
|
||||||
|
* handler should go in the Drag handler tests.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var nav = new OpenLayers.Control.TouchNavigation();
|
||||||
|
t.eq(nav.documentDrag, false, "documentDrag false by default");
|
||||||
|
|
||||||
|
var map = new OpenLayers.Map({
|
||||||
|
div: document.body,
|
||||||
|
controls: [new OpenLayers.Control.TouchNavigation({documentDrag: true})]
|
||||||
|
});
|
||||||
|
nav = map.controls[0];
|
||||||
|
|
||||||
|
t.eq(nav.dragPan.documentDrag, true, "documentDrag set on the DragPan control");
|
||||||
|
map.destroy();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_dragPanOptions(t) {
|
||||||
|
|
||||||
|
t.plan(2);
|
||||||
|
|
||||||
|
var nav = new OpenLayers.Control.TouchNavigation();
|
||||||
|
t.eq(nav.dragPanOptions, null, "dragPanOptions null by default");
|
||||||
|
|
||||||
|
var map = new OpenLayers.Map({
|
||||||
|
div: document.body,
|
||||||
|
controls: [
|
||||||
|
new OpenLayers.Control.TouchNavigation({
|
||||||
|
dragPanOptions: {foo: 'bar'}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
nav = map.controls[0];
|
||||||
|
|
||||||
|
t.eq(nav.dragPan.foo, 'bar',
|
||||||
|
"foo property is set on the DragPan control");
|
||||||
|
map.destroy();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
<li>Control/SelectFeature.html</li>
|
<li>Control/SelectFeature.html</li>
|
||||||
<li>Control/Snapping.html</li>
|
<li>Control/Snapping.html</li>
|
||||||
<li>Control/Split.html</li>
|
<li>Control/Split.html</li>
|
||||||
|
<li>Control/TouchNavigation.html</li>
|
||||||
<li>Control/TransformFeature.html</li>
|
<li>Control/TransformFeature.html</li>
|
||||||
<li>Control/WMSGetFeatureInfo.html</li>
|
<li>Control/WMSGetFeatureInfo.html</li>
|
||||||
<li>Control/WMTSGetFeatureInfo.html</li>
|
<li>Control/WMTSGetFeatureInfo.html</li>
|
||||||
|
|||||||
Reference in New Issue
Block a user