Adding a PinchZoom control for smooth zooming on multi-touch devices. p=bbinet,me r=crschmidt (closes #3105)
git-svn-id: http://svn.openlayers.org/trunk/openlayers@11544 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
192
lib/OpenLayers/Control/PinchZoom.js
Normal file
192
lib/OpenLayers/Control/PinchZoom.js
Normal file
@@ -0,0 +1,192 @@
|
||||
/* 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/Handler/Pinch.js
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class: OpenLayers.Control.PinchZoom
|
||||
*
|
||||
* Inherits:
|
||||
* - <OpenLayers.Control>
|
||||
*/
|
||||
OpenLayers.Control.PinchZoom = OpenLayers.Class(OpenLayers.Control, {
|
||||
|
||||
/**
|
||||
* Property: type
|
||||
* {OpenLayers.Control.TYPES}
|
||||
*/
|
||||
type: OpenLayers.Control.TYPE_TOOL,
|
||||
|
||||
/**
|
||||
* Property: containerOrigin
|
||||
* {Object} Cached object representing the layer container origin (in pixels).
|
||||
*/
|
||||
containerOrigin: null,
|
||||
|
||||
/**
|
||||
* Property: pinchOrigin
|
||||
* {Object} Cached object representing the pinch start (in pixels).
|
||||
*/
|
||||
pinchOrigin: null,
|
||||
|
||||
/**
|
||||
* Property: currentCenter
|
||||
* {Object} Cached object representing the latest pinch center (in pixels).
|
||||
*/
|
||||
currentCenter: null,
|
||||
|
||||
/**
|
||||
* APIProperty: autoActivate
|
||||
* {Boolean} Activate the control when it is added to a map. Default is
|
||||
* true.
|
||||
*/
|
||||
autoActivate: true,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Control.PinchZoom
|
||||
* Create a control for zooming with pinch gestures. This works on devices
|
||||
* with multi-touch support.
|
||||
*
|
||||
* Parameters:
|
||||
* options - {Object} An optional object whose properties will be set on
|
||||
* the control
|
||||
*/
|
||||
initialize: function(options) {
|
||||
OpenLayers.Control.prototype.initialize.apply(this, arguments);
|
||||
this.handler = new OpenLayers.Handler.Pinch(this, {
|
||||
start: this.pinchStart,
|
||||
move: this.pinchMove,
|
||||
done: this.pinchDone
|
||||
}, this.handlerOptions);
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: activate
|
||||
* Activate this control. Must be called after the control is added to a
|
||||
* map.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The control was successfully activated.
|
||||
*/
|
||||
activate: function() {
|
||||
var activated = OpenLayers.Control.prototype.activate.apply(this,arguments);
|
||||
if (activated) {
|
||||
this.map.events.on({
|
||||
moveend: this.updateContainerOrigin,
|
||||
scope: this
|
||||
});
|
||||
this.updateContainerOrigin();
|
||||
}
|
||||
return activated;
|
||||
},
|
||||
|
||||
/**
|
||||
* APIMethod: deactivate
|
||||
* Deactivate this control.
|
||||
*
|
||||
* Returns:
|
||||
* {Boolean} The control was successfully deactivated.
|
||||
*/
|
||||
deactivate: function() {
|
||||
var deactivated = OpenLayers.Control.prototype.deactivate.apply(this,arguments);
|
||||
if (this.map && this.map.events) {
|
||||
this.map.events.un({
|
||||
moveend: this.updateContainerOrigin,
|
||||
scope: this
|
||||
});
|
||||
}
|
||||
return deactivated;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: updateContainerOrigin
|
||||
* Must be called each time the layer container origin changes.
|
||||
*/
|
||||
updateContainerOrigin: function() {
|
||||
var container = this.map.layerContainerDiv;
|
||||
this.containerOrigin = {
|
||||
x: parseInt(container.style.left, 10),
|
||||
y: parseInt(container.style.top, 10)
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: pinchStart
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {Event}
|
||||
* pinchData - {Object} pinch data object related to the current touchmove
|
||||
* of the pinch gesture. This give us the current scale of the pinch.
|
||||
*/
|
||||
pinchStart: function(evt, pinchData) {
|
||||
this.pinchOrigin = evt.xy;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: pinchMove
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {Event}
|
||||
* pinchData - {Object} pinch data object related to the current touchmove
|
||||
* of the pinch gesture. This give us the current scale of the pinch.
|
||||
*/
|
||||
pinchMove: function(evt, pinchData) {
|
||||
var scale = pinchData.scale;
|
||||
var containerOrigin = this.containerOrigin;
|
||||
var pinchOrigin = this.pinchOrigin;
|
||||
var current = evt.xy;
|
||||
|
||||
var dx = Math.round((current.x - pinchOrigin.x) + (scale - 1) * (containerOrigin.x - pinchOrigin.x));
|
||||
var dy = Math.round((current.y - pinchOrigin.y) + (scale - 1) * (containerOrigin.y - pinchOrigin.y));
|
||||
|
||||
this.applyTransform(
|
||||
"translate(" + dx + "px, " + dy + "px) scale(" + scale + ")"
|
||||
);
|
||||
this.currentCenter = current;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: applyTransform
|
||||
* Applies the given transform to layers.
|
||||
*/
|
||||
applyTransform: function(transform) {
|
||||
var style = this.map.layerContainerDiv.style;
|
||||
style['-webkit-transform'] = transform;
|
||||
style['-moz-transform'] = transform;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: pinchDone
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {Event}
|
||||
* start - {Object} pinch data object related to the touchstart event that
|
||||
* started the pinch gesture.
|
||||
* last - {Object} pinch data object related to the last touchmove event
|
||||
* of the pinch gesture. This give us the final scale of the pinch.
|
||||
*/
|
||||
pinchDone: function(evt, start, last) {
|
||||
var zoom = this.map.getZoomForResolution(this.map.getResolution() / last.scale, true);
|
||||
var resolution = this.map.getResolutionForZoom(zoom);
|
||||
|
||||
var location = this.map.getLonLatFromPixel(this.pinchOrigin);
|
||||
var zoomPixel = this.currentCenter;
|
||||
var size = this.map.getSize();
|
||||
|
||||
location.lon += resolution * ((size.w / 2) - zoomPixel.x);
|
||||
location.lat -= resolution * ((size.h / 2) - zoomPixel.y);
|
||||
|
||||
this.map.setCenter(location, zoom);
|
||||
|
||||
var style = this.map.layerContainerDiv.style;
|
||||
style['-webkit-transform'] = "";
|
||||
style['-moz-transform'] = "";
|
||||
},
|
||||
|
||||
CLASS_NAME: "OpenLayers.Control.PinchZoom"
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user