Skip to content

Instantly share code, notes, and snippets.

@kriszyp
Created July 27, 2011 22:32
Show Gist options
  • Save kriszyp/1110512 to your computer and use it in GitHub Desktop.
Save kriszyp/1110512 to your computer and use it in GitHub Desktop.
define(["./base/lang"], function(lang){
// module:
// dojo/gesture/tap
// summary:
// This module provides tap gesture event handlers
// - dojo.gesture.tap -> to fire 'tap' event
// - dojo.gesture.tap.hold -> to fire 'tap.hold' event
// - dojo.gesture.tap.doubletap -> to fire 'tap.doubletap' event
// example:
// A. Used with dojo.connect()
// | dojo.connect(node, dojo.gesture.tap, function(e){});
// | dojo.connect(node, dojo.gesture.tap.hold, function(e){});
// | dojo.connect(node, dojo.gesture.tap.doubletap, function(e){});
//
// B. Used with dojo.on
// | define(["dojo/on", "dojo/gesture/tap"], function(on, tap){
// | on(node, tap, function(e){});
// | on(node, tap.hold, function(e){});
// | on(node, tap.doubletap, function(e){});
//
// C. Used with dojo.gesture.tap.* directly
// | dojo.gesture.tap(node, function(e){});
// | dojo.gesture.tap.hold(node, function(e){});
// | dojo.gesture.tap.doubletap(node, function(e){});
//
// Though there is always a default singleton gesture instance after being required, e.g
// | require(["dojo/gesture/tap"], function(){...});
// It's possible to unRegister it and create a new one with different parameter setting:
// | dojo.gesture.unRegister(dojo.gesture.tap);
// | var myTap = new dojo.gesture.tap.Tap({holdThreshold: 300});
// | dojo.gesture.register(myTap);
// | dojo.connect(node, myTap, function(e){});
// | dojo.connect(node, myTap.hold, function(e){});
// | dojo.connect(node, myTap.doubletap, function(e){});
function Tap(settings){
settings = lang.mixin({
holdThreshold: 500,
doubleTapTimeout: 250,
tapRadius: 10,
type: "tap"
}, settings);
var data = {};
function isTap(data, e){
var dx = Math.abs(data.tapContext.x - e.screenX);
var dy = Math.abs(data.tapContext.y - e.screenY);
return dx <= this.tapRadius && dy <= this.tapRadius;
}
return function(node, listener){
on(node, "touchstart", function(){
if(e.touches && e.touches.length >= 2){
//tap gesture is only for single touch
delete data.tapContext;
return;
}
var target = e.currentTarget;
if(!data.tapContext){
data.tapContext = {x: 0, y: 0, t: 0, c: 0};
}
var ct = new Date().getTime();
if(ct - data.tapContext.t <= this.doubleTapTimeout){
data.tapContext.c++;
}else{
data.tapContext.c = 1;
data.tapContext.x = e.screenX;
data.tapContext.y = e.screenY;
}
data.tapContext.t = ct;
clearTimeout(data.tapTimeOut);
data.tapTimeOut = setTimeout(function(){
if(type == "hold" && isTap(data, e)){
listener(e);
}
clearTimeout(data.tapTimeOut);
delete data.tapContext;
}, settings.holdThreshold);
});
on(node, "touchend", function(e){
if(!data.tapContext){
clearTimeout(data.tapTimeOut);
return;
}
switch(data.tapContext.c){
case 1:
if(type == 'tap'){
listener(e);
}
break;
case 2:
if(isTap(data, e) && type == "doubletap"){
listener(e);
}
break;
}
});
}
}
var tap = new Tap();
tap.Tap = Tap;
tap.doubletap = Tap({type:"doubletap"});
tap.hold = Tap({type:"hold"});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment