2013-01-11 18:48:15 +04:00
/ *
2013-01-23 16:31:04 +04:00
* @ fileOverview TouchSwipe - jQuery Plugin
* @ version 1.6 . 0
*
* @ author Matt Bryson http : //www.github.com/mattbryson
* @ see https : //github.com/mattbryson/TouchSwipe-Jquery-Plugin
* @ see http : //labs.skinkers.com/touchSwipe/
* @ see http : //plugins.jquery.com/project/touchSwipe
2013-01-11 18:48:15 +04:00
*
* Copyright ( c ) 2010 Matt Bryson ( www . skinkers . com )
* Dual licensed under the MIT or GPL Version 2 licenses .
*
*
* Changelog
* $Date : 2010 - 12 - 12 ( Wed , 12 Dec 2010 ) $
2013-01-23 16:31:04 +04:00
* $version : 1.0 . 0
2013-01-11 18:48:15 +04:00
* $version : 1.0 . 1 - removed multibyte comments
*
* $Date : 2011 - 21 - 02 ( Mon , 21 Feb 2011 ) $
* $version : 1.1 . 0 - added allowPageScroll property to allow swiping and scrolling of page
* - changed handler signatures so one handler can be used for multiple events
* $Date : 2011 - 23 - 02 ( Wed , 23 Feb 2011 ) $
* $version : 1.2 . 0 - added click handler . This is fired if the user simply clicks and does not swipe . The event object and click target are passed to handler .
* - If you use the http : //code.google.com/p/jquery-ui-for-ipad-and-iphone/ plugin, you can also assign jQuery mouse events to children of a touchSwipe object.
* $version : 1.2 . 1 - removed console log !
*
2013-01-23 16:31:04 +04:00
* $version : 1.2 . 2 - Fixed bug where scope was not preserved in callback methods .
2013-01-11 18:48:15 +04:00
*
* $Date : 2011 - 28 - 04 ( Thurs , 28 April 2011 ) $
* $version : 1.2 . 4 - Changed licence terms to be MIT or GPL inline with jQuery . Added check for support of touch events to stop non compatible browsers erroring .
*
* $Date : 2011 - 27 - 09 ( Tues , 27 September 2011 ) $
* $version : 1.2 . 5 - Added support for testing swipes with mouse on desktop browser ( thanks to https : //github.com/joelhy)
*
* $Date : 2012 - 14 - 05 ( Mon , 14 May 2012 ) $
* $version : 1.2 . 6 - Added timeThreshold between start and end touch , so user can ignore slow swipes ( thanks to Mark Chase ) . Default is null , all swipes are detected
2013-01-23 16:31:04 +04:00
*
2013-01-11 18:48:15 +04:00
* $Date : 2012 - 05 - 06 ( Tues , 05 June 2012 ) $
* $version : 1.2 . 7 - Changed time threshold to have null default for backwards compatibility . Added duration param passed back in events , and refactored how time is handled .
*
* $Date : 2012 - 05 - 06 ( Tues , 05 June 2012 ) $
* $version : 1.2 . 8 - Added the possibility to return a value like null or false in the trigger callback . In that way we can control when the touch start / move should take effect or not ( simply by returning in some cases return null ; or return false ; ) This effects the ontouchstart / ontouchmove event .
*
* $Date : 2012 - 06 - 06 ( Wed , 06 June 2012 ) $
* $version : 1.3 . 0 - Refactored whole plugin to allow for methods to be executed , as well as exposed defaults for user override . Added 'enable' , 'disable' , and 'destroy' methods
*
* $Date : 2012 - 05 - 06 ( Fri , 05 June 2012 ) $
* $version : 1.3 . 1 - Bug fixes - bind ( ) with false as last argument is no longer supported in jQuery 1.6 , also , if you just click , the duration is now returned correctly .
*
* $Date : 2012 - 29 - 07 ( Sun , 29 July 2012 ) $
* $version : 1.3 . 2 - Added fallbackToMouseEvents option to NOT capture mouse events on non touch devices .
* - Added "all" fingers value to the fingers property , so any combinatin of fingers triggers the swipe , allowing event handlers to check the finger count
*
* $Date : 2012 - 09 - 08 ( Thurs , 9 Aug 2012 ) $
* $version : 1.3 . 3 - Code tidy prep for minified version
*
* $Date : 2012 - 04 - 10 ( wed , 4 Oct 2012 ) $
* $version : 1.4 . 0 - Added pinch support , pinchIn and pinchOut
*
* $Date : 2012 - 11 - 10 ( Thurs , 11 Oct 2012 ) $
* $version : 1.5 . 0 - Added excludedElements , a jquery selector that specifies child elements that do NOT trigger swipes . By default , this is one select that removes all form , input select , button and anchor elements .
*
* $Date : 2012 - 22 - 10 ( Mon , 22 Oct 2012 ) $
* $version : 1.5 . 1 - Fixed bug with jQuery 1.8 and trailing comma in excludedElements
2013-01-23 16:31:04 +04:00
* - Fixed bug with IE and eventPreventDefault ( )
* $Date : 2013 - 01 - 12 ( Fri , 12 Jan 2013 ) $
* $version : 1.6 . 0 - Fixed bugs with pinching , mainly when both pinch and swipe enabled , as well as adding time threshold for multifinger gestures , so releasing one finger beofre the other doesnt trigger as single finger gesture .
* - made the demo site all static local HTML pages so they can be run locally by a developer
* - added jsDoc comments and added documentation for the plugin
2013-01-11 18:48:15 +04:00
* /
2013-01-23 16:31:04 +04:00
/ * *
* See ( http : //jquery.com/).
* @ name $
* @ class
* See the jQuery Library ( http : //jquery.com/) for full details. This just
* documents the function and classes that are added to jQuery by this plug - in .
* /
/ * *
* See ( http : //jquery.com/)
* @ name fn
* @ class
* See the jQuery Library ( http : //jquery.com/) for full details. This just
* documents the function and classes that are added to jQuery by this plug - in .
* @ memberOf $
* /
2013-01-11 18:48:15 +04:00
( function ( $ ) {
2013-01-23 16:31:04 +04:00
+ "use strict" ;
2013-01-11 18:48:15 +04:00
//Constants
var LEFT = "left" ,
RIGHT = "right" ,
UP = "up" ,
DOWN = "down" ,
IN = "in" ,
OUT = "out" ,
NONE = "none" ,
AUTO = "auto" ,
2013-01-23 16:31:04 +04:00
SWIPE = "swipe" ,
PINCH = "pinch" ,
CLICK = "click" ,
2013-01-11 18:48:15 +04:00
HORIZONTAL = "horizontal" ,
VERTICAL = "vertical" ,
ALL _FINGERS = "all" ,
PHASE _START = "start" ,
PHASE _MOVE = "move" ,
PHASE _END = "end" ,
PHASE _CANCEL = "cancel" ,
SUPPORTS _TOUCH = 'ontouchstart' in window ,
PLUGIN _NS = 'TouchSwipe' ;
2013-01-23 16:31:04 +04:00
/ * *
* The default configuration , and available options to configure touch swipe with .
* You can set the default values by updating any of the properties prior to instantiation .
* @ name $ . fn . swipe . defaults
* @ namespace
* @ property { int } [ fingers = 1 ] The number of fingers to detect in a swipe . Any swipes that do not meet this requirement will NOT trigger swipe handlers .
* @ property { int } [ threshold = 75 ] The number of pixels that the user must move their finger by before it is considered a swipe .
* @ property { int } [ pinchThreshold = 20 ] The number of pixels that the user must pinch their finger by before it is considered a pinch .
* @ property { int } [ maxTimeThreshold = null ] Time , in milliseconds , between touchStart and touchEnd must NOT exceed in order to be considered a swipe .
* @ property { int } [ fingerReleaseThreshold = 250 ] Time in milliseconds between releasing multiple fingers . If 2 fingers are down , and are released one after the other , if they are within this threshold , it counts as a simultaneous release .
* @ property { function } [ swipe = null ] A handler to catch all swipes . See { @ link $ . fn . swipe # event : swipe }
* @ property { function } [ swipeLeft = null ] A handler that is triggered for "left" swipes . See { @ link $ . fn . swipe # event : swipeLeft }
* @ property { function } [ swipeRight = null ] A handler that is triggered for "right" swipes . See { @ link $ . fn . swipe # event : swipeRight }
* @ property { function } [ swipeUp = null ] A handler that is triggered for "up" swipes . See { @ link $ . fn . swipe # event : swipeUp }
* @ property { function } [ swipeDown = null ] A handler that is triggered for "down" swipes . See { @ link $ . fn . swipe # event : swipeDown }
* @ property { function } [ swipeStatus = null ] A handler triggered for every phase of the swipe . See { @ link $ . fn . swipe # event : swipeStatus }
* @ property { function } [ pinchIn = null ] A handler triggered for pinch in events . See { @ link $ . fn . swipe # event : pinchIn }
* @ property { function } [ pinchOut = null ] A handler triggered for pinch out events . See { @ link $ . fn . swipe # event : pinchOut }
* @ property { function } [ pinchStatus = null ] A handler triggered for every phase of a pinch . See { @ link $ . fn . swipe # event : pinchStatus }
* @ property { function } [ click = null ] A handler triggered when a user just clicks on the item , rather than swipes it . If they do not move , click is triggered , if they do move , it is not .
* @ property { boolean } [ triggerOnTouchEnd = true ] If true , the swipe events are triggered when the touch end event is received ( user releases finger ) . If false , it will be triggered on reaching the threshold , and then cancel the touch event automatically .
* @ property { string } [ allowPageScroll = 'auto' ] How the browser handles page scrolls when the user is swiping on a touchSwipe object . See { @ link $ . fn . swipe . pageScroll } . < br / > < br / >
< code > "auto" < /code> : all undefined swipes will cause the page to scroll in that direction. <br/ >
< code > "none" < /code> : the page will not scroll when user swipes. <br/ >
< code > "horizontal" < /code> : will force page to scroll on horizontal swipes. <br/ >
< code > "vertical" < /code> : will force page to scroll on vertical swipes. <br/ >
* @ property { boolean } [ fallbackToMouseEvents = true ] If true mouse events are used when run on a non touch device , false will stop swipes being triggered by mouse events on non tocuh devices .
* @ property { string } [ excludedElements = "button, input, select, textarea, a, .noSwipe" ] A jquery selector that specifies child elements that do NOT trigger swipes . By default this excludes all form , input , select , button , anchor and . noSwipe elements .
* /
2013-01-11 18:48:15 +04:00
var defaults = {
2013-01-23 16:31:04 +04:00
fingers : 1 ,
threshold : 75 ,
pinchThreshold : 20 ,
maxTimeThreshold : null ,
fingerReleaseThreshold : 250 ,
swipe : null ,
swipeLeft : null ,
swipeRight : null ,
swipeUp : null ,
swipeDown : null ,
swipeStatus : null ,
pinchIn : null ,
pinchOut : null ,
pinchStatus : null ,
click : null ,
triggerOnTouchEnd : true ,
allowPageScroll : "auto" ,
fallbackToMouseEvents : true ,
excludedElements : "button, input, select, textarea, a, .noSwipe"
2013-01-11 18:48:15 +04:00
} ;
/ * *
2013-01-23 16:31:04 +04:00
* Applies TouchSwipe behaviour to one or more jQuery objects .
* The TouchSwipe plugin can be instantiated via this method , or methods within
* TouchSwipe can be executed via this method as per jQuery plugin architecture .
* @ see TouchSwipe
* @ class
* @ param { Mixed } method If the current DOMNode is a TouchSwipe object , and < code > method < / c o d e > i s a T o u c h S w i p e m e t h o d , t h e n
* the < code > method < / c o d e > i s e x e c u t e d , a n d a n y f o l l o w i n g a r g u m e n t s a r e p a s s e d t o t h e T o u c h S w i p e m e t h o d .
* If < code > method < / c o d e > i s a n o b j e c t , t h e n t h e T o u c h S w i p e c l a s s i s i n s t a n t i a t e d o n t h e c u r r e n t D O M N o d e , p a s s i n g t h e
* configuration properties defined in the object . See TouchSwipe
*
2013-01-11 18:48:15 +04:00
* /
$ . fn . swipe = function ( method ) {
var $this = $ ( this ) ,
plugin = $this . data ( PLUGIN _NS ) ;
//Check if we are already instantiated and trying to execute a method
if ( plugin && typeof method === 'string' ) {
if ( plugin [ method ] ) {
return plugin [ method ] . apply ( this , Array . prototype . slice . call ( arguments , 1 ) ) ;
} else {
$ . error ( 'Method ' + method + ' does not exist on jQuery.swipe' ) ;
}
}
//Else not instantiated and trying to pass init object (or nothing)
else if ( ! plugin && ( typeof method === 'object' || ! method ) ) {
return init . apply ( this , arguments ) ;
}
return $this ;
} ;
//Expose our defaults so a user could override the plugin defaults
$ . fn . swipe . defaults = defaults ;
2013-01-23 16:31:04 +04:00
/ * *
* The phases that a touch event goes through . The < code > phase < / c o d e > i s p a s s e d t o t h e e v e n t h a n d l e r s .
* These properties are read only , attempting to change them will not alter the values passed to the event handlers .
* @ namespace
* @ readonly
* @ property { string } PHASE _START Constant indicating the start phase of the touch event . Value is < code > "start" < / c o d e > .
* @ property { string } PHASE _MOVE Constant indicating the move phase of the touch event . Value is < code > "move" < / c o d e > .
* @ property { string } PHASE _END Constant indicating the end phase of the touch event . Value is < code > "end" < / c o d e > .
* @ property { string } PHASE _CANCEL Constant indicating the cancel phase of the touch event . Value is < code > "cancel" < / c o d e > .
* /
2013-01-11 18:48:15 +04:00
$ . fn . swipe . phases = {
PHASE _START : PHASE _START ,
PHASE _MOVE : PHASE _MOVE ,
PHASE _END : PHASE _END ,
PHASE _CANCEL : PHASE _CANCEL
} ;
2013-01-23 16:31:04 +04:00
/ * *
* The direction constants that are passed to the event handlers .
* These properties are read only , attempting to change them will not alter the values passed to the event handlers .
* @ namespace
* @ readonly
* @ property { string } LEFT Constant indicating the left direction . Value is < code > "left" < / c o d e > .
* @ property { string } RIGHT Constant indicating the right direction . Value is < code > "right" < / c o d e > .
* @ property { string } UP Constant indicating the up direction . Value is < code > "up" < / c o d e > .
* @ property { string } DOWN Constant indicating the down direction . Value is < code > "cancel" < / c o d e > .
* @ property { string } IN Constant indicating the in direction . Value is < code > "in" < / c o d e > .
* @ property { string } OUT Constant indicating the out direction . Value is < code > "out" < / c o d e > .
* /
2013-01-11 18:48:15 +04:00
$ . fn . swipe . directions = {
LEFT : LEFT ,
RIGHT : RIGHT ,
UP : UP ,
DOWN : DOWN ,
IN : IN ,
OUT : OUT
} ;
2013-01-23 16:31:04 +04:00
/ * *
* The page scroll constants that can be used to set the value of < code > allowPageScroll < / c o d e > o p t i o n
* These properties are read only
* @ namespace
* @ readonly
* @ see $ . fn . swipe . defaults # allowPageScroll
* @ property { string } NONE Constant indicating no page scrolling is allowed . Value is < code > "none" < / c o d e > .
* @ property { string } HORIZONTAL Constant indicating horizontal page scrolling is allowed . Value is < code > "horizontal" < / c o d e > .
* @ property { string } VERTICAL Constant indicating vertical page scrolling is allowed . Value is < code > "vertical" < / c o d e > .
* @ property { string } AUTO Constant indicating either horizontal or vertical will be allowed , depending on the swipe handlers registered . Value is < code > "auto" < / c o d e > .
* /
2013-01-11 18:48:15 +04:00
$ . fn . swipe . pageScroll = {
NONE : NONE ,
HORIZONTAL : HORIZONTAL ,
VERTICAL : VERTICAL ,
AUTO : AUTO
} ;
2013-01-23 16:31:04 +04:00
/ * *
* Constants representing the number of fingers used in a swipe . These are used to set both the value of < code > fingers < / c o d e > i n t h e
* options object , as well as the value of the < code > fingers < / c o d e > e v e n t p r o p e r t y .
* These properties are read only , attempting to change them will not alter the values passed to the event handlers .
* @ namespace
* @ readonly
* @ see $ . fn . swipe . defaults # fingers
* @ property { string } ONE Constant indicating 1 finger is to be detected / was detected . Value is < code > 1 < / c o d e > .
* @ property { string } TWO Constant indicating 2 fingers are to be detected / were detected . Value is < code > 1 < / c o d e > .
* @ property { string } THREE Constant indicating 3 finger are to be detected / were detected . Value is < code > 1 < / c o d e > .
* @ property { string } ALL Constant indicating any combination of finger are to be detected . Value is < code > "all" < / c o d e > .
* /
2013-01-11 18:48:15 +04:00
$ . fn . swipe . fingers = {
ONE : 1 ,
TWO : 2 ,
THREE : 3 ,
ALL : ALL _FINGERS
} ;
/ * *
* Initialise the plugin for each DOM element matched
2013-01-23 16:31:04 +04:00
* This creates a new instance of the main TouchSwipe class for each DOM element , and then
2013-01-11 18:48:15 +04:00
* saves a reference to that instance in the elements data property .
2013-01-23 16:31:04 +04:00
* @ internal
2013-01-11 18:48:15 +04:00
* /
function init ( options ) {
//Prep and extend the options
if ( options && ( options . allowPageScroll === undefined && ( options . swipe !== undefined || options . swipeStatus !== undefined ) ) ) {
options . allowPageScroll = NONE ;
}
if ( ! options ) {
options = { } ;
}
//pass empty object so we dont modify the defaults
options = $ . extend ( { } , $ . fn . swipe . defaults , options ) ;
//For each element instantiate the plugin
return this . each ( function ( ) {
var $this = $ ( this ) ;
//Check we havent already initialised the plugin
var plugin = $this . data ( PLUGIN _NS ) ;
if ( ! plugin ) {
plugin = new touchSwipe ( this , options ) ;
$this . data ( PLUGIN _NS , plugin ) ;
}
} ) ;
}
/ * *
2013-01-23 16:31:04 +04:00
* Main TouchSwipe Plugin Class .
* Do not use this to construct your TouchSwipe object , use the jQuery plugin method $ . fn . swipe ( ) ; { @ link $ . fn . swipe }
* @ private
* @ name TouchSwipe
* @ param { DOMNode } element The HTML DOM object to apply to plugin to
* @ param { Object } options The options to configure the plugin with . @ link { $ . fn . swipe . defaults }
* @ see $ . fh . swipe . defaults
* @ see $ . fh . swipe
* @ class
2013-01-11 18:48:15 +04:00
* /
function touchSwipe ( element , options ) {
var useTouchEvents = ( SUPPORTS _TOUCH || ! options . fallbackToMouseEvents ) ,
START _EV = useTouchEvents ? 'touchstart' : 'mousedown' ,
MOVE _EV = useTouchEvents ? 'touchmove' : 'mousemove' ,
END _EV = useTouchEvents ? 'touchend' : 'mouseup' ,
CANCEL _EV = 'touchcancel' ;
2013-01-23 16:31:04 +04:00
//touch properties
2013-01-11 18:48:15 +04:00
var distance = 0 ;
var direction = null ;
var duration = 0 ;
var startTouchesDistance = 0 ;
var endTouchesDistance = 0 ;
var pinchZoom = 1 ;
var pinchDirection = 0 ;
//jQuery wrapped element for this instance
var $element = $ ( element ) ;
2013-01-23 16:31:04 +04:00
//Current phase of th touch cycle
2013-01-11 18:48:15 +04:00
var phase = "start" ;
2013-01-23 16:31:04 +04:00
// the current number of fingers being used.
var fingerCount = 0 ;
2013-01-11 18:48:15 +04:00
//track mouse points / delta
var fingerData = null ;
//track times
var startTime = 0 ;
var endTime = 0 ;
2013-01-23 16:31:04 +04:00
var previousTouchEndTime = 0 ;
var previousTouchFingerCount = 0 ;
2013-01-11 18:48:15 +04:00
// Add gestures to all swipable areas if supported
try {
$element . bind ( START _EV , touchStart ) ;
$element . bind ( CANCEL _EV , touchCancel ) ;
}
catch ( e ) {
$ . error ( 'events not supported ' + START _EV + ',' + CANCEL _EV + ' on jQuery.swipe' ) ;
}
2013-01-23 16:31:04 +04:00
//
2013-01-11 18:48:15 +04:00
//Public methods
2013-01-23 16:31:04 +04:00
//
2013-01-11 18:48:15 +04:00
/ * *
* re - enables the swipe plugin with the previous configuration
2013-01-23 16:31:04 +04:00
* @ function
* @ name $ . fn . swipe # enable
* @ return { DOMNode } The Dom element that was registered with TouchSwipe
* @ example $ ( "#element" ) . swipe ( "enable" ) ;
2013-01-11 18:48:15 +04:00
* /
this . enable = function ( ) {
$element . bind ( START _EV , touchStart ) ;
$element . bind ( CANCEL _EV , touchCancel ) ;
return $element ;
} ;
/ * *
* disables the swipe plugin
2013-01-23 16:31:04 +04:00
* @ function
* @ name $ . fn . swipe # disable
* @ return { DOMNode } The Dom element that is now registered with TouchSwipe
* @ example $ ( "#element" ) . swipe ( "disable" ) ;
2013-01-11 18:48:15 +04:00
* /
this . disable = function ( ) {
removeListeners ( ) ;
return $element ;
} ;
/ * *
* Destroy the swipe plugin completely . To use any swipe methods , you must re initialise the plugin .
2013-01-23 16:31:04 +04:00
* @ function
* @ name $ . fn . swipe # destroy
* @ return { DOMNode } The Dom element that was registered with TouchSwipe
* @ example $ ( "#element" ) . swipe ( "destroy" ) ;
2013-01-11 18:48:15 +04:00
* /
this . destroy = function ( ) {
removeListeners ( ) ;
$element . data ( PLUGIN _NS , null ) ;
return $element ;
} ;
2013-01-23 16:31:04 +04:00
//
// Private methods
//
//
// EVENTS
//
2013-01-11 18:48:15 +04:00
/ * *
2013-01-23 16:31:04 +04:00
* Event handler for a touch start event .
2013-01-11 18:48:15 +04:00
* Stops the default click event from triggering and stores where we touched
2013-01-23 16:31:04 +04:00
* @ inner
* @ param { object } jqEvent The normalised jQuery event object .
2013-01-11 18:48:15 +04:00
* /
2013-01-23 16:31:04 +04:00
function touchStart ( jqEvent ) {
2013-01-11 18:48:15 +04:00
//If we already in a touch event (a finger already in use) then ignore subsequent ones..
if ( getTouchInProgress ( ) )
return ;
//Check if this element matches any in the excluded elements selectors, or its parent is excluded, if so, DONT swipe
2013-01-23 16:31:04 +04:00
if ( $ ( jqEvent . target ) . closest ( options . excludedElements , $element ) . length > 0 )
2013-01-11 18:48:15 +04:00
return ;
//As we use Jquery bind for events, we need to target the original event object
2013-01-23 16:31:04 +04:00
var event = jqEvent . originalEvent ;
2013-01-11 18:48:15 +04:00
var ret ,
evt = SUPPORTS _TOUCH ? event . touches [ 0 ] : event ;
phase = PHASE _START ;
//If we support touches, get the finger count
if ( SUPPORTS _TOUCH ) {
// get the total number of fingers touching the screen
fingerCount = event . touches . length ;
}
//Else this is the desktop, so stop the browser from dragging the image
else {
2013-01-23 16:31:04 +04:00
jqEvent . preventDefault ( ) ; //call this on jq event so we are cross browser
2013-01-11 18:48:15 +04:00
}
//clear vars..
distance = 0 ;
direction = null ;
pinchDirection = null ;
duration = 0 ;
startTouchesDistance = 0 ;
endTouchesDistance = 0 ;
pinchZoom = 1 ;
2013-01-23 16:31:04 +04:00
pinchDistance = 0 ;
fingerData = createAllFingerData ( ) ;
cancelMultiFingerRelease ( ) ;
2013-01-11 18:48:15 +04:00
// check the number of fingers is what we are looking for, or we are capturing pinches
if ( ! SUPPORTS _TOUCH || ( fingerCount === options . fingers || options . fingers === ALL _FINGERS ) || hasPinches ( ) ) {
// get the coordinates of the touch
2013-01-23 16:31:04 +04:00
createFingerData ( 0 , evt ) ;
2013-01-11 18:48:15 +04:00
startTime = getTimeStamp ( ) ;
if ( fingerCount == 2 ) {
//Keep track of the initial pinch distance, so we can calculate the diff later
//Store second finger data as start
2013-01-23 16:31:04 +04:00
createFingerData ( 1 , event . touches [ 1 ] ) ;
2013-01-11 18:48:15 +04:00
startTouchesDistance = endTouchesDistance = calculateTouchesDistance ( fingerData [ 0 ] . start , fingerData [ 1 ] . start ) ;
}
if ( options . swipeStatus || options . pinchStatus ) {
ret = triggerHandler ( event , phase ) ;
}
}
else {
//A touch with more or less than the fingers we are looking for, so cancel
2013-01-23 16:31:04 +04:00
ret = false ;
2013-01-11 18:48:15 +04:00
}
//If we have a return value from the users handler, then return and cancel
if ( ret === false ) {
phase = PHASE _CANCEL ;
triggerHandler ( event , phase ) ;
return ret ;
}
else {
setTouchInProgress ( true ) ;
2013-01-23 16:31:04 +04:00
2013-01-11 18:48:15 +04:00
$element . bind ( MOVE _EV , touchMove ) ;
$element . bind ( END _EV , touchEnd ) ;
}
} ;
2013-01-23 16:31:04 +04:00
2013-01-11 18:48:15 +04:00
/ * *
* Event handler for a touch move event .
* If we change fingers during move , then cancel the event
2013-01-23 16:31:04 +04:00
* @ inner
* @ param { object } jqEvent The normalised jQuery event object .
2013-01-11 18:48:15 +04:00
* /
2013-01-23 16:31:04 +04:00
function touchMove ( jqEvent ) {
2013-01-11 18:48:15 +04:00
//As we use Jquery bind for events, we need to target the original event object
2013-01-23 16:31:04 +04:00
var event = jqEvent . originalEvent ;
2013-01-11 18:48:15 +04:00
2013-01-23 16:31:04 +04:00
//If we are ending, cancelling, or within the threshold of 2 fingers being released, dont track anything..
if ( phase === PHASE _END || phase === PHASE _CANCEL || inMultiFingerRelease ( ) )
2013-01-11 18:48:15 +04:00
return ;
var ret ,
evt = SUPPORTS _TOUCH ? event . touches [ 0 ] : event ;
2013-01-23 16:31:04 +04:00
//Update the finger data
var currentFinger = updateFingerData ( evt ) ;
2013-01-11 18:48:15 +04:00
endTime = getTimeStamp ( ) ;
2013-01-23 16:31:04 +04:00
2013-01-11 18:48:15 +04:00
if ( SUPPORTS _TOUCH ) {
fingerCount = event . touches . length ;
}
phase = PHASE _MOVE ;
//If we have 2 fingers get Touches distance as well
if ( fingerCount == 2 ) {
2013-01-23 16:31:04 +04:00
2013-01-11 18:48:15 +04:00
//Keep track of the initial pinch distance, so we can calculate the diff later
//We do this here as well as the start event, incase they start with 1 finger, and the press 2 fingers
if ( startTouchesDistance == 0 ) {
2013-01-23 16:31:04 +04:00
//Create second finger if this is the first time...
createFingerData ( 1 , event . touches [ 1 ] ) ;
2013-01-11 18:48:15 +04:00
startTouchesDistance = endTouchesDistance = calculateTouchesDistance ( fingerData [ 0 ] . start , fingerData [ 1 ] . start ) ;
} else {
2013-01-23 16:31:04 +04:00
//Else just update the second finger
updateFingerData ( event . touches [ 1 ] ) ;
2013-01-11 18:48:15 +04:00
endTouchesDistance = calculateTouchesDistance ( fingerData [ 0 ] . end , fingerData [ 1 ] . end ) ;
pinchDirection = calculatePinchDirection ( fingerData [ 0 ] . end , fingerData [ 1 ] . end ) ;
}
pinchZoom = calculatePinchZoom ( startTouchesDistance , endTouchesDistance ) ;
2013-01-23 16:31:04 +04:00
pinchDistance = Math . abs ( startTouchesDistance - endTouchesDistance ) ;
2013-01-11 18:48:15 +04:00
}
2013-01-23 16:31:04 +04:00
if ( ( fingerCount === options . fingers || options . fingers === ALL _FINGERS ) || ! SUPPORTS _TOUCH || hasPinches ( ) ) {
direction = calculateDirection ( currentFinger . start , currentFinger . end ) ;
2013-01-11 18:48:15 +04:00
//Check if we need to prevent default evnet (page scroll / pinch zoom) or not
2013-01-23 16:31:04 +04:00
validateDefaultEvent ( jqEvent , direction ) ;
2013-01-11 18:48:15 +04:00
//Distance and duration are all off the main finger
2013-01-23 16:31:04 +04:00
distance = calculateDistance ( currentFinger . start , currentFinger . end ) ;
duration = calculateDuration ( ) ;
2013-01-11 18:48:15 +04:00
if ( options . swipeStatus || options . pinchStatus ) {
ret = triggerHandler ( event , phase ) ;
}
//If we trigger whilst dragging, not on touch end, then calculate now...
if ( ! options . triggerOnTouchEnd ) {
var cancel = ! validateSwipeTime ( ) ;
// if the user swiped more than the minimum length, perform the appropriate action
if ( validateSwipeDistance ( ) === true ) {
phase = PHASE _END ;
ret = triggerHandler ( event , phase ) ;
} else if ( cancel ) {
phase = PHASE _CANCEL ;
triggerHandler ( event , phase ) ;
}
}
}
else {
phase = PHASE _CANCEL ;
triggerHandler ( event , phase ) ;
}
if ( ret === false ) {
phase = PHASE _CANCEL ;
triggerHandler ( event , phase ) ;
}
}
2013-01-23 16:31:04 +04:00
2013-01-11 18:48:15 +04:00
/ * *
* Event handler for a touch end event .
* Calculate the direction and trigger events
2013-01-23 16:31:04 +04:00
* @ inner
* @ param { object } jqEvent The normalised jQuery event object .
2013-01-11 18:48:15 +04:00
* /
2013-01-23 16:31:04 +04:00
function touchEnd ( jqEvent ) {
2013-01-11 18:48:15 +04:00
//As we use Jquery bind for events, we need to target the original event object
2013-01-23 16:31:04 +04:00
var event = jqEvent . originalEvent ;
2013-01-11 18:48:15 +04:00
2013-01-23 16:31:04 +04:00
//If we are still in a touch with another finger return
//This allows us to wait a fraction and see if the other finger comes up, if it does within the threshold, then we treat it as a multi release, not a single release.
if ( SUPPORTS _TOUCH ) {
if ( event . touches . length > 0 ) {
startMultiFingerRelease ( ) ;
return true ;
}
}
//If a previous finger has been released, check how long ago, if within the threshold, then assume it was a multifinger release.
//This is used to allow 2 fingers to release fractionally after each other, whilst maintainig the event as containg 2 fingers, not 1
if ( inMultiFingerRelease ( ) ) {
fingerCount = previousTouchFingerCount ;
}
2013-01-11 18:48:15 +04:00
2013-01-23 16:31:04 +04:00
//call this on jq event so we are cross browser
jqEvent . preventDefault ( ) ;
//Set end of swipe
2013-01-11 18:48:15 +04:00
endTime = getTimeStamp ( ) ;
//If we trigger handlers at end of swipe OR, we trigger during, but they didnt trigger and we are still in the move phase
if ( options . triggerOnTouchEnd || ( options . triggerOnTouchEnd === false && phase === PHASE _MOVE ) ) {
phase = PHASE _END ;
//The number of fingers we want were matched, or on desktop we ignore
var hasCorrectFingerCount = ( ( fingerCount === options . fingers || options . fingers === ALL _FINGERS ) || ! SUPPORTS _TOUCH ) ;
//We have an end value for the finger
var hasEndPoint = fingerData [ 0 ] . end . x !== 0 ;
//Check if the above conditions are met to make this swipe count...
2013-01-23 16:31:04 +04:00
var isSwipe = hasCorrectFingerCount && hasEndPoint && ( didPinch ( ) || didSwipe ( ) ) ;
2013-01-11 18:48:15 +04:00
//If we are in a swipe, validate the time and distance...
if ( isSwipe ) {
2013-01-23 16:31:04 +04:00
triggerHandler ( event , phase ) ;
} else {
2013-01-11 18:48:15 +04:00
phase = PHASE _CANCEL ;
triggerHandler ( event , phase ) ;
}
}
else if ( phase === PHASE _MOVE ) {
phase = PHASE _CANCEL ;
triggerHandler ( event , phase ) ;
}
$element . unbind ( MOVE _EV , touchMove , false ) ;
$element . unbind ( END _EV , touchEnd , false ) ;
setTouchInProgress ( false ) ;
}
2013-01-23 16:31:04 +04:00
2013-01-11 18:48:15 +04:00
/ * *
* Event handler for a touch cancel event .
* Clears current vars
2013-01-23 16:31:04 +04:00
* @ inner
2013-01-11 18:48:15 +04:00
* /
function touchCancel ( ) {
// reset the variables back to default values
fingerCount = 0 ;
endTime = 0 ;
startTime = 0 ;
startTouchesDistance = 0 ;
endTouchesDistance = 0 ;
pinchZoom = 1 ;
2013-01-23 16:31:04 +04:00
//If we were in progress of tracking a possible multi touch end, then re set it.
cancelMultiFingerRelease ( ) ;
setTouchInProgress ( false ) ;
}
/ * *
* Removes all listeners that were associated with the plugin
* @ inner
* /
function removeListeners ( ) {
$element . unbind ( START _EV , touchStart ) ;
$element . unbind ( CANCEL _EV , touchCancel ) ;
$element . unbind ( MOVE _EV , touchMove ) ;
$element . unbind ( END _EV , touchEnd ) ;
2013-01-11 18:48:15 +04:00
setTouchInProgress ( false ) ;
}
/ * *
* Trigger the relevant event handler
* The handlers are passed the original event , the element that was swiped , and in the case of the catch all handler , the direction that was swiped , "left" , "right" , "up" , or "down"
2013-01-23 16:31:04 +04:00
* @ param { object } event the original event object
* @ param { string } phase the phase of the swipe ( start , end cancel etc ) { @ link $ . fn . swipe . phases }
* @ inner
2013-01-11 18:48:15 +04:00
* /
function triggerHandler ( event , phase ) {
2013-01-23 16:31:04 +04:00
2013-01-11 18:48:15 +04:00
var ret = undefined ;
2013-01-23 16:31:04 +04:00
// SWIPE GESTURES
if ( hasSwipes ( ) ) {
//Trigger the swipe events...
ret = triggerHandlerForGesture ( event , phase , SWIPE ) ;
2013-01-11 18:48:15 +04:00
}
2013-01-23 16:31:04 +04:00
// PINCH GESTURES (if the above didnt cancel)
if ( hasPinches ( ) && ret !== false ) {
//Trigger the pinch events...
ret = triggerHandlerForGesture ( event , phase , PINCH ) ;
2013-01-11 18:48:15 +04:00
}
2013-01-23 16:31:04 +04:00
// CLICKS / TAPS (if the above didnt cancel)
if ( hasClick ( ) && ret !== false ) {
//Trigger the pinch events...
ret = triggerHandlerForGesture ( event , phase , CLICK ) ;
}
// If we are cancelling the gesture, then manually trigger the reset handler
2013-01-11 18:48:15 +04:00
if ( phase === PHASE _CANCEL ) {
2013-01-23 16:31:04 +04:00
touchCancel ( event ) ;
2013-01-11 18:48:15 +04:00
}
2013-01-23 16:31:04 +04:00
// If we are ending the gesture, then manually trigger the reset handler IF all fingers are off
if ( phase === PHASE _END ) {
//If we support touch, then check that all fingers are off before we cancel
if ( SUPPORTS _TOUCH ) {
if ( event . touches . length == 0 ) {
touchCancel ( event ) ;
}
}
else {
touchCancel ( event ) ;
2013-01-11 18:48:15 +04:00
}
2013-01-23 16:31:04 +04:00
}
return ret ;
}
/ * *
* Trigger the relevant event handler
* The handlers are passed the original event , the element that was swiped , and in the case of the catch all handler , the direction that was swiped , "left" , "right" , "up" , or "down"
* @ param { object } event the original event object
* @ param { string } phase the phase of the swipe ( start , end cancel etc ) { @ link $ . fn . swipe . phases }
* @ param { string } gesture the gesture to triger a handler for : PINCH or SWIPE { @ link $ . fn . swipe . gestures }
* @ return Boolean False , to indicate that the event should stop propagation , or void .
* @ inner
* /
function triggerHandlerForGesture ( event , phase , gesture ) {
var ret = undefined ;
//SWIPES....
if ( gesture == SWIPE ) {
//Trigger status every time..
if ( options . swipeStatus ) {
ret = options . swipeStatus . call ( $element , event , phase , direction || null , distance || 0 , duration || 0 , fingerCount ) ;
//If the status cancels, then dont run the subsequent event handlers..
if ( ret === false ) return false ;
2013-01-11 18:48:15 +04:00
}
2013-01-23 16:31:04 +04:00
if ( phase == PHASE _END && validateSwipe ( ) ) {
//trigger catch all event handler
if ( options . swipe ) {
ret = options . swipe . call ( $element , event , direction , distance , duration , fingerCount ) ;
//If the status cancels, then dont run the subsequent event handlers..
if ( ret === false ) return false ;
}
2013-01-11 18:48:15 +04:00
2013-01-23 16:31:04 +04:00
//trigger direction specific event handlers
switch ( direction ) {
case LEFT :
if ( options . swipeLeft ) {
ret = options . swipeLeft . call ( $element , event , direction , distance , duration , fingerCount ) ;
}
break ;
case RIGHT :
if ( options . swipeRight ) {
ret = options . swipeRight . call ( $element , event , direction , distance , duration , fingerCount ) ;
}
break ;
case UP :
if ( options . swipeUp ) {
ret = options . swipeUp . call ( $element , event , direction , distance , duration , fingerCount ) ;
}
break ;
case DOWN :
if ( options . swipeDown ) {
ret = options . swipeDown . call ( $element , event , direction , distance , duration , fingerCount ) ;
}
break ;
}
2013-01-11 18:48:15 +04:00
}
}
2013-01-23 16:31:04 +04:00
//PINCHES....
if ( gesture == PINCH ) {
//Trigger status every time
if ( options . pinchStatus ) {
ret = options . pinchStatus . call ( $element , event , phase , pinchDirection || null , pinchDistance || 0 , duration || 0 , fingerCount , pinchZoom ) ;
//If the status cancels, then dont run the subsequent event handlers..
if ( ret === false ) return false ;
}
if ( phase == PHASE _END && validatePinch ( ) ) {
switch ( pinchDirection ) {
case IN :
if ( options . pinchIn ) {
ret = options . pinchIn . call ( $element , event , pinchDirection || null , pinchDistance || 0 , duration || 0 , fingerCount , pinchZoom ) ;
}
break ;
case OUT :
if ( options . pinchOut ) {
ret = options . pinchOut . call ( $element , event , pinchDirection || null , pinchDistance || 0 , duration || 0 , fingerCount , pinchZoom ) ;
}
break ;
}
}
2013-01-11 18:48:15 +04:00
}
2013-01-23 16:31:04 +04:00
//CLICKS...
if ( gesture == CLICK ) {
if ( phase === PHASE _CANCEL ) {
if ( options . click && ( fingerCount === 1 || ! SUPPORTS _TOUCH ) && ( isNaN ( distance ) || distance === 0 ) ) {
ret = options . click . call ( $element , event , event . target ) ;
}
}
}
2013-01-11 18:48:15 +04:00
return ret ;
}
2013-01-23 16:31:04 +04:00
//
// GESTURE VALIDATION
//
2013-01-11 18:48:15 +04:00
/ * *
* Checks the user has swipe far enough
2013-01-23 16:31:04 +04:00
* @ return Boolean if < code > threshold < / c o d e > h a s b e e n s e t , e l s e n u l l i s r e t u r n e d .
* @ inner
2013-01-11 18:48:15 +04:00
* /
function validateSwipeDistance ( ) {
if ( options . threshold !== null ) {
return distance >= options . threshold ;
}
return null ;
}
2013-01-23 16:31:04 +04:00
/ * *
* Checks the user has pinched far enough
* @ return Boolean if < code > pinchThreshold < / c o d e > h a s b e e n s e t , e l s e n u l l i s r e t u r n e d .
* @ inner
* /
function validatePinchDistance ( ) {
if ( options . pinchThreshold !== null ) {
return pinchDistance >= options . pinchThreshold ;
}
return null ;
}
2013-01-11 18:48:15 +04:00
/ * *
* Checks that the time taken to swipe meets the minimum / maximum requirements
2013-01-23 16:31:04 +04:00
* @ return Boolean
* @ inner
2013-01-11 18:48:15 +04:00
* /
function validateSwipeTime ( ) {
var result ;
//If no time set, then return true
if ( options . maxTimeThreshold ) {
if ( duration >= options . maxTimeThreshold ) {
result = false ;
} else {
result = true ;
}
}
else {
result = true ;
}
return result ;
}
/ * *
* Checks direction of the swipe and the value allowPageScroll to see if we should allow or prevent the default behaviour from occurring .
* This will essentially allow page scrolling or not when the user is swiping on a touchSwipe object .
2013-01-23 16:31:04 +04:00
* @ param { object } jqEvent The normalised jQuery representation of the event object .
* @ param { string } direction The direction of the event . See { @ link $ . fn . swipe . directions }
* @ see $ . fn . swipe . directions
* @ inner
2013-01-11 18:48:15 +04:00
* /
2013-01-23 16:31:04 +04:00
function validateDefaultEvent ( jqEvent , direction ) {
2013-01-11 18:48:15 +04:00
if ( options . allowPageScroll === NONE || hasPinches ( ) ) {
2013-01-23 16:31:04 +04:00
jqEvent . preventDefault ( ) ;
2013-01-11 18:48:15 +04:00
} else {
var auto = options . allowPageScroll === AUTO ;
switch ( direction ) {
case LEFT :
if ( ( options . swipeLeft && auto ) || ( ! auto && options . allowPageScroll != HORIZONTAL ) ) {
2013-01-23 16:31:04 +04:00
jqEvent . preventDefault ( ) ;
2013-01-11 18:48:15 +04:00
}
break ;
case RIGHT :
if ( ( options . swipeRight && auto ) || ( ! auto && options . allowPageScroll != HORIZONTAL ) ) {
2013-01-23 16:31:04 +04:00
jqEvent . preventDefault ( ) ;
2013-01-11 18:48:15 +04:00
}
break ;
case UP :
if ( ( options . swipeUp && auto ) || ( ! auto && options . allowPageScroll != VERTICAL ) ) {
2013-01-23 16:31:04 +04:00
jqEvent . preventDefault ( ) ;
2013-01-11 18:48:15 +04:00
}
break ;
case DOWN :
if ( ( options . swipeDown && auto ) || ( ! auto && options . allowPageScroll != VERTICAL ) ) {
2013-01-23 16:31:04 +04:00
jqEvent . preventDefault ( ) ;
2013-01-11 18:48:15 +04:00
}
break ;
}
}
}
2013-01-23 16:31:04 +04:00
// PINCHES
/ * *
* Returns true of the current pinch meets the thresholds
* @ return Boolean
* @ inner
* /
function validatePinch ( ) {
//Check the pinch thresholds
var hasValidPinchDistance = validatePinchDistance ( ) ;
//Check the pinch met the minimum requirements
var valid = ( hasValidPinchDistance === true || hasValidPinchDistance === null ) ;
return valid ;
}
/ * *
* Returns true if any Pinch events have been registered
* @ return Boolean
* @ inner
* /
function hasPinches ( ) {
//Enure we dont return 0 or null for false values
return ! ! ( options . pinchStatus || options . pinchIn || options . pinchOut ) ;
}
/ * *
* Returns true if we are detecting pinches , and have one
* @ return Boolean
* @ inner
* /
function didPinch ( ) {
//Enure we dont return 0 or null for false values
return ! ! ( pinchDirection && hasPinches ( ) ) ;
}
// SWIPES
/ * *
* Returns true if the current swipe meets the thresholds
* @ return Boolean
* @ inner
* /
function validateSwipe ( ) {
//Check validity of swipe
var hasValidTime = validateSwipeTime ( ) ;
var hasValidDistance = validateSwipeDistance ( ) ;
// if the user swiped more than the minimum length, perform the appropriate action
// hasValidDistance is null when no distance is set
var valid = ( hasValidDistance === true || hasValidDistance === null ) && hasValidTime ;
return valid ;
}
/ * *
* Returns true if any Swipe events have been registered
* @ return Boolean
* @ inner
* /
function hasSwipes ( ) {
//Enure we dont return 0 or null for false values
return ! ! ( options . swipe || options . swipeStatus || options . swipeLeft || options . swipeRight || options . swipeUp || options . swipeDown ) ;
}
/ * *
* Returns true if we are detecting swipes and have one
* @ return Boolean
* @ inner
* /
function didSwipe ( ) {
//Enure we dont return 0 or null for false values
return ! ! ( direction && hasSwipes ( ) ) ;
}
// TAP / CLICK
/ * *
* Returns true of any clcik / tap evetns have been registered
* @ return Boolean
* @ inner
* /
function hasClick ( ) {
//Enure we dont return 0 or null for false values
return ! ! ( options . click ) ;
}
// MULTI FINGER TOUCH
/ * *
* Starts tracking the time between 2 finger releases , and keeps track of how many fingers we initially had up
* @ inner
* /
function startMultiFingerRelease ( ) {
previousTouchEndTime = getTimeStamp ( ) ;
previousTouchFingerCount = event . touches . length + 1 ;
}
/ * *
* Cancels the tracking of time between 2 finger releases , and resets counters
* @ inner
* /
function cancelMultiFingerRelease ( ) {
previousTouchEndTime = 0 ;
previousTouchFingerCount = 0 ;
}
/ * *
* Checks if we are in the threshold between 2 fingers being released
* @ return Boolean
* @ inner
* /
function inMultiFingerRelease ( ) {
var withinThreshold = false ;
if ( previousTouchEndTime ) {
var diff = getTimeStamp ( ) - previousTouchEndTime
if ( diff <= options . fingerReleaseThreshold ) {
withinThreshold = true ;
}
}
return withinThreshold ;
}
/ * *
* gets a data flag to indicate that a touch is in progress
* @ return Boolean
* @ inner
* /
function getTouchInProgress ( ) {
//strict equality to ensure only true and false are returned
return ! ! ( $element . data ( PLUGIN _NS + '_intouch' ) === true ) ;
}
/ * *
* Sets a data flag to indicate that a touch is in progress
* @ param { boolean } val The value to set the property to
* @ inner
* /
function setTouchInProgress ( val ) {
//strict equality to ensure only true and false can update the value
$element . data ( PLUGIN _NS + '_intouch' , val === true ) ;
}
/ * *
* Creates the finger data for the touch / finger in the event object .
* @ param { int } index The index in the array to store the finger data ( usually the order the fingers were pressed )
* @ param { object } evt The event object containing finger data
* @ return finger data object
* @ inner
* /
function createFingerData ( index , evt ) {
var id = evt . identifier !== undefined ? evt . identifier : 0 ;
fingerData [ index ] . identifier = id ;
fingerData [ index ] . start . x = fingerData [ index ] . end . x = evt . pageX ;
fingerData [ index ] . start . y = fingerData [ index ] . end . y = evt . pageY ;
return fingerData [ index ] ;
}
/ * *
* Updates the finger data for a particular event object
* @ param { object } evt The event object containing the touch / finger data to upadte
* @ return a finger data object .
* @ inner
* /
function updateFingerData ( evt ) {
var id = evt . identifier !== undefined ? evt . identifier : 0 ;
var f = getFingerData ( id ) ;
f . end . x = evt . pageX ;
f . end . y = evt . pageY ;
return f ;
}
/ * *
* Returns a finger data object by its event ID .
* Each touch event has an identifier property , which is used
* to track repeat touches
* @ param { int } id The unique id of the finger in the sequence of touch events .
* @ return a finger data object .
* @ inner
* /
function getFingerData ( id ) {
for ( var i = 0 ; i < fingerData . length ; i ++ ) {
if ( fingerData [ i ] . identifier == id ) {
return fingerData [ i ] ;
}
}
}
/ * *
* Creats all the finger onjects and returns an array of finger data
* @ return Array of finger objects
* @ inner
* /
function createAllFingerData ( ) {
var fingerData = [ ] ;
for ( var i = 0 ; i <= 5 ; i ++ ) {
fingerData . push ( {
start : { x : 0 , y : 0 } ,
end : { x : 0 , y : 0 } ,
identifier : 0
} ) ;
}
return fingerData ;
}
//
// MATHS / UTILS
//
2013-01-11 18:48:15 +04:00
/ * *
2013-01-23 16:31:04 +04:00
* Calculate the duration of the swipe
* @ return int
* @ inner
2013-01-11 18:48:15 +04:00
* /
function calculateDuration ( ) {
return endTime - startTime ;
}
/ * *
* Calculate the distance between 2 touches ( pinch )
2013-01-23 16:31:04 +04:00
* @ param { point } startPoint A point object containing x and y co - ordinates
* @ param { point } endPoint A point object containing x and y co - ordinates
* @ return int ;
* @ inner
2013-01-11 18:48:15 +04:00
* /
function calculateTouchesDistance ( startPoint , endPoint ) {
var diffX = Math . abs ( startPoint . x - endPoint . x ) ;
var diffY = Math . abs ( startPoint . y - endPoint . y ) ;
return Math . round ( Math . sqrt ( diffX * diffX + diffY * diffY ) ) ;
}
/ * *
* Calculate the zoom factor between the start and end distances
2013-01-23 16:31:04 +04:00
* @ param { int } startDistance Distance ( between 2 fingers ) the user started pinching at
* @ param { int } endDistance Distance ( between 2 fingers ) the user ended pinching at
* @ return float The zoom value from 0 to 1.
* @ inner
2013-01-11 18:48:15 +04:00
* /
function calculatePinchZoom ( startDistance , endDistance ) {
var percent = ( endDistance / startDistance ) * 1 ;
return percent . toFixed ( 2 ) ;
}
/ * *
* Returns the pinch direction , either IN or OUT for the given points
2013-01-23 16:31:04 +04:00
* @ return string Either { @ link $ . fn . swipe . directions . IN } or { @ link $ . fn . swipe . directions . OUT }
* @ see $ . fn . swipe . directions
* @ inner
2013-01-11 18:48:15 +04:00
* /
function calculatePinchDirection ( ) {
if ( pinchZoom < 1 ) {
return OUT ;
}
else {
return IN ;
}
}
/ * *
* Calculate the length / distance of the swipe
2013-01-23 16:31:04 +04:00
* @ param { point } startPoint A point object containing x and y co - ordinates
* @ param { point } endPoint A point object containing x and y co - ordinates
* @ return int
* @ inner
2013-01-11 18:48:15 +04:00
* /
function calculateDistance ( startPoint , endPoint ) {
return Math . round ( Math . sqrt ( Math . pow ( endPoint . x - startPoint . x , 2 ) + Math . pow ( endPoint . y - startPoint . y , 2 ) ) ) ;
}
/ * *
2013-01-23 16:31:04 +04:00
* Calculate the angle of the swipe
* @ param { point } startPoint A point object containing x and y co - ordinates
* @ param { point } endPoint A point object containing x and y co - ordinates
* @ return int
* @ inner
2013-01-11 18:48:15 +04:00
* /
2013-01-23 16:31:04 +04:00
function calculateAngle ( startPoint , endPoint ) {
2013-01-11 18:48:15 +04:00
var x = startPoint . x - endPoint . x ;
var y = endPoint . y - startPoint . y ;
var r = Math . atan2 ( y , x ) ; //radians
var angle = Math . round ( r * 180 / Math . PI ) ; //degrees
//ensure value is positive
if ( angle < 0 ) {
angle = 360 - Math . abs ( angle ) ;
}
return angle ;
}
/ * *
2013-01-23 16:31:04 +04:00
* Calculate the direction of the swipe
* This will also call calculateAngle to get the latest angle of swipe
* @ param { point } startPoint A point object containing x and y co - ordinates
* @ param { point } endPoint A point object containing x and y co - ordinates
* @ return string Either { @ link $ . fn . swipe . directions . LEFT } / { @ link $ . fn . swipe . directions . RIGHT } / { @ link $ . fn . swipe . directions . DOWN } / { @ link $ . fn . swipe . directions . UP }
* @ see $ . fn . swipe . directions
* @ inner
2013-01-11 18:48:15 +04:00
* /
function calculateDirection ( startPoint , endPoint ) {
2013-01-23 16:31:04 +04:00
var angle = calculateAngle ( startPoint , endPoint ) ;
2013-01-11 18:48:15 +04:00
if ( ( angle <= 45 ) && ( angle >= 0 ) ) {
return LEFT ;
} else if ( ( angle <= 360 ) && ( angle >= 315 ) ) {
return LEFT ;
} else if ( ( angle >= 135 ) && ( angle <= 225 ) ) {
return RIGHT ;
} else if ( ( angle > 45 ) && ( angle < 135 ) ) {
return DOWN ;
} else {
return UP ;
}
}
/ * *
* Returns a MS time stamp of the current time
2013-01-23 16:31:04 +04:00
* @ return int
* @ inner
2013-01-11 18:48:15 +04:00
* /
function getTimeStamp ( ) {
var now = new Date ( ) ;
return now . getTime ( ) ;
}
2013-01-23 16:31:04 +04:00
}
2013-01-11 18:48:15 +04:00
2013-01-23 16:31:04 +04:00
/ * *
* A catch all handler that is triggered for all swipe directions .
* @ name $ . fn . swipe # swipe
* @ event
* @ default null
* @ param { EventObject } event The original event object
* @ param { int } direction The direction the user swiped in . See { @ link $ . fn . swipe . directions }
* @ param { int } distance The distance the user swiped
* @ param { int } duration The duration of the swipe in milliseconds
* @ param { int } fingerCount The number of fingers used . See { @ link $ . fn . swipe . fingers }
* /
/ * *
* A handler that is triggered for "left" swipes .
* @ name $ . fn . swipe # swipeLeft
* @ event
* @ default null
* @ param { EventObject } event The original event object
* @ param { int } direction The direction the user swiped in . See { @ link $ . fn . swipe . directions }
* @ param { int } distance The distance the user swiped
* @ param { int } duration The duration of the swipe in milliseconds
* @ param { int } fingerCount The number of fingers used . See { @ link $ . fn . swipe . fingers }
* /
/ * *
* A handler that is triggered for "right" swipes .
* @ name $ . fn . swipe # swipeRight
* @ event
* @ default null
* @ param { EventObject } event The original event object
* @ param { int } direction The direction the user swiped in . See { @ link $ . fn . swipe . directions }
* @ param { int } distance The distance the user swiped
* @ param { int } duration The duration of the swipe in milliseconds
* @ param { int } fingerCount The number of fingers used . See { @ link $ . fn . swipe . fingers }
* /
/ * *
* A handler that is triggered for "up" swipes .
* @ name $ . fn . swipe # swipeUp
* @ event
* @ default null
* @ param { EventObject } event The original event object
* @ param { int } direction The direction the user swiped in . See { @ link $ . fn . swipe . directions }
* @ param { int } distance The distance the user swiped
* @ param { int } duration The duration of the swipe in milliseconds
* @ param { int } fingerCount The number of fingers used . See { @ link $ . fn . swipe . fingers }
* /
/ * *
* A handler that is triggered for "down" swipes .
* @ name $ . fn . swipe # swipeDown
* @ event
* @ default null
* @ param { EventObject } event The original event object
* @ param { int } direction The direction the user swiped in . See { @ link $ . fn . swipe . directions }
* @ param { int } distance The distance the user swiped
* @ param { int } duration The duration of the swipe in milliseconds
* @ param { int } fingerCount The number of fingers used . See { @ link $ . fn . swipe . fingers }
* /
/ * *
* A handler triggered for every phase of the swipe . This handler is constantly fired for the duration of the pinch .
* This is triggered regardless of swipe thresholds .
* @ name $ . fn . swipe # swipeStatus
* @ event
* @ default null
* @ param { EventObject } event The original event object
* @ param { string } phase The phase of the swipe event . See { @ link $ . fn . swipe . phases }
* @ param { string } direction The direction the user swiped in . This is null if the user has yet to move . See { @ link $ . fn . swipe . directions }
* @ param { int } distance The distance the user swiped . This is 0 if the user has yet to move .
* @ param { int } duration The duration of the swipe in milliseconds
* @ param { int } fingerCount The number of fingers used . See { @ link $ . fn . swipe . fingers }
* /
/ * *
* A handler triggered for pinch in events .
* @ name $ . fn . swipe # pinchIn
* @ event
* @ default null
* @ param { EventObject } event The original event object
* @ param { int } direction The direction the user pinched in . See { @ link $ . fn . swipe . directions }
* @ param { int } distance The distance the user pinched
* @ param { int } duration The duration of the swipe in milliseconds
* @ param { int } fingerCount The number of fingers used . See { @ link $ . fn . swipe . fingers }
* @ param { int } zoom The zoom / scale level the user pinched too , 0 - 1.
* /
/ * *
* A handler triggered for pinch out events .
* @ name $ . fn . swipe # pinchOut
* @ event
* @ default null
* @ param { EventObject } event The original event object
* @ param { int } direction The direction the user pinched in . See { @ link $ . fn . swipe . directions }
* @ param { int } distance The distance the user pinched
* @ param { int } duration The duration of the swipe in milliseconds
* @ param { int } fingerCount The number of fingers used . See { @ link $ . fn . swipe . fingers }
* @ param { int } zoom The zoom / scale level the user pinched too , 0 - 1.
* /
/ * *
* A handler triggered for all pinch events . This handler is constantly fired for the duration of the pinch . This is triggered regardless of thresholds .
* @ name $ . fn . swipe # pinchStatus
* @ event
* @ default null
* @ param { EventObject } event The original event object
* @ param { int } direction The direction the user pinched in . See { @ link $ . fn . swipe . directions }
* @ param { int } distance The distance the user pinched
* @ param { int } duration The duration of the swipe in milliseconds
* @ param { int } fingerCount The number of fingers used . See { @ link $ . fn . swipe . fingers }
* @ param { int } zoom The zoom / scale level the user pinched too , 0 - 1.
* /
/ * *
* A click handler triggered when a user simply clicks , rather than swipes on an element .
* @ name $ . fn . swipe # click
* @ event
* @ default null
* @ param { EventObject } event The original event object
* @ param { DomObject } target The element clicked on .
* /
2013-01-11 18:48:15 +04:00
} ) ( jQuery ) ;