Skip to content

Instantly share code, notes, and snippets.

@aubricus
Last active December 23, 2015 11:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aubricus/6630877 to your computer and use it in GitHub Desktop.
Save aubricus/6630877 to your computer and use it in GitHub Desktop.
Swipe Detection
SwipeEvent = {
'START' : 'start',
'DRAG' : 'drag',
'COMPLETE': 'complete',
'FAIL' : 'fail'
};
/**
* @namespace Swipe
* @description Simple interface to detect a touch based "Swipe"
* @param {object} spec Configuration object {}
* @param {object} my This is used to share secrets between objects; optional.
*
* @returns {object} The public interface for the Swipe object
*/
Swipe = function(spec, my){
var self = {};
var dispatcher = Dispatcher();
my = my || {};
var DIRECTION_UNKNOWN = 'unknown';
var DIRECTION_RIGHT = 'right';
var DIRECTION_LEFT = 'left';
var error_target = '[Swipe] error no target specified';
var target = spec.target || false;
var start = false;
var move = false;
var delta = false;
var direction = DIRECTION_UNKNOWN;
var _isScroll;
function __new__(){
self.on = dispatcher.on;
self.off = dispatcher.off;
}
/* initialization */
function __init__(){
self.name = 'Swipe';
if(target !== false){
initializeTouch(target);
}else{
throw error_target;
}
}
/* private methods */
function initializeTouch(target){
try{
target.addEventListener('touchstart', handleTouchStart, false);
target.addEventListener('touchmove', handleTouchMove, false);
target.addEventListener('touchend', handleTouchEnd, false);
}catch(e){
throw e;
}
}
function isScroll(){
if(typeof _isScroll === 'undefined'){
set_isScroll();
}
return _isScroll;
}
function set_isScroll(){
var delta = getDelta(start, move);
if(delta !== false){
_isScroll = (delta.x < delta.y);
}
}
/* event delegates */
function handleTouchStart(e){
if(isSingleTouch(e)){
// !important - disables native scrolling (fixes bug on android specifically)
e.preventDefault();
start = {
'x':e.touches[0].pageX,
'y':e.touches[0].pageY
};
dispatchStart();
}
}
function handleTouchMove(e){
// if touch is single touch (not pinch) and user is not attempting a vertical scroll
if(isSingleTouch(e) && !isScroll()){
// !important - disables native scrolling (fixes bug on android specifically)
e.preventDefault();
move = {
'x': e.touches[0].pageX,
'y': e.touches[0].pageY
};
delta = getDelta(start, move);
dispatchDrag();
}
}
function handleTouchEnd(e){
e.preventDefault();
direction = (move.x - start.x) > 0 ? DIRECTION_RIGHT : DIRECTION_LEFT;
if(isPastTollerance(delta)){
dispatchComplete();
}else{
dispatchFail();
}
// once gesture has reset ended data.
_isScroll = undefined;
start = false;
move = false;
delta = false;
}
/* helpers */
function getDelta(start, move){
if(start === false || move === false) return false;
var x = Math.abs(start.x - move.x);
var y = Math.abs(start.y - move.y);
return {'x': x, 'y': y};
}
function isSingleTouch(e){
return e.touches.length === 1 || e.scale && e.scale === 1;
}
function isPastTollerance(delta){
var result = false;
var dx = delta.x;
var width = target.getBoundingClientRect().width;
var threshold = 0.3;
if(dx > width*threshold){
result = true;
}
return result;
}
/* event dispatcher helpers */
function dispatchStart(){
log('dispatchStart');
dispatcher.dispatch(
SwipeEvent.START,
{
'start': start
}
);
}
function dispatchDrag(){
dispatcher.dispatch(
SwipeEvent.DRAG,
{
'start': start,
'move' : move,
'delta': delta,
'isScroll' : _isScroll
}
);
}
function dispatchComplete(){
log('dispatchComplete');
dispatcher.dispatch(
SwipeEvent.COMPLETE,
{
'start': start,
'move': move,
'delta': delta,
'direction': direction
}
);
}
function dispatchFail(){
log('dispatchFail');
dispatcher.dispatch(
SwipeEvent.FAIL,
{
'start': start,
'move': move,
'delta': delta,
'direction': direction
}
);
}
// do not delete //
__new__();
__init__();
return self;
// #eo do not delete //
};
/* #eo Swipe */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment