/**
* A simple event recognizer which knows when you double tap.
*/
Ext.define('Ext.event.gesture.DoubleTap', {
extend: 'Ext.event.gesture.SingleTouch',
priority: 300,
config: {
/**
* @cfg {Number}
* The maximum distance a touch can move without canceling recognition
*/
moveDistance: 8,
/**
* @cfg {Number}
* The minimum distance the second tap can occur from the first tap and still
* be considered a doubletap
*/
tapDistance: 24,
maxDuration: 300
},
handledEvents: ['singletap', 'doubletap'],
/**
* @member Ext.dom.Element
* @event singletap
* Fires when there is a single tap.
* @param {Ext.event.Event} event The {@link Ext.event.Event} event encapsulating the DOM event.
* @param {HTMLElement} node The target of the event.
* @param {Object} options The options object passed to Ext.mixin.Observable.addListener.
*/
/**
* @member Ext.dom.Element
* @event doubletap
* Fires when there is a double tap.
* @param {Ext.event.Event} event The {@link Ext.event.Event} event encapsulating the DOM event.
* @param {HTMLElement} node The target of the event.
* @param {Object} options The options object passed to Ext.mixin.Observable.addListener.
*/
singleTapTimer: null,
startTime: 0,
lastTapTime: 0,
onTouchStart: function(e) {
var me = this,
ret = me.callParent([e]),
lastStartPoint;
if (ret !== false) {
me.isStarted = true;
// the start point of the last touch that occurred.
lastStartPoint = me.lastStartPoint = e.changedTouches[0].point;
// the start point of the "first" touch in this gesture
me.startPoint = me.startPoint || lastStartPoint;
me.startTime = e.time;
Ext.undefer(me.singleTapTimer);
}
return ret;
},
onTouchMove: function(e) {
var me = this,
point = e.changedTouches[0].point,
scale = Ext.Element.getViewportScale(),
// account for scale so that move distance is actual screen pixels, not page pixels
distance = Math.round(Math.abs(point.getDistanceTo(me.lastStartPoint) * scale));
if (distance >= me.getMoveDistance()) {
return me.cancel(e);
}
},
onTouchEnd: function(e) {
var me = this,
maxDuration = me.getMaxDuration(),
time = e.time,
target = e.target,
lastTapTime = me.lastTapTime,
lastTarget = me.lastTarget,
point = e.changedTouches[0].point,
duration, scale, distance;
me.lastTapTime = time;
me.lastTarget = target;
if (lastTapTime) {
duration = time - lastTapTime;
if (duration <= maxDuration) {
scale = Ext.Element.getViewportScale();
// account for scale so that move distance is actual screen pixels, not page pixels
distance = Math.round(Math.abs(point.getDistanceTo(me.startPoint) * scale));
if (distance <= me.getTapDistance()) {
if (target !== lastTarget) {
return me.cancel(e);
}
me.lastTarget = null;
me.lastTapTime = 0;
me.fire('doubletap', e, {
touch: e.changedTouches[0],
duration: duration
});
return me.callParent([e]);
}
}
}
if (time - me.startTime > maxDuration) {
me.fire('singletap', e);
me.reset();
}
else {
me.setSingleTapTimer(e);
}
},
setSingleTapTimer: function(e) {
var me = this;
me.singleTapTimer = Ext.defer(function() {
me.fire('singletap', e);
me.reset();
}, me.getMaxDuration());
},
reset: function() {
var me = this;
Ext.undefer(me.singleTapTimer);
me.startTime = me.lastTapTime = 0;
me.lastStartPoint = me.startPoint = me.singleTapTimer = null;
return me.callParent();
}
}, function(DoubleTap) {
var gestures = Ext.manifest.gestures;
DoubleTap.instance = new DoubleTap(gestures && gestures.doubleTap);
});