231 lines
6.2 KiB
JavaScript
231 lines
6.2 KiB
JavaScript
/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
|
|
* full list of contributors). Published under the 2-clause BSD license.
|
|
* See license.txt in the OpenLayers distribution or repository for the
|
|
* full text of the license. */
|
|
|
|
/**
|
|
* @requires OpenLayers/Handler.js
|
|
*/
|
|
|
|
/**
|
|
* Class: OpenLayers.Handler.Pinch
|
|
* The pinch handler is used to deal with sequences of browser events related
|
|
* to pinch gestures. The handler is used by controls that want to know
|
|
* when a pinch sequence begins, when a pinch is happening, and when it has
|
|
* finished.
|
|
*
|
|
* Controls that use the pinch handler typically construct it with callbacks
|
|
* for 'start', 'move', and 'done'. Callbacks for these keys are
|
|
* called when the pinch begins, with each change, and when the pinch is
|
|
* done.
|
|
*
|
|
* Create a new pinch handler with the <OpenLayers.Handler.Pinch> constructor.
|
|
*
|
|
* Inherits from:
|
|
* - <OpenLayers.Handler>
|
|
*/
|
|
OpenLayers.Handler.Pinch = OpenLayers.Class(OpenLayers.Handler, {
|
|
|
|
/**
|
|
* Property: started
|
|
* {Boolean} When a touchstart event is received, we want to record it,
|
|
* but not set 'pinching' until the touchmove get started after
|
|
* starting.
|
|
*/
|
|
started: false,
|
|
|
|
/**
|
|
* Property: stopDown
|
|
* {Boolean} Stop propagation of touchstart events from getting to
|
|
* listeners on the same element. Default is false.
|
|
*/
|
|
stopDown: false,
|
|
|
|
/**
|
|
* Property: pinching
|
|
* {Boolean}
|
|
*/
|
|
pinching: false,
|
|
|
|
/**
|
|
* Property: last
|
|
* {Object} Object that store informations related to pinch last touch.
|
|
*/
|
|
last: null,
|
|
|
|
/**
|
|
* Property: start
|
|
* {Object} Object that store informations related to pinch touchstart.
|
|
*/
|
|
start: null,
|
|
|
|
/**
|
|
* Constructor: OpenLayers.Handler.Pinch
|
|
* Returns OpenLayers.Handler.Pinch
|
|
*
|
|
* Parameters:
|
|
* control - {<OpenLayers.Control>} The control that is making use of
|
|
* this handler. If a handler is being used without a control, the
|
|
* handlers setMap method must be overridden to deal properly with
|
|
* the map.
|
|
* callbacks - {Object} An object containing functions to be called when
|
|
* the pinch operation start, change, or is finished. The callbacks
|
|
* should expect to receive an object argument, which contains
|
|
* information about scale, distance, and position of touch points.
|
|
* options - {Object}
|
|
*/
|
|
|
|
/**
|
|
* Method: touchstart
|
|
* Handle touchstart events
|
|
*
|
|
* Parameters:
|
|
* evt - {Event}
|
|
*
|
|
* Returns:
|
|
* {Boolean} Let the event propagate.
|
|
*/
|
|
touchstart: function(evt) {
|
|
var propagate = true;
|
|
this.pinching = false;
|
|
if (OpenLayers.Event.isMultiTouch(evt)) {
|
|
this.started = true;
|
|
this.last = this.start = {
|
|
distance: this.getDistance(evt.touches),
|
|
delta: 0,
|
|
scale: 1
|
|
};
|
|
this.callback("start", [evt, this.start]);
|
|
propagate = !this.stopDown;
|
|
} else {
|
|
this.started = false;
|
|
this.start = null;
|
|
this.last = null;
|
|
}
|
|
// prevent document dragging
|
|
OpenLayers.Event.preventDefault(evt);
|
|
return propagate;
|
|
},
|
|
|
|
/**
|
|
* Method: touchmove
|
|
* Handle touchmove events
|
|
*
|
|
* Parameters:
|
|
* evt - {Event}
|
|
*
|
|
* Returns:
|
|
* {Boolean} Let the event propagate.
|
|
*/
|
|
touchmove: function(evt) {
|
|
if (this.started && OpenLayers.Event.isMultiTouch(evt)) {
|
|
this.pinching = true;
|
|
var current = this.getPinchData(evt);
|
|
this.callback("move", [evt, current]);
|
|
this.last = current;
|
|
// prevent document dragging
|
|
OpenLayers.Event.stop(evt);
|
|
}
|
|
return true;
|
|
},
|
|
|
|
/**
|
|
* Method: touchend
|
|
* Handle touchend events
|
|
*
|
|
* Parameters:
|
|
* evt - {Event}
|
|
*
|
|
* Returns:
|
|
* {Boolean} Let the event propagate.
|
|
*/
|
|
touchend: function(evt) {
|
|
if (this.started) {
|
|
this.started = false;
|
|
this.pinching = false;
|
|
this.callback("done", [evt, this.start, this.last]);
|
|
this.start = null;
|
|
this.last = null;
|
|
}
|
|
return true;
|
|
},
|
|
|
|
/**
|
|
* Method: activate
|
|
* Activate the handler.
|
|
*
|
|
* Returns:
|
|
* {Boolean} The handler was successfully activated.
|
|
*/
|
|
activate: function() {
|
|
var activated = false;
|
|
if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
|
|
this.pinching = false;
|
|
activated = true;
|
|
}
|
|
return activated;
|
|
},
|
|
|
|
/**
|
|
* Method: deactivate
|
|
* Deactivate the handler.
|
|
*
|
|
* Returns:
|
|
* {Boolean} The handler was successfully deactivated.
|
|
*/
|
|
deactivate: function() {
|
|
var deactivated = false;
|
|
if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
|
|
this.started = false;
|
|
this.pinching = false;
|
|
this.start = null;
|
|
this.last = null;
|
|
deactivated = true;
|
|
}
|
|
return deactivated;
|
|
},
|
|
|
|
/**
|
|
* Method: getDistance
|
|
* Get the distance in pixels between two touches.
|
|
*
|
|
* Parameters:
|
|
* touches - {Array(Object)}
|
|
*
|
|
* Returns:
|
|
* {Number} The distance in pixels.
|
|
*/
|
|
getDistance: function(touches) {
|
|
var t0 = touches[0];
|
|
var t1 = touches[1];
|
|
return Math.sqrt(
|
|
Math.pow(t0.clientX - t1.clientX, 2) +
|
|
Math.pow(t0.clientY - t1.clientY, 2)
|
|
);
|
|
},
|
|
|
|
|
|
/**
|
|
* Method: getPinchData
|
|
* Get informations about the pinch event.
|
|
*
|
|
* Parameters:
|
|
* evt - {Event}
|
|
*
|
|
* Returns:
|
|
* {Object} Object that contains data about the current pinch.
|
|
*/
|
|
getPinchData: function(evt) {
|
|
var distance = this.getDistance(evt.touches);
|
|
var scale = distance / this.start.distance;
|
|
return {
|
|
distance: distance,
|
|
delta: this.last.distance - distance,
|
|
scale: scale
|
|
};
|
|
},
|
|
|
|
CLASS_NAME: "OpenLayers.Handler.Pinch"
|
|
});
|
|
|