Advertisement
NicolasBernier

jgestures.js 0.90 - shake with directional swipe working

Jan 4th, 2014
332
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*jslint undef: true, browser: true, continue: true, eqeq: true, vars: true, forin: true, white: true, newcap: false, nomen: true, plusplus: true, maxerr: 50, indent: 4 */
  2.  
  3. /**
  4.  * jGestures: a jQuery plugin for gesture events
  5.  * Copyright 2010-2011 Neue Digitale / Razorfish GmbH
  6.  * Copyright 2011-2012, Razorfish GmbH
  7.  *
  8.  * Licensed under the Apache License, Version 2.0 (the "License");
  9.  * you may not use this file except in compliance with the License.
  10.  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  *
  17.  * @fileOverview
  18.  * Razorfish GmbH javascript library: add touch events such as 'pinch',
  19.  * 'rotate', 'swipe', 'tap' and 'orientationchange' on capable user agents.
  20.  * For incapable devices there's a basic event substitution: a "tapone" event
  21.  * can be triggered by "clicking", a "swipeone" by performing a swipe-ish
  22.  * gesture using the mouse (buttondown - mousemove - buttonup).
  23.  *
  24.  * This is still a beta version, bugfixes and improvements appreciated.
  25.  *
  26.  * @author martin.krause@razorfish.de
  27.  * @version 0.90-shake
  28.  *
  29.  * @requires
  30.  * jQuery JavaScript Library v1.4.2 - http://jquery.com/
  31.  *  Copyright 2010, John Resig
  32.  *  Dual licensed under the MIT or GPL Version 2 licenses.
  33.  *  http://jquery.org/license
  34.  *
  35.  * @example jQuery('#swipe').bind('swipeone',eventHandler);
  36.  *
  37.  * Notification on native events:
  38.  * On every native touchstart, touchend, gesturestart and gestureend-event,
  39.  * jgestures triggers a corresponding custom event
  40.  * ('jGestures.touchstart', 'jGestures.touchend;start', 'jGestures.touchend;processed',
  41.  * 'jGestures.gesturestart', 'jGestures.gestureend;start', 'jGestures.gestureend;processed') on the event-element.
  42.  * The  eventhandler's second argument represents the original touch event (yes: including all touchpoints).
  43.  * Use this if you need very detailed control e.g. kinetic scrolling or implementing additional gestures.
  44.  *
  45.  * Every jGesture-eventhandler receives a custom object as second argument
  46.  * containing the original event (originalEvent property) and processed
  47.  * information (such as delta values and timesptamp).
  48.  * Example:{
  49.  *              type: eventtype e.g. "swipe","pinch",
  50.  *              originalEvent: {DOM-Event},
  51.  *              // default: just one entry on the delta-array - the first touchpoint
  52.  *              // the first touchpoint is the reference point for every gesture,
  53.  *              // because moving touchpoints in various directions would result in
  54.  *              // a gesture.
  55.  *              // delta and direction details are just provided for touch not for gesture / motion events
  56.  *              delta : [
  57.  *                  {
  58.  *                      lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)
  59.  *                      lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)
  60.  *                      moved: {Number},  // distance: relative to the original touchpoint
  61.  *                      startX: {Number} , // relative to the original touchpoint
  62.  *                      startY: {Number} ,// relative to the original touchpoint
  63.  *                  } ],
  64.  *              // based on the first touchpoint
  65.  *              direction : { // relative to the last touchevent (e.g. touchmove!)
  66.  *                  vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)
  67.  *                  orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)
  68.  *                  lastX : {Number}, // -1,0,+1 || null (orientationchange) // relative to the last touchevent (e.g. touchmove!)
  69.  *                  lastY : {Number}, // -1,0,+1 || null (orientationchange)// relative to the last touchevent (e.g. touchmove!)
  70.  *                  startX: {Number} , // relative to the original touchpoint
  71.  *                  startY: {Number} ,// relative to the original touchpoint
  72.  *                  name  : {String} // name of the direction (left, right, up, down, rightup, leftup, rightdown, leftdown)
  73.  *              },
  74.  *              rotation: {Number} || null, // gestureonly: amount of rotation relative to the current position NOT the original
  75.  *              scale: {Number} || null, // gestureonly: amount of scaling relative to the current position NOT the original
  76.  *              duration: {Number}, // ms: relative to the original touchpoint
  77.  *              description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint
  78.  *          };
  79.  *
  80.  * Available jGesture-events can be grouped into:
  81.  *
  82.  *
  83.  * Device events:
  84.  *  The jGesture-Events in this group are triggered by the device.
  85.  *
  86.  * @event 'orientationchange'
  87.  *      The device is turned clockwise or counterclockwise. This event is triggered
  88.  *      by the device and might use an internal gyroscope.
  89.  *  obj.description:
  90.  *      orientationchange:landscape:clockwise:-90
  91.  *      orientationchange:portrait:default:0
  92.  *      orientationchange:landscape:counterclockwise|portrait:90
  93.  *      orientationchange:portrait:upsidedown:180
  94.  *
  95.  *
  96.  * Move events:
  97.  *  The jGesture-Events in this group are triggered during the touch/gesture
  98.  *  execution whenever a touchpoint changes.
  99.  *  In contrast to touchend/gestureend-events which are triggered after
  100.  *  the touch/gesture has completed.
  101.  *
  102.  * @event 'pinch'
  103.  *      Is triggered during a pinch gesture (two fingers moving away from or
  104.  *      towards each other).
  105.  *  obj.description:
  106.  *      pinch:-1:close
  107.  *      pinch:+1:open
  108.  *
  109.  * @event 'rotate'
  110.  *      Is triggered during a rotation gesture (two fingers rotating clockwise
  111.  *      or counterclockwise).
  112.  *  obj.description:
  113.  *      rotate:-1:counterclockwise
  114.  *      rotate:+1:+clockwise
  115.  *
  116.  * @event 'swipemove'
  117.  *      Is triggered during a swipe move gesture (finger(s) being moved around
  118.  *      the device, e.g. dragging)
  119.  *  obj.description:
  120.  *      swipemove:1:left:down
  121.  *      swipemove:1:left:up
  122.  *      swipemove:1:left:steady
  123.  *      swipemove:1:right:down
  124.  *      swipemove:1:right:up
  125.  *      swipemove:1:right:steady
  126.  *      swipemove:2:left:down
  127.  *      swipemove:2:left:up
  128.  *      swipemove:2:left:steady
  129.  *      swipemove:2:right:down
  130.  *      swipemove:2:right:up
  131.  *      swipemove:2:right:steady
  132.  *      swipemove:2:left:down
  133.  *      swipemove:3:left:up
  134.  *      swipemove:3:left:steady
  135.  *      swipemove:3:right:down
  136.  *      swipemove:3:right:up
  137.  *      swipemove:3:right:steady
  138.  *      swipemove:3:left:down
  139.  *      swipemove:4:left:up
  140.  *      swipemove:4:left:steady
  141.  *      swipemove:4:right:down
  142.  *      swipemove:4:right:up
  143.  *      swipemove:4:right:steady
  144.  *
  145.  *
  146.  * Toucheend events:
  147.  *  The jGesture-Events in this group are triggered after the touch/gesture
  148.  *  has completed.
  149.  *  In contrast to touchmove-events which are triggered during the touch/gesture
  150.  *  execution whenever a touchpoint changes.
  151.  *
  152.  * @event 'swipeone'
  153.  *      Is triggered after a swipe move gesture with one touchpoint (one finger
  154.  *      was moved around the device)
  155.  *  obj.description:
  156.  *      swipeone:1:left:down
  157.  *      swipeone:1:left:up
  158.  *      swipeone:1:left:steady
  159.  *      swipeone:1:right:down
  160.  *      swipeone:1:right:up
  161.  *      swipeone:1:right:steady
  162.  *
  163.  * @event 'swipetwo'
  164.  *      Is triggered after a swipe move gesture with two touchpoints (two fingers
  165.  *      were moved around the device)
  166.  *  obj.description:
  167.  *      swipetwo:2:left:down
  168.  *      swipetwo:2:left:up
  169.  *      swipetwo:2:left:steady
  170.  *      swipetwo:2:right:down
  171.  *      swipetwo:2:right:up
  172.  *      swipetwo:2:right:steady
  173.  *
  174.  * @event 'swipethree'
  175.  *      Is triggered after a swipe move gesture with three touchpoints (three
  176.  *      fingers were moved around the device)
  177.  *  obj.description:
  178.  *      swipethree:3:left:down
  179.  *      swipethree:3:left:up
  180.  *      swipethree:3:left:steady
  181.  *      swipethree:3:right:down
  182.  *      swipethree:3:right:up
  183.  *      swipethree:3:right:steady
  184.  *
  185.  * @event 'swipefour'
  186.  *      Is triggered after a swipe move gesture with four touchpoints (four
  187.  *      fingers were moved around the device)
  188.  *  obj.description:
  189.  *      swipefour:4:left:down
  190.  *      swipefour:4:left:up
  191.  *      swipefour:4:left:steady
  192.  *      swipefour:4:right:down
  193.  *      swipefour:4:right:up
  194.  *      swipefour:4:right:steady
  195.  *
  196.  *
  197.  * @event 'swipeup'
  198.  *      Is triggered after an  strict upwards swipe move gesture
  199.  *  obj.description:
  200.  *      swipe:1:steady:up
  201.  *      swipe:2:steady:up
  202.  *      swipe:3:steady:up
  203.  *      swipe:4:steady:up
  204.  *
  205.  * @event 'swiperightup'
  206.  *      Is triggered after a rightwards and upwards swipe move gesture
  207.  *  obj.description:
  208.  *      swipe:1:right:up
  209.  *      swipe:2:right:up
  210.  *      swipe:3:right:up
  211.  *      swipe:4:right:up
  212.  *
  213.  * @event 'swiperight'
  214.  *      Is triggered after a  strict rightwards swipe move gesture
  215.  *  obj.description:
  216.  *      swipe:1:right:steady
  217.  *      swipe:2:right:steady
  218.  *      swipe:3:right:steady
  219.  *      swipe:4:right:steady
  220.  *
  221.  * @event 'swiperightdown'
  222.  *      Is triggered after a rightwards and downwards swipe move gesture
  223.  *  obj.description:
  224.  *      swipe:1:right:down
  225.  *      swipe:2:right:down
  226.  *      swipe:3:right:down
  227.  *      swipe:4:right:down
  228.  *
  229.  * @event 'swipedown'
  230.  *      Is triggered after a  strict downwards swipe move gesture
  231.  *  obj.description:
  232.  *      swipe:1:steady:down
  233.  *      swipe:2:steady:down
  234.  *      swipe:3:steady:down
  235.  *      swipe:4:steady:down
  236.  *
  237.  * @event 'swipeleftdown'
  238.  *      Is triggered after a leftwards and downwards swipe move gesture
  239.  *  obj.description:
  240.  *      swipe:1:left:down
  241.  *      swipe:2:left:down
  242.  *      swipe:3:left:down
  243.  *      swipe:4:left:down
  244.  *
  245.  * @event 'swipeleft'
  246.  *      Is triggered after a strict leftwards swipe move gesture
  247.  *  obj.description:
  248.  *      swipe:1:left:steady
  249.  *      swipe:2:left:steady
  250.  *      swipe:3:left:steady
  251.  *      swipe:4:left:steady
  252.  *
  253.  * @event 'swipeleftup'
  254.  *      Is triggered after a leftwards and upwards swipe move gesture
  255.  *  obj.description:
  256.  *      swipe:1:left:up
  257.  *      swipe:2:left:up
  258.  *      swipe:3:left:up
  259.  *      swipe:4:left:up
  260.  *
  261.  * @event 'tapone'
  262.  *      Is triggered after a single (one finger) tap gesture
  263.  *  obj.description:
  264.  *      tapone
  265.  *
  266.  * @event 'taptwo'
  267.  *      Is triggered after a double (two finger) tap gesture
  268.  *  obj.description:
  269.  *      taptwo
  270.  * *
  271.  * @event 'tapthree'
  272.  *      Is triggered after a tripple (three finger) tap gesture
  273.  *  obj.description:
  274.  *      tapthree
  275.  *
  276.  *
  277.  * Gestureend events:
  278.  *  A gesture is an interpretation of different touchpoints.
  279.  *  The jGesture-Events in this group are triggered when a gesture has finished
  280.  *  and the touchpoints are removed from the device.
  281.  *
  282.  * @event 'pinchopen'
  283.  *      Is triggered when a pinchopen gesture (two fingers moving away from each
  284.  *      other) occured and the touchpoints (fingers) are removed the device.
  285.  *  obj.description:
  286.  *      pinch:+1:open
  287.  *
  288.  * @event 'pinchclose'
  289.  *      Is triggered when a pinchclose gesture (two fingers moving towards each
  290.  *      other) occured and the touchpoints (fingers) are removed the device.
  291.  *  obj.description:
  292.  *      pinch:-1:close
  293.  *
  294.  * @event 'rotatecw'
  295.  *      Is triggered when a clockwise rotation gesture (two fingers rotating
  296.  *      clockwise) occured and the touchpoints (fingers) are removed the device.
  297.  *  obj.description:
  298.  *      rotate:+1:+clockwise
  299.  *
  300.  * @event 'rotateccw'
  301.  *      Is triggered when a counterclockwise rotation gesture (two fingers
  302.  *      rotating counterclockwise) occured and the touchpoints (fingers) are
  303.  *      removed the device.
  304.  *  obj.description:
  305.  *      rotate:-1:+counterclockwise
  306.  *
  307.  *
  308.  * Motion events:
  309.  *  A "motion event" is an interpretation of changes in space, e.g. a "shaking motion"
  310.  *  consists of a specified number of acceleration changes in a given interval.
  311.  * For understanding "directions", place your mobile device on a table with the bottom
  312.  * (home button) close to you:
  313.  *  - x-axis: horizontal left / right
  314.  *  - y-axis: horizontal front / back (through the home button)
  315.  *  - z-axis: vertical through your device
  316.  *
  317.  *  Note: Devicemotion / deviceorientation don't send custom event (such as: jGestures.touchstart).
  318.  *  Note: Devicemotion should be bound on the "window-element" - because the whole device moves
  319.  *
  320.  * @event 'shake'
  321.  *      Is triggered when a shaking motion is detected
  322.  *  obj.description:
  323.  *      shake:leftright:x-axisfrontback:y-axis:updown:z-axis
  324.  *
  325.  * @event 'shakefrontback'
  326.  *      Is triggered when a shaking motion is detected and the gesture can be interpreted as a mainly front-back movement.
  327.   * obj.description:
  328.  *      shakefrontback:shakefrontback:y-axis
  329.  *
  330.  * @event 'shakeleftright'
  331.  *      Is triggered when a shaking motion is detected and the gesture can be interpreted as a mainly left-right movement.
  332.  *      Additional major movements are mentioned in the obj.description.
  333.  *  obj.description:
  334.  *      shakeleftright:leftright:x-axis
  335.  *
  336.  * @event 'shakeupdown'
  337.  *      Is triggered when a shaking motion is detected and the gesture can be interpreted as a mainly up-down movement.
  338.  *      Additional major movements are mentioned in the obj.description.
  339.  *  obj.description:
  340.  *      shake:shakeupdown:updown:z-axis
  341.  *
  342.  * @example
  343.  *      .bind( eventType, [ eventData ], handler(eventObject) )
  344.  * jQuery('body').bind('tapone',function(){alert(arguments[1].description);})
  345.  *
  346.  */
  347.  
  348.  (function($) {
  349.  
  350.     /**
  351.     * General thresholds.
  352.     */
  353.     // @TODO: move to $...defaults
  354.     // @TODO: shake to defaults freeze etc
  355.     // change of x deg in y ms
  356.  
  357.  
  358.     $.jGestures = {};
  359.     $.jGestures.defaults = {};
  360.     $.jGestures.defaults.thresholdShake =  {
  361.         requiredShakes : 10,
  362.         freezeShakes: 100,
  363.         frontback : {
  364.             sensitivity: 10
  365.          },
  366.         leftright : {
  367.             sensitivity: 10
  368.         },
  369.         updown : {
  370.             sensitivity: 10
  371.         }
  372.     };
  373.  
  374.     $.jGestures.defaults.thresholdPinchopen = 0.05;
  375.     $.jGestures.defaults.thresholdPinchmove = 0.05;
  376.     $.jGestures.defaults.thresholdPinch = 0.05;
  377.     $.jGestures.defaults.thresholdPinchclose = 0.05;
  378.     $.jGestures.defaults.thresholdRotatecw = 5; //deg
  379.     $.jGestures.defaults.thresholdRotateccw = 5; // deg
  380.     // a tap becomes a swipe if x/y values changes are above this threshold
  381.     $.jGestures.defaults.thresholdMove = 20;
  382.     $.jGestures.defaults.thresholdSwipe = 100;
  383.     // get capable user agents
  384.     $.jGestures.data = {};
  385.     $.jGestures.data.capableDevicesInUserAgentString = ['iPad','iPhone','iPod','Mobile Safari']; // basic functionality such as swipe, pinch, rotate, tap should work on every mobile safari, e.g. GalaxyTab
  386.     $.jGestures.data.hasGestures = (function () { var _i; for(_i = 0; _i < $.jGestures.data.capableDevicesInUserAgentString.length; _i++ ) {  if (navigator.userAgent.indexOf($.jGestures.data.capableDevicesInUserAgentString[_i]) !== -1 ) {return true;} } return false; } )();
  387.     $.hasGestures = $.jGestures.data.hasGestures;
  388.     $.jGestures.events = {
  389.         touchstart : 'jGestures.touchstart',
  390.         touchendStart: 'jGestures.touchend;start',
  391.         touchendProcessed: 'jGestures.touchend;processed',
  392.         gesturestart: 'jGestures.gesturestart',
  393.         gestureendStart: 'jGestures.gestureend;start',
  394.         gestureendProcessed: 'jGestures.gestureend;processed'
  395.     };
  396.  
  397.     jQuery
  398.         .each({
  399.             // "first domevent necessary"_"touch event+counter" : "exposed as"
  400.             // event: orientationchange
  401.             orientationchange_orientationchange01: "orientationchange",
  402.             // event: gestures
  403.             gestureend_pinchopen01: "pinchopen",
  404.             gestureend_pinchclose01: "pinchclose",
  405.             gestureend_rotatecw01 : 'rotatecw',
  406.             gestureend_rotateccw01 : 'rotateccw',
  407.             // move events
  408.             gesturechange_pinch01: 'pinch',
  409.             gesturechange_rotate01: 'rotate',
  410.             touchstart_swipe13: 'swipemove',
  411.             // event: touches
  412.             touchstart_swipe01: "swipeone",
  413.             touchstart_swipe02: "swipetwo",
  414.             touchstart_swipe03: "swipethree",
  415.             touchstart_swipe04: "swipefour",
  416.             touchstart_swipe05: 'swipeup',
  417.             touchstart_swipe06: 'swiperightup',
  418.             touchstart_swipe07: 'swiperight',
  419.             touchstart_swipe08: 'swiperightdown',
  420.             touchstart_swipe09: 'swipedown',
  421.             touchstart_swipe10: 'swipeleftdown',
  422.             touchstart_swipe11: 'swipeleft',
  423.             touchstart_swipe12: 'swipeleftup',
  424.             touchstart_tap01: 'tapone',
  425.             touchstart_tap02: 'taptwo',
  426.             touchstart_tap03: 'tapthree',
  427.             touchstart_tap04: 'tapfour',
  428.  
  429.             devicemotion_shake01: 'shake',
  430.             devicemotion_shake02: 'shakefrontback',
  431.             devicemotion_shake03: 'shakeleftright',
  432.             devicemotion_shake04: 'shakeupdown'
  433.  
  434.         },
  435.  
  436.         /**
  437.         * Add gesture events inside the jQuery.event.special namespace
  438.         */
  439.         function( sInternal_, sPublicFN_ ) {
  440.  
  441.             // add as funciton to jQuery.event.special.sPublicFN_
  442.             jQuery.event.special[ sPublicFN_ ] = {
  443.  
  444.                 /**
  445.                 * When the first event handler is bound, jQuery executes the setup function.
  446.                 * This plugin just uses one eventhandler per element, regardless of the number of bound events.
  447.                 * All Events are stored internally as properties on the dom-element using the $.data api.
  448.                 * The setup-function adds the eventlistener, acting as a proxy function for the internal events.
  449.                 * $.data.ojQueryGestures[_sDOMEvent ('tap') ] = {Boolean}
  450.                 * @return {Void}
  451.                 */
  452.                 setup: function () {
  453.                     // split the arguments to necessary controll arguements
  454.                     var _aSplit = sInternal_.split('_');
  455.                     var _sDOMEvent = _aSplit[0]; //
  456.                     // get the associated gesture event and strip the counter: necessary for distinguisihng similliar events such as tapone-tapfour
  457.                     var _sGestureEvent = _aSplit[1].slice(0,_aSplit[1].length-2);
  458.                     var _$element = jQuery(this);
  459.                     var _oDatajQueryGestures ;
  460.                     var oObj;
  461.                     // bind the event handler on the first $.bind() for a gestureend-event, set marker
  462.                     if (!_$element.data('ojQueryGestures') || !_$element.data('ojQueryGestures')[_sDOMEvent])  {
  463.                         // setup pseudo event
  464.                         _oDatajQueryGestures = _$element.data('ojQueryGestures') || {};
  465.                         oObj = {};
  466.                         // marker for:  domEvent being set on this element
  467.                         // e.g.: $.data.oGestureInternals['touchstart'] = true;
  468.                         // since they're grouped, i'm just marking the first one being added
  469.                         oObj[_sDOMEvent] = true;
  470.                         $.extend(true,_oDatajQueryGestures,oObj);
  471.                         _$element.data('ojQueryGestures' ,_oDatajQueryGestures);
  472.                         // add gesture events
  473.                         if($.hasGestures) {
  474.                             switch(_sGestureEvent) {
  475.  
  476.                                 // event: orientationchange
  477.                                 case 'orientationchange':
  478.                                     _$element.get(0).addEventListener('orientationchange', _onOrientationchange, false);
  479.                                 break;
  480.  
  481.                                 // event:
  482.                                 // - shake
  483.                                 // - tilt
  484.                                 case 'shake':
  485.                                 case 'shakefrontback':
  486.                                 case 'shakeleftright':
  487.                                 case 'shakeupdown':
  488.                                 case 'tilt':
  489.                                     //$.hasGyroscope = true //!window.DeviceOrientationEvent;
  490.                                     //_$element.get(0).addEventListener('devicemotion', _onDevicemotion, false);
  491.                                     //_$element.get(0).addEventListener('deviceorientation', _onDeviceorientation, false);
  492.                                     _$element.get(0).addEventListener('devicemotion', _onDevicemotion, false);
  493.                                 break;
  494.  
  495.                                 // event:
  496.                                 // - touchstart
  497.                                 // - touchmove
  498.                                 // - touchend
  499.                                 case 'tap':
  500.                                 case 'swipe':
  501.                                 case 'swipeup':
  502.                                 case 'swiperightup':
  503.                                 case 'swiperight':
  504.                                 case 'swiperightdown':
  505.                                 case 'swipedown':
  506.                                 case 'swipeleftdown':
  507.                                 case 'swipeleft':
  508.                                     _$element.get(0).addEventListener('touchstart', _onTouchstart, false);
  509.                                 break;
  510.  
  511.                                 // event: gestureend
  512.                                 case 'pinchopen':
  513.                                 case 'pinchclose' :
  514.                                 case 'rotatecw' :
  515.                                 case 'rotateccw' :
  516.                                     _$element.get(0).addEventListener('gesturestart', _onGesturestart, false);
  517.                                     _$element.get(0).addEventListener('gestureend', _onGestureend, false);
  518.                                 break;
  519.  
  520.                                 // event: gesturechange
  521.                                 case 'pinch':
  522.                                 case 'rotate':
  523.                                     _$element.get(0).addEventListener('gesturestart', _onGesturestart, false);
  524.                                     _$element.get(0).addEventListener('gesturechange', _onGesturechange, false);
  525.                                 break;
  526.                             }
  527.                         }
  528.                         // create substitute for gesture events
  529.                         else {
  530.                             switch(_sGestureEvent) {
  531.                                 // event substitutes:
  532.                                 // - touchstart: mousedown
  533.                                 // - touchmove: none
  534.                                 // - touchend: mouseup
  535.                                 case 'tap':
  536.                                 case 'swipe':
  537.                                     // _$element.get(0).addEventListener('mousedown', _onTouchstart, false);
  538.                                      _$element.bind('mousedown', _onTouchstart);
  539.                                 break;
  540.  
  541.                                 // no substitution
  542.                                 case 'orientationchange':
  543.                                 case 'pinchopen':
  544.                                 case 'pinchclose' :
  545.                                 case 'rotatecw' :
  546.                                 case 'rotateccw' :
  547.                                 case 'pinch':
  548.                                 case 'rotate':
  549.                                 case 'shake':
  550.                                 case 'tilt':
  551.  
  552.                                 break;
  553.                             }
  554.                         }
  555.  
  556.                     }
  557.                     return false;
  558.                 },
  559.  
  560.                 /**
  561.                 * For every $.bind(GESTURE) the add-function will be called.
  562.                 * Instead of binding an actual eventlister, the event is stored as $.data on the element.
  563.                 * The handler will be triggered using $.triggerHandler(GESTURE) if the internal
  564.                 * eventhandler (proxy being bound on setup()) detects a GESTURE event
  565.                 * @param {Object} event_ jQuery-Event-Object being passed by $.bind()
  566.                 * @return {Void}
  567.                 */
  568.                 add : function(event_) {
  569.                     // add pseudo event: properties on $.data
  570.                     var _$element = jQuery(this);
  571.                     var _oDatajQueryGestures = _$element.data('ojQueryGestures');
  572. //                  _oDatajQueryGestures[event_.type] = { 'originalType' : event_.type , 'threshold' : event_.data.threshold, 'preventDefault' : event_.data.preventDefault } ;
  573.                     _oDatajQueryGestures[event_.type] = { 'originalType' : event_.type } ;
  574.                     return false;
  575.                 },
  576.  
  577.                 /**
  578.                 * For every $.unbind(GESTURE) the remove-function will be called.
  579.                 * Instead of removing the actual eventlister, the event is removed from $.data on the element.
  580.                 * @param {Object} event_ jQuery-Event-Object being passed by $.bind()
  581.                 * @return {Void}
  582.                 */
  583.                 remove : function(event_) {
  584.                     // remove pseudo event: properties on $.data
  585.                     var _$element = jQuery(this);
  586.                     var _oDatajQueryGestures = _$element.data('ojQueryGestures');
  587.                     _oDatajQueryGestures[event_.type] = false;
  588.                     _$element.data('ojQueryGestures' ,_oDatajQueryGestures );
  589.                     return false;
  590.                 },
  591.  
  592.                 /**
  593.                 * The last $.unbind()-call on the domElement triggers the teardown function
  594.                 * removing the eventlistener
  595.                 * @return {Void}
  596.                 */
  597.                 // @TODO: maybe rework teardown to work with event type?!
  598.                 teardown : function() {
  599.                     // split the arguments to necessary controll arguements
  600.                     var _aSplit = sInternal_.split('_');
  601.                     var _sDOMEvent = _aSplit[0]; //
  602.                     // get the associated gesture event and strip the counter: necessary for distinguisihng similliar events such as tapone-tapfour
  603.                     var _sGestureEvent = _aSplit[1].slice(0,_aSplit[1].length-2);
  604.                     var _$element = jQuery(this);
  605.                     var _oDatajQueryGestures;
  606.                     var oObj;
  607.                     // bind the event handler on the first $.bind() for a gestureend-event, set marker
  608.                     if (!_$element.data('ojQueryGestures') || !_$element.data('ojQueryGestures')[_sDOMEvent])  {
  609.                         // setup pseudo event
  610.                         _oDatajQueryGestures = _$element.data('ojQueryGestures') || {};
  611.                         oObj = {};
  612.                         // remove marker for:  domEvent being set on this element
  613.                         oObj[_sDOMEvent] = false;
  614.                         $.extend(true,_oDatajQueryGestures,oObj);
  615.                         _$element.data('ojQueryGestures' ,_oDatajQueryGestures);
  616.  
  617.                         // remove gesture events
  618.                         if($.hasGestures) {
  619.                             switch(_sGestureEvent) {
  620.  
  621.                                 // event: orientationchange
  622.                                 case 'orientationchange':
  623.                                     _$element.get(0).removeEventListener('orientationchange', _onOrientationchange, false);
  624.                                 break;
  625.  
  626.                                 case 'shake':
  627.                                 case 'shakefrontback':
  628.                                 case 'shakeleftright':
  629.                                 case 'shakeupdown':
  630.                                 case 'tilt':
  631.                                     _$element.get(0).removeEventListener('devicemotion', _onDevicemotion, false);
  632.                                 break;
  633.  
  634.                                 // event :
  635.                                 // - touchstart
  636.                                 // - touchmove
  637.                                 // - touchend
  638.                                 case 'tap':
  639.                                 case 'swipe':
  640.                                 case 'swipeup':
  641.                                 case 'swiperightup':
  642.                                 case 'swiperight':
  643.                                 case 'swiperightdown':
  644.                                 case 'swipedown':
  645.                                 case 'swipeleftdown':
  646.                                 case 'swipeleft':
  647.                                 case 'swipeleftup':
  648.                                     _$element.get(0).removeEventListener('touchstart', _onTouchstart, false);
  649.                                     _$element.get(0).removeEventListener('touchmove', _onTouchmove, false);
  650.                                     _$element.get(0).removeEventListener('touchend', _onTouchend, false);
  651.                                 break;
  652.  
  653.                                 // event: gestureend
  654.                                 case 'pinchopen':
  655.                                 case 'pinchclose' :
  656.                                 case 'rotatecw' :
  657.                                 case 'rotateccw' :
  658.                                     _$element.get(0).removeEventListener('gesturestart', _onGesturestart, false);
  659.                                     _$element.get(0).removeEventListener('gestureend', _onGestureend, false);
  660.                                 break;
  661.  
  662.                                 // event: gesturechange
  663.                                 case 'pinch':
  664.                                 case 'rotate':
  665.                                     _$element.get(0).removeEventListener('gesturestart', _onGesturestart, false);
  666.                                     _$element.get(0).removeEventListener('gesturechange', _onGesturechange, false);
  667.                                 break;
  668.                             }
  669.                         }
  670.                         // remove substitute for gesture events
  671.                         else {
  672.                             switch(_sGestureEvent) {
  673.                                 // event substitutes:
  674.                                 // - touchstart: mousedown
  675.                                 // - touchmove: none
  676.                                 // - touchend: mouseup
  677.                                 case 'tap':
  678.                                 case 'swipe':
  679. //                                  _$element.get(0).removeEventListener('mousedown', _onTouchstart, false);
  680. //                                  _$element.get(0).removeEventListener('mousemove', _onTouchmove, false);
  681. //                                  _$element.get(0).removeEventListener('mouseup', _onTouchend, false);
  682.                                     _$element.unbind('mousedown', _onTouchstart);
  683.                                     _$element.unbind('mousemove', _onTouchmove);
  684.                                     _$element.unbind('mouseup', _onTouchend);
  685.                                 break;
  686.  
  687.                                 // no substitution
  688.                                 case 'orientationchange':
  689.                                 case 'pinchopen':
  690.                                 case 'pinchclose' :
  691.                                 case 'rotatecw' :
  692.                                 case 'rotateccw' :
  693.                                 case 'pinch':
  694.                                 case 'rotate':
  695.                                 case 'shake':
  696.                                 case 'tilt':
  697.  
  698.                                 break;
  699.                             }
  700.                         }
  701.  
  702.                     }
  703.                 return false;
  704.                 }
  705.  
  706.             };
  707.         });
  708.  
  709.     /**
  710.     * Creates the object that ist passed as second argument to the $element.triggerHandler function.
  711.     * This object contains detailed informations about the gesture event.
  712.     * @param {Object} oOptions_  {type: {String}, touches: {String}, deltaY: {String},deltaX : {String}, startMove: {Object}, event:{DOM-Event}, timestamp:{String},vector: {Number}}
  713.     * @example _createOptions (
  714.     *               {
  715.     *                   type: 'swipemove',
  716.     *                   touches: '1',
  717.     *                   deltaY: _iDeltaY,
  718.     *                   deltaX : _iDeltaX,
  719.     *                   startMove: _oDatajQueryGestures.oStartTouch,
  720.     *                   event:event_,
  721.     *                   timestamp:_oEventData.timestamp,
  722.     *                   vector: -1
  723.     *               }
  724.     *           );
  725.     * @returns {Object}
  726.     *           {
  727.     *               type: eventtype e.g. "swipe","pinch",
  728.     *               originalEvent: {DOM-Event},
  729.     *               // default: just one entry on the delta-array - the first touchpoint
  730.     *               // the first touchpoint is the reference point for every gesture,
  731.     *               // because moving touchpoints in various directions would result in
  732.     *               // a gesture.
  733.     *               // delta and direction details are just provided for touch not for gesture / motion events
  734.     *               delta : [
  735.     *                   {
  736.     *                       lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)
  737.     *                       lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)
  738.     *                       moved: {Number},  // distance: relative to the original touchpoint
  739.     *                       startX: {Number} , // relative to the original touchpoint
  740.     *                       startY: {Number} ,// relative to the original touchpoint
  741.     *                   } ],
  742.     *               // based on the first touchpoint
  743.     *               direction : { // relative to the last touchevent (e.g. touchmove!)
  744.     *                   vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)
  745.     *                   orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)
  746.     *                   lastX : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)
  747.     *                   lastY : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)
  748.     *                   startX: {Number} , //-1,0,+1 relative to the original touchpoint
  749.     *                   startY: {Number} ,// -1,0,+1 relative to the original touchpoint
  750.  *                  name  : {String} // name of the direction (left, right, up, down, rightup, leftup, rightdown, leftdown)
  751.     *               },
  752.     *               rotation: {Number} || null, // gestureonly: amount of rotation relative to the current position NOT the original
  753.     *               scale: {Number} || null, // gestureonly: amount of scaling relative to the current position NOT the original
  754.     *               duration: {Number}, // ms: relative to the original touchpoint
  755.     *               description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint
  756.     *           };
  757.     */
  758.     function _createOptions(oOptions_) {
  759.         // force properties
  760.         oOptions_.startMove = (oOptions_.startMove) ? oOptions_.startMove : {startX: null,startY:null,timestamp:null}  ;
  761.         var _iNow = new Date().getTime();
  762.         var _oDirection;
  763.         var _oDelta;
  764.         // calculate touch differences
  765.         if (oOptions_.touches) {
  766.             // store delta values
  767.             _oDelta = [
  768.                 {
  769.                     lastX: oOptions_.deltaX ,
  770.                     lastY: oOptions_.deltaY,
  771.                     moved: null,
  772.                     startX:  oOptions_.screenX - oOptions_.startMove.screenX ,
  773.                     startY: oOptions_.screenY - oOptions_.startMove.screenY
  774.                 }
  775.             ];
  776.  
  777.             _oDirection =  {
  778.                 vector: oOptions_.vector || null,
  779.                 orientation : window.orientation || null,
  780.                 lastX : ((_oDelta[0].lastX > 0) ? +1 : ( (_oDelta[0].lastX < 0) ? -1 : 0 ) ),
  781.                 lastY : ((_oDelta[0].lastY > 0) ? +1 : ( (_oDelta[0].lastY < 0) ? -1 : 0 ) ),
  782.                 startX : ((_oDelta[0].startX > 0) ? +1 : ( (_oDelta[0].startX < 0) ? -1 : 0 ) ),
  783.                 startY : ((_oDelta[0].startY > 0) ? +1 : ( (_oDelta[0].startY < 0) ? -1 : 0 ) )
  784.             };
  785.  
  786.             // calculate distance traveled using the pythagorean theorem
  787.             _oDelta[0].moved =  Math.sqrt(Math.pow(Math.abs(_oDelta[0].startX), 2) + Math.pow(Math.abs(_oDelta[0].startY), 2));
  788.            
  789.             // determine direction name
  790.             var x = _oDelta[0].lastX,
  791.                     y = _oDelta[0].lastY;
  792.                     direction = null;
  793.        
  794.             if (x == 0 || y/x <= -2 || y/x >= 2) {
  795.                 if (y > 0)
  796.                     direction = 'down';
  797.                 else if (y < 0)
  798.                     direction = 'up';
  799.             }
  800.             else if (y == 0 || x/y <= -2 || x/y >= 2) {
  801.                 if (x > 0)
  802.                     direction = 'right';
  803.                 else if (x < 0)
  804.                     direction = 'left';
  805.             }
  806.             else if (0.5 < y/x && y/x < 2) {
  807.                 if (y > 0)
  808.                     direction = 'rightdown';
  809.                 else if (y < 0)
  810.                     direction = 'leftup';
  811.             }          
  812.             else if (-2 < y/x && y/x < -0.5) {
  813.                 if (y > 0)
  814.                     direction = 'leftdown';
  815.                 else if (y < 0)
  816.                     direction = 'rightup';
  817.             }          
  818.            
  819.             _oDirection.name = direction;
  820.         }
  821.         return {
  822.             type: oOptions_.type || null,
  823.             originalEvent: oOptions_.event || null,
  824.             delta : _oDelta  || null,
  825.             direction : _oDirection || { orientation : window.orientation || null, vector: oOptions_.vector || null},
  826.             duration: (oOptions_.duration) ? oOptions_.duration : ( oOptions_.startMove.timestamp ) ? _iNow - oOptions_.timestamp : null,
  827.             rotation: oOptions_.rotation || null,
  828.             scale: oOptions_.scale || null,
  829.             description : oOptions_.description || [
  830.                 oOptions_.type,
  831.                 ':',
  832.                 oOptions_.touches,
  833.                 ':',
  834.                 ((_oDelta[0].lastX != 0) ? ((_oDelta[0].lastX > 0) ? 'right' : 'left') : 'steady'),
  835.                 ':',
  836.                 ((_oDelta[0].lastY != 0) ? ( (_oDelta[0].lastY > 0) ? 'down' : 'up') :'steady')
  837.                 ].join('')
  838.         };
  839.  
  840.     }
  841.  
  842.  
  843.  
  844.     /**
  845.     * DOM-event handlers
  846.     */
  847.  
  848.     /**
  849.     * Handler: orientationchange
  850.     * Triggers the bound orientationchange handler on the window element
  851.     * The "orientationchange" handler will receive an object with additional information
  852.     * about the event.
  853.     *  {
  854.     *   direction : {
  855.     *       orientation: {-90|0|90|180}
  856.     *   },
  857.     *   description : [
  858.     *       'orientationchange:{landscape:clockwise:|portrait:default|landscape:counterclockwise|portrait:upsidedown}:{-90|0|90|180}' // e.g. 'orientation:landscape:clockwise:-90
  859.     *   }
  860.     * @param {DOM-Event} event_
  861.     * @return {Void}
  862.     */
  863.     function _onOrientationchange(event_) {
  864.  
  865.         // window.orientation: -90,0,90,180
  866.         var _aDict = ['landscape:clockwise:','portrait:default:','landscape:counterclockwise:','portrait:upsidedown:'];
  867.  
  868.         $(window).triggerHandler('orientationchange',
  869.             {
  870.                 direction : {orientation: window.orientation},
  871.                 description : [
  872.                     'orientationchange:',
  873.                     _aDict[( (window.orientation / 90) +1)],
  874.                     window.orientation
  875.                     ].join('')
  876.             });
  877.     }
  878.  
  879.  
  880.     /**
  881.     * Handler: devicemotion
  882.     * Calculates "motion events" such as shake, tilt, wiggle by observing "changes in space"
  883.     * For understanding "directions", place your mobile device on a table with the bottom
  884.     * (home button) close to you:
  885.     *  - x-axis: horizontal left / right
  886.     *  - y-axis: horizontal front / back (through the home button)
  887.     *  - z-axis: vertical through your device
  888.     * @param {DOM-Event} event_
  889.     * @returns {Object}
  890.     *           {
  891.     *               type: eventtype e.g. "shake",
  892.     *               originalEvent: {DOM-Event},
  893.     *               // delta and direction details are just provided for touch not for gesture / motion events
  894.     *               delta : null,
  895.     *               direction :{
  896.     *                   vector: null,
  897.     *                   orientation: -90,0,90,180 || null (window.orienntation)
  898.     *               }
  899.     *               rotation: {Number} , //  amount of rotation relative to the current position NOT the original
  900.     *               scale: {Number} , // amount of scaling relative to the current position NOT the original
  901.     *               duration: {Number}, // ms: duration of the motion
  902.     *               description : {String} // details as String: pinch:{'close'|'open'} e.g. "pinch:-1:close" ||  rotate:{'counterclockwise'|'clockwise'} e.g. "rotate:-1:counterclockwise"
  903.     *           };
  904.     * @param {DOM-Event} event_
  905.     * @return {Void}
  906.     */
  907.     function _onDevicemotion(event_) {
  908.  
  909.         var _sType;
  910.         var _$element = jQuery(window);
  911.         //var _bHasGyroscope = $.hasGyroscope;
  912.  
  913.         // skip custom notification: devicemotion is triggered every 0.05s regardlesse of any gesture
  914.  
  915.         // get options
  916.         var _oDatajQueryGestures = _$element.data('ojQueryGestures');
  917.  
  918.         var _oThreshold = $.jGestures.defaults.thresholdShake;
  919.  
  920.         // get last position or set initital values
  921.         var _oLastDevicePosition = _oDatajQueryGestures.oDeviceMotionLastDevicePosition || {
  922.             accelerationIncludingGravity : {
  923.                 x: 0,
  924.                 y: 0,
  925.                 z: 0
  926.             },
  927.             shake : {
  928.                 eventCount: 0,
  929.                 intervalsPassed: 0,
  930.                 intervalsFreeze: 0
  931.             },
  932.             shakeleftright : {
  933.                 eventCount: 0,
  934.                 intervalsPassed: 0,
  935.                 intervalsFreeze: 0
  936.             },
  937.             shakefrontback : {
  938.                 eventCount: 0,
  939.                 intervalsPassed: 0,
  940.                 intervalsFreeze: 0
  941.             },
  942.             shakeupdown : {
  943.                 eventCount: 0,
  944.                 intervalsPassed: 0,
  945.                 intervalsFreeze: 0
  946.             }
  947.         };
  948.  
  949.         // cache current values
  950.         var _oCurrentDevicePosition = {
  951.             accelerationIncludingGravity : {
  952.                 x: event_.accelerationIncludingGravity.x,
  953.                 y: event_.accelerationIncludingGravity.y,
  954.                 z: event_.accelerationIncludingGravity.z
  955.             },
  956.             shake: {
  957.                 eventCount: _oLastDevicePosition.shake.eventCount,
  958.                 intervalsPassed: _oLastDevicePosition.shake.intervalsPassed,
  959.                 intervalsFreeze: _oLastDevicePosition.shake.intervalsFreeze
  960.              },
  961.              shakeleftright: {
  962.                 eventCount: _oLastDevicePosition.shakeleftright.eventCount,
  963.                 intervalsPassed: _oLastDevicePosition.shakeleftright.intervalsPassed,
  964.                 intervalsFreeze: _oLastDevicePosition.shakeleftright.intervalsFreeze
  965.              },
  966.              shakefrontback: {
  967.                 eventCount: _oLastDevicePosition.shakefrontback.eventCount,
  968.                 intervalsPassed: _oLastDevicePosition.shakefrontback.intervalsPassed,
  969.                 intervalsFreeze: _oLastDevicePosition.shakefrontback.intervalsFreeze
  970.              },
  971.              shakeupdown: {
  972.                 eventCount: _oLastDevicePosition.shakeupdown.eventCount,
  973.                 intervalsPassed: _oLastDevicePosition.shakeupdown.intervalsPassed,
  974.                 intervalsFreeze: _oLastDevicePosition.shakeupdown.intervalsFreeze
  975.              }
  976.  
  977.         };
  978.  
  979.  
  980.         // options
  981.         var _aType;
  982.         var _aDescription;
  983.         var _oObj;
  984.  
  985.  
  986.         // trigger events for all bound pseudo events on this element
  987.         for (_sType in _oDatajQueryGestures) {
  988.             // get current pseudo event
  989.  
  990.  
  991.             // trigger bound events on this element
  992.             switch(_sType) {
  993.  
  994.                 case 'shake':
  995.                 case 'shakeleftright':
  996.                 case 'shakefrontback':
  997.                 case 'shakeupdown':
  998.  
  999.                     // options
  1000.                     _aType = [];
  1001.                     _aDescription = [];
  1002.  
  1003.                     _aType.push(_sType);
  1004.  
  1005.                     // freeze shake - prevent multiple shake events on one  shaking motion (user won't stop shaking immediately)
  1006.                     if (++_oCurrentDevicePosition[_sType].intervalsFreeze > _oThreshold.freezeShakes && _oCurrentDevicePosition[_sType].intervalsFreeze < (2*_oThreshold.freezeShakes) ) { break;   }
  1007.  
  1008.                     // set control values
  1009.                     _oCurrentDevicePosition[_sType].intervalsFreeze  = 0;
  1010.                     _oCurrentDevicePosition[_sType].intervalsPassed++;
  1011.  
  1012.                     // check for shaking motions: massive acceleration changes in every direction
  1013.                     if ( ( _sType === 'shake' ||_sType === 'shakeleftright' ) && ( _oCurrentDevicePosition.accelerationIncludingGravity.x > _oThreshold.leftright.sensitivity  || _oCurrentDevicePosition.accelerationIncludingGravity.x < (-1* _oThreshold.leftright.sensitivity) ) ) {
  1014.                         _aType.push('leftright');
  1015.                         _aType.push('x-axis');
  1016.                     }
  1017.  
  1018.                     if ( ( _sType === 'shake' ||_sType === 'shakefrontback' ) && (_oCurrentDevicePosition.accelerationIncludingGravity.y > _oThreshold.frontback.sensitivity  || _oCurrentDevicePosition.accelerationIncludingGravity.y < (-1 * _oThreshold.frontback.sensitivity) ) ) {
  1019.                         _aType.push('frontback');
  1020.                         _aType.push('y-axis');
  1021.                     }
  1022.  
  1023.                     if ( ( _sType === 'shake' ||_sType === 'shakeupdown' ) && ( _oCurrentDevicePosition.accelerationIncludingGravity.z+9.81 > _oThreshold.updown.sensitivity  || _oCurrentDevicePosition.accelerationIncludingGravity.z+9.81 < (-1 * _oThreshold.updown.sensitivity) ) ) {
  1024.                         _aType.push('updown');
  1025.                         _aType.push('z-axis');
  1026.                     }
  1027.  
  1028.                     // at least one successful shaking event
  1029.                     if (_aType.length > 1) {
  1030.                         // minimum number of shaking motions during  the defined "time" (messured by events - device event interval: 0.05s)
  1031.                         if (++_oCurrentDevicePosition[_sType].eventCount == _oThreshold.requiredShakes && (_oCurrentDevicePosition[_sType].intervalsPassed) < _oThreshold.freezeShakes ) {
  1032.                             // send event
  1033.                             _$element.triggerHandler(_sType, _createOptions ({type: _sType, description: _aType.join(':'), event:event_,duration:_oCurrentDevicePosition[_sType].intervalsPassed*5 }) );
  1034.                             // reset
  1035.                             _oCurrentDevicePosition[_sType].eventCount = 0;
  1036.                             _oCurrentDevicePosition[_sType].intervalsPassed = 0;
  1037.                             // freeze shake
  1038.                             _oCurrentDevicePosition[_sType].intervalsFreeze = _oThreshold.freezeShakes+1;
  1039.                         }
  1040.                         // too slow, reset
  1041.                         else if (_oCurrentDevicePosition[_sType].eventCount == _oThreshold.requiredShakes && (_oCurrentDevicePosition[_sType].intervalsPassed) > _oThreshold.freezeShakes ) {
  1042.                             _oCurrentDevicePosition[_sType].eventCount = 0 ;
  1043.                             _oCurrentDevicePosition[_sType].intervalsPassed = 0;
  1044.                         }
  1045.                     }
  1046.                 break;
  1047.  
  1048.             }
  1049.  
  1050.             // refresh pseudo events
  1051.             _oObj = {};
  1052.             _oObj.oDeviceMotionLastDevicePosition = _oCurrentDevicePosition;
  1053.             _$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));
  1054.  
  1055.         }
  1056.     }
  1057.  
  1058.  
  1059.     /**
  1060.     * Handler: touchstart or mousedown
  1061.     * Setup pseudo-event by storing initial values such as :
  1062.     *   screenX : {Number}
  1063.     *   screenY : {Number}
  1064.     *   timestamp: {Number}
  1065.     *  on the pseudo gesture event and
  1066.     *  sets up additional eventlisteners for handling touchmove events.
  1067.     * @param {DOM-Event} event_
  1068.     * @return {Void}
  1069.     */
  1070.     function _onTouchstart(event_) {
  1071.  
  1072.         // ignore bubbled handlers
  1073.         // if ( event_.currentTarget !== event_.target ) { return; }
  1074.  
  1075.         var _$element = jQuery(event_.currentTarget);
  1076.         // var _$element = jQuery(event_.target);
  1077.  
  1078.         // trigger custom notification
  1079.         _$element.triggerHandler($.jGestures.events.touchstart,event_);
  1080.  
  1081.  
  1082.         // set the necessary touch events
  1083.         if($.hasGestures) {
  1084.             event_.currentTarget.addEventListener('touchmove', _onTouchmove, false);
  1085.             event_.currentTarget.addEventListener('touchend', _onTouchend, false);
  1086.         }
  1087.         // event substitution
  1088.         else {
  1089. //          event_.currentTarget.addEventListener('mousemove', _onTouchmove, false);
  1090. //          event_.currentTarget.addEventListener('mouseup', _onTouchend, false);
  1091.             _$element.bind('mousemove', _onTouchmove);
  1092.             _$element.bind('mouseup', _onTouchend);
  1093.         }
  1094.  
  1095.         // get stored pseudo event
  1096.         var _oDatajQueryGestures = _$element.data('ojQueryGestures');
  1097.  
  1098.         // var _oEventData = _oDatajQueryGestures[_sType];
  1099.         var _eventBase = (event_.touches) ? event_.touches[0] : event_;
  1100.         // store current values for calculating relative values (changes between touchmoveevents)
  1101.         var _oObj = {};
  1102.         _oObj.oLastSwipemove = { screenX : _eventBase.screenX, screenY : _eventBase.screenY, timestamp:new Date().getTime()};
  1103.         _oObj.oStartTouch = { screenX : _eventBase.screenX, screenY : _eventBase.screenY, timestamp:new Date().getTime()};
  1104.  
  1105.         _$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));
  1106.     }
  1107.  
  1108.  
  1109.     /**
  1110.     * Handler: touchmove or mousemove
  1111.     * Calculates the x/y changes since the last event,
  1112.     * compares it to $.jGestures.defaults.thresholdMove and triggers
  1113.     * an swipemove event if the distance exceed the
  1114.     * threshold.
  1115.     * Custom-event argument object:
  1116.     * {Object}
  1117.     *           {
  1118.     *               type: e.g. 'swipemove',
  1119.     *               ≈: {DOM-Event},
  1120.     *               // default: just one entry on the delta-array - the first touchpoint
  1121.     *               // the first touchpoint is the reference point for every gesture,
  1122.     *               // because moving touchpoints in various directions would result in
  1123.     *               // a gesture.
  1124.     *               // delta and direction details are just provided for touch not for gesture / motion events
  1125.     *               delta : [
  1126.     *                   {
  1127.     *                       lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)
  1128.     *                       lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)
  1129.     *                       moved: {Number},  // distance: relative to the original touchpoint
  1130.     *                       startX: {Number} , // relative to the original touchpoint
  1131.     *                       startY: {Number} ,// relative to the original touchpoint
  1132.     *                   } ],
  1133.     *               // based on the first touchpoint
  1134.     *               direction : { // relative to the last touchevent (e.g. touchmove!)
  1135.     *                   vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)
  1136.     *                   orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)
  1137.     *                   lastX : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)
  1138.     *                   lastY : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)
  1139.     *                   startX: {Number} , //-1,0,+1 relative to the original touchpoint
  1140.     *                   startY: {Number} ,// -1,0,+1 relative to the original touchpoint
  1141.     *               },
  1142.     *               rotation: null, // gestureonly: amount of rotation relative to the current position NOT the original
  1143.     *               scale: null, // gestureonly: amount of scaling relative to the current position NOT the original
  1144.     *               duration: {Number}, // ms: relative to the original touchpoint
  1145.     *               description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint
  1146.     *           };
  1147.     *
  1148.     * @param {DOM-Event} event_
  1149.     * @return {Void}
  1150.     */
  1151.     function _onTouchmove(event_) {
  1152.  
  1153.         var _$element = jQuery(event_.currentTarget);
  1154.         // var _$element = jQuery(event_.target);
  1155.  
  1156.         // get stored pseudo event
  1157.         var _oDatajQueryGestures = _$element.data('ojQueryGestures');
  1158.  
  1159.         var _bHasTouches = !!event_.touches;
  1160.         var _iScreenX = (_bHasTouches) ? event_.changedTouches[0].screenX : event_.screenX;
  1161.         var _iScreenY = (_bHasTouches) ? event_.changedTouches[0].screenY : event_.screenY;
  1162.  
  1163.         //relative to the last event
  1164.         var _oEventData = _oDatajQueryGestures.oLastSwipemove;
  1165.         var _iDeltaX = _iScreenX - _oEventData.screenX   ;
  1166.         var _iDeltaY = _iScreenY - _oEventData.screenY;
  1167.  
  1168.         var _oDetails;
  1169.  
  1170.             // there's a swipemove set (not the first occurance), trigger event
  1171.         if (!!_oDatajQueryGestures.oLastSwipemove) {
  1172.             // check
  1173.             _oDetails = _createOptions({type: 'swipemove', touches: (_bHasTouches) ? event_.touches.length: '1', screenY: _iScreenY,screenX:_iScreenX ,deltaY: _iDeltaY,deltaX : _iDeltaX, startMove:_oEventData, event:event_, timestamp:_oEventData.timestamp});
  1174.             _$element.triggerHandler(_oDetails.type,_oDetails);
  1175.         }
  1176.         // store the new values
  1177.         var _oObj = {};
  1178.         var _eventBase = (event_.touches) ? event_.touches[0] : event_;
  1179.         _oObj.oLastSwipemove = { screenX : _eventBase.screenX, screenY : _eventBase.screenY, timestamp:new Date().getTime()};
  1180.         _$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));
  1181.     }
  1182.  
  1183.  
  1184.     /**
  1185.     * Handler: touchend or mouseup
  1186.     * Removes the additional handlers (move/end)
  1187.     * Calculates the x/y changes since the touchstart event
  1188.     * not in relation to the last move event.
  1189.     * Triggers the
  1190.     *   swipeone|swipetwo|swipethree|swipefour|
  1191.     *   swipeup|swiperightup|swiperight|swiperightdown|swipedown|
  1192.     *   swipeleftdown|swipeleft|swipeleftup|
  1193.     *   tapone|taptwo|tapthree|tapfour
  1194.     * event.
  1195.     *       {Object}
  1196.     *           {
  1197.     *               type: eventtype e.g. "swipeone","swipeleftdown",
  1198.     *               originalEvent: {DOM-Event},
  1199.     *               // default: just one entry on the delta-array - the first touchpoint
  1200.     *               // the first touchpoint is the reference point for every gesture,
  1201.     *               // because moving touchpoints in various directions would result in
  1202.     *               // a gesture.
  1203.     *               // delta and direction details are just provided for touch not for gesture / motion events
  1204.     *               delta : [
  1205.     *                   {
  1206.     *                       lastX:{Number} , // x-axis: relative to the last touchevent (e.g. touchmove!)
  1207.     *                       lastY:{Number}, // y-axis: relative to the last touchevent (e.g. touchmove!)
  1208.     *                       moved: {Number},  // distance: relative to the original touchpoint
  1209.     *                       startX: {Number} , // relative to the original touchpoint
  1210.     *                       startY: {Number} ,// relative to the original touchpoint
  1211.     *                   } ],
  1212.     *               // based on the first touchpoint
  1213.     *               direction : { // relative to the last touchevent (e.g. touchmove!)
  1214.     *                   vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)
  1215.     *                   orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)
  1216.     *                   lastX : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)
  1217.     *                   lastY : {Number}, // -1,0,+1 relative to the last touchevent (e.g. touchmove!)
  1218.     *                   startX: {Number} , //-1,0,+1 relative to the original touchpoint
  1219.     *                   startY: {Number} ,// -1,0,+1 relative to the original touchpoint
  1220.     *               },
  1221.     *               rotation: null,
  1222.     *               scale: null ,
  1223.     *               duration: {Number}, // ms: relative to the original touchpoint
  1224.     *               description : {String} // details as String: {TYPE *}:{TOUCHES 1|2|3|4}:{X-AXIS 'right'|'left'|'steady'}:{Y-AXIS 'down'|'up'|'steady'} e.g. "swipe:1:left:steady" relative to the last touchpoint
  1225.     *           };
  1226.     * @param {DOM-Event} event_
  1227.     * @return {Void}
  1228.     */
  1229.     function _onTouchend(event_) {
  1230.  
  1231.         // ignore bubbled handlers
  1232.         // if ( event_.currentTarget !== event_.target ) { return; }
  1233.  
  1234.         var _$element = jQuery(event_.currentTarget);
  1235.         var _bHasTouches = !!event_.changedTouches;
  1236.         var _iTouches = (_bHasTouches) ? event_.changedTouches.length : '1';
  1237.         var _iScreenX = (_bHasTouches) ? event_.changedTouches[0].screenX : event_.screenX;
  1238.         var _iScreenY = (_bHasTouches) ? event_.changedTouches[0].screenY : event_.screenY;
  1239.  
  1240.         // trigger custom notification
  1241.         _$element.triggerHandler($.jGestures.events.touchendStart,event_);
  1242.  
  1243.         // var _$element = jQuery(event_.target);
  1244.         // remove events
  1245.         if($.hasGestures) {
  1246.             event_.currentTarget.removeEventListener('touchmove', _onTouchmove, false);
  1247.             event_.currentTarget.removeEventListener('touchend', _onTouchend, false);
  1248.         }
  1249.         // event substitution
  1250.         else {
  1251. //          event_.currentTarget.removeEventListener('mousemove', _onTouchmove, false);
  1252. //          event_.currentTarget.removeEventListener('mouseup', _onTouchend, false);
  1253.             _$element.unbind('mousemove', _onTouchmove);
  1254.             _$element.unbind('mouseup', _onTouchend);
  1255.         }
  1256.         // get all bound pseudo events
  1257.         var _oDatajQueryGestures = _$element.data('ojQueryGestures');
  1258.  
  1259.         // if the current change on the x/y position is above the defined threshold for moving an element set the moved flag
  1260.         // to distinguish between a moving gesture and a shaking finger trying to tap
  1261.         var _bHasMoved = (
  1262.             Math.abs(_oDatajQueryGestures.oStartTouch.screenX - _iScreenX) > $.jGestures.defaults.thresholdMove ||
  1263.             Math.abs(_oDatajQueryGestures.oStartTouch.screenY - _iScreenY) > $.jGestures.defaults.thresholdMove
  1264.         ) ? true : false;
  1265.  
  1266.         // if the current change on the x/y position is above the defined threshold for swiping set the moved flag
  1267.         // to indicate we're dealing with a swipe gesture
  1268.         var _bHasSwipeGesture = (
  1269.             Math.abs(_oDatajQueryGestures.oStartTouch.screenX - _iScreenX) > $.jGestures.defaults.thresholdSwipe ||
  1270.             Math.abs(_oDatajQueryGestures.oStartTouch.screenY - _iScreenY) > $.jGestures.defaults.thresholdSwipe
  1271.         ) ? true : false;
  1272.  
  1273.  
  1274.         var _sType;
  1275.         var _oEventData ;
  1276.  
  1277.         var _oDelta;
  1278.  
  1279.         // calculate distances in relation to the touchstart position not the last touchmove event!
  1280.         var _iDeltaX;
  1281.         var _iDeltaY;
  1282.         var _oDetails;
  1283.  
  1284.         var _aDict = ['zero','one','two','three','four'];
  1285.  
  1286.         // swipe marker
  1287.         var _bIsSwipe;
  1288.  
  1289.  
  1290.         // trigger events for all bound pseudo events on this element
  1291.         for (_sType in _oDatajQueryGestures) {
  1292.  
  1293.             // get current pseudo event
  1294.             _oEventData = _oDatajQueryGestures.oStartTouch;
  1295.  
  1296.             _oDelta = {};
  1297.             _iScreenX = (_bHasTouches) ? event_.changedTouches[0].screenX : event_.screenX;
  1298.             _iScreenY = (_bHasTouches) ? event_.changedTouches[0].screenY : event_.screenY;
  1299.             // calculate distances in relation to the touchstart position not the last touchmove event!
  1300.             _iDeltaX = _iScreenX - _oEventData.screenX ;
  1301.             _iDeltaY = _iScreenY - _oEventData.screenY;
  1302.             _oDetails = _createOptions({type: 'swipe', touches: _iTouches, screenY: _iScreenY,screenX:_iScreenX ,deltaY: _iDeltaY,deltaX : _iDeltaX, startMove:_oEventData, event:event_, timestamp:  _oEventData.timestamp });
  1303.  
  1304.  
  1305.             // swipe marker
  1306.             _bIsSwipe = false;
  1307.  
  1308.             // trigger bound events on this element
  1309.             switch(_sType) {
  1310.                 case 'swipeone':
  1311.                 case 'swipetwo':
  1312.                 case 'swipethree':
  1313.                 case 'swipefour':
  1314.                 case 'swipeup':
  1315.                 case 'swiperightup':
  1316.                 case 'swiperight':
  1317.                 case 'swiperightdown':
  1318.                 case 'swipedown':
  1319.                 case 'swipeleftdown':
  1320.                 case 'swipeleft':
  1321.                 case 'swipeleftup':            
  1322.  
  1323.                     if( _bHasTouches === false && _iTouches >= 1 && _bHasMoved === false){
  1324.                         // trigger tap!
  1325.                         break;
  1326.                     }
  1327.                     if (_bHasTouches===false || ( _iTouches >= 1  && _bHasMoved === true && _bHasSwipeGesture===true)) {
  1328.                         _bIsSwipe = true;
  1329.  
  1330.                         // trigger simple swipe                    
  1331.                         _oDetails.type = ['swipe',_aDict[_iTouches]].join('');
  1332.                        
  1333.                         if (_oDetails.type == _sType) {
  1334.                             _$element.triggerHandler(_oDetails.type,_oDetails);
  1335.                             break;
  1336.                         }
  1337.                            
  1338.                         // trigger directional swipe
  1339.                         if (_oDetails.direction.name !== null) {
  1340.                             _oDetails.type = 'swipe' + _oDetails.direction.name;
  1341.                        
  1342.                             if (_oDetails.type == _sType)                      
  1343.                                 _$element.triggerHandler(_oDetails.type,_oDetails);
  1344.                         }
  1345.                     }
  1346.                 break;
  1347.                
  1348.                 case 'tapone':
  1349.                 case 'taptwo':
  1350.                 case 'tapthree':
  1351.                 case 'tapfour':
  1352.                     if (( /* _bHasTouches && */ _bHasMoved !== true && _bIsSwipe !==true) && (_aDict[_iTouches] ==_sType.slice(3)) ) {
  1353.                         _oDetails.description = ['tap',_aDict[_iTouches]].join('');
  1354.                         _oDetails.type = ['tap',_aDict[_iTouches]].join('');
  1355.                        
  1356.                         if (_oDetails.type == _sType)                          
  1357.                             _$element.triggerHandler(_oDetails.type,_oDetails);
  1358.                         }
  1359.                     break;
  1360.  
  1361.             }
  1362.  
  1363.             // refresh pseudo events
  1364.             var _oObj = {};
  1365. //          _oObj[_sType] = false;
  1366. //          _oObj.hasTouchmoved = false;
  1367.             _$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));
  1368.             _$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));
  1369.  
  1370.         }
  1371.         _$element.triggerHandler($.jGestures.events.touchendProcessed,event_);
  1372.     }
  1373.  
  1374.  
  1375.     /**
  1376.     * Handler: gesturestart
  1377.     * Setup pseudo-event by storing initial values such as :
  1378.     *   timestamp: {Number}
  1379.     *  on the pseudo gesture event
  1380.     * Since the gesture-event doesn't supply event.touches no tuchpoints will be calculated
  1381.     * @param {DOM-Event} event_
  1382.     * @return {Void}
  1383.     */
  1384.     function _onGesturestart(event_) {
  1385.  
  1386.         // ignore bubbled handlers
  1387.         // if ( event_.currentTarget !== event_.target ) { return; }
  1388.  
  1389.         var _$element = jQuery(event_.currentTarget);
  1390.         // var _$element = jQuery(event_.target);
  1391.  
  1392.         // trigger custom notification
  1393.         _$element.triggerHandler($.jGestures.events.gesturestart,event_);
  1394.  
  1395.  
  1396.         // get stored pseudo event
  1397.         var _oDatajQueryGestures = _$element.data('ojQueryGestures');
  1398.  
  1399.         // var _oEventData = _oDatajQueryGestures[_sType];
  1400.         // store current values for calculating relative values (changes between touchmoveevents)
  1401.         var _oObj = {};
  1402.         _oObj.oStartTouch = {timestamp:new Date().getTime()};
  1403.         _$element.data('ojQueryGestures',$.extend(true,_oDatajQueryGestures,_oObj));
  1404.     }
  1405.  
  1406.     /**
  1407.     * Handler: gesturechange
  1408.     * Read the event_.scale / event_.rotate values,
  1409.     * an triggers a pinch|rotate event if necessary.
  1410.     * Since the gesture-event doesn't supply event.touches no tuchpoints will be calculated
  1411.     * @returns {Object}
  1412.     *           {
  1413.     *               type: eventtype e.g. "pinch","rotate",
  1414.     *               originalEvent: {DOM-Event},
  1415.     *               // delta and direction details are just provided for touch not for gesture / motion events
  1416.     *               delta : null,
  1417.     *               direction : {
  1418.     *                   vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)
  1419.     *                    orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)
  1420.     *                },
  1421.     *               rotation: {Number} , //  amount of rotation relative to the current position NOT the original
  1422.     *               scale: {Number} , // amount of scaling relative to the current position NOT the original
  1423.     *               duration: {Number}, // ms: relative to the original touchpoint
  1424.     *               description : {String} // details as String: pinch:{'close'|'open'} e.g. "pinch:-1:close" ||  rotate:{'counterclockwise'|'clockwise'} e.g. "rotate:-1:counterclockwise"
  1425.     *           };
  1426.     * @param {DOM-Event} event_
  1427.     * @return {Void}
  1428.     */
  1429.     function _onGesturechange(event_) {
  1430.  
  1431.         // ignore bubbled handlers
  1432.         // if ( event_.currentTarget !== event_.target ) { return; }
  1433.  
  1434.         var _$element = jQuery(event_.currentTarget);
  1435.         // var _$element = jQuery(event_.target);
  1436.         var _iDelta,_iDirection,_sDesc,_oDetails;
  1437.         // get all pseudo events
  1438.         var _oDatajQueryGestures = _$element.data('ojQueryGestures');
  1439.  
  1440.         // trigger events for all bound pseudo events on this element
  1441.         var _sType;
  1442.         for (_sType in _oDatajQueryGestures) {
  1443.  
  1444.             // trigger a specific bound event
  1445.             switch(_sType) {
  1446.  
  1447.                 case 'pinch':
  1448.                     _iDelta = event_.scale;
  1449.                     if ( ( ( _iDelta < 1 ) && (_iDelta % 1) < (1 - $.jGestures.defaults.thresholdPinchclose) ) || ( ( _iDelta > 1 ) && (_iDelta % 1) > ($.jGestures.defaults.thresholdPinchopen) ) ) {
  1450.                         _iDirection = (_iDelta < 1 ) ? -1 : +1 ;
  1451.                         _oDetails = _createOptions({type: 'pinch', scale: _iDelta, touches: null,startMove:_oDatajQueryGestures.oStartTouch, event:event_, timestamp: _oDatajQueryGestures.oStartTouch.timestamp, vector:_iDirection, description: ['pinch:',_iDirection,':' , ( (_iDelta < 1 ) ? 'close' : 'open' )].join('') });
  1452.                         _$element.triggerHandler(_oDetails.type, _oDetails);
  1453.                     }
  1454.                 break;
  1455.  
  1456.                 case 'rotate':
  1457.                     _iDelta = event_.rotation;
  1458.                     if ( ( ( _iDelta < 1 ) &&  ( -1*(_iDelta) > $.jGestures.defaults.thresholdRotateccw ) ) || ( ( _iDelta > 1 ) && (_iDelta  > $.jGestures.defaults.thresholdRotatecw) ) ) {
  1459.                         _iDirection = (_iDelta < 1 ) ? -1 : +1 ;
  1460.                         _oDetails = _createOptions({type: 'rotate', rotation: _iDelta, touches: null, startMove:_oDatajQueryGestures.oStartTouch, event:event_, timestamp: _oDatajQueryGestures.oStartTouch.timestamp, vector:_iDirection, description: ['rotate:',_iDirection,':' , ( (_iDelta < 1 ) ? 'counterclockwise' : 'clockwise' )].join('') });
  1461.                         _$element.triggerHandler(_oDetails.type, _oDetails);
  1462.                     }
  1463.                 break;
  1464.  
  1465.             }
  1466.         }
  1467.  
  1468.     }
  1469.  
  1470.  
  1471.     /**
  1472.     * Handler: gestureend
  1473.     * Read the event_.scale / event_.rotate values,
  1474.     * compares it to $.jGestures.defaults.threshold* and triggers
  1475.     * a pinchclose|pinchclose|rotatecw|rotateccw event if the distance exceed the
  1476.     * Since the gesture-event doesn't supply event.touches no tuchpoints will be calculated
  1477.     * * Custom-event argument object:
  1478.     * @returns {Object}
  1479.     *           {
  1480.     *               type: eventtype e.g. "pinchclose","pinchopen", "rotatecw", "rotateccw",
  1481.     *               originalEvent: {DOM-Event},
  1482.     *               // delta and direction details are just provided for touch not for gesture / motion events
  1483.     *               delta : null,
  1484.     *               // based on the first touchpoint
  1485.     *               direction : {
  1486.     *                   vector: {Number}, // -1|+1, indicates the direction if necessary(pinch/rotate)
  1487.     *                   orientation: {Number} // window.orientation: -90,0,90,180 || null (window.orienntation)
  1488.     *               },
  1489.     *               rotation: {Number} , //  amount of rotation relative to the current position NOT the original
  1490.     *               scale: {Number} , // amount of scaling relative to the current position NOT the original
  1491.     *               duration: {Number}, // ms: relative to the original touchpoint
  1492.     *               description : {String} // details as String: pinch:{'close'|'open'} e.g. "pinch:-1:close" ||  rotate:{'counterclockwise'|'clockwise'} e.g. "rotate:-1:counterclockwise"
  1493.     *           };
  1494.     * @param {DOM-Event} event_
  1495.     * @return {Void}
  1496.     */
  1497.     function _onGestureend(event_) {
  1498.         // ignore bubbled handlers
  1499.         // if ( event_.currentTarget !== event_.target ) { return; }
  1500.  
  1501.         var _$element = jQuery(event_.currentTarget);
  1502.         // var _$element = jQuery(event_.target);
  1503.  
  1504.         // trigger custom notification
  1505.         _$element.triggerHandler($.jGestures.events.gestureendStart,event_);
  1506.  
  1507.         var _iDelta;
  1508.         var _oDatajQueryGestures = _$element.data('ojQueryGestures');
  1509.  
  1510.         // trigger handler for every bound event
  1511.         var _sType;
  1512.         for (_sType in _oDatajQueryGestures) {
  1513.  
  1514.             switch(_sType) {
  1515.  
  1516.                 case 'pinchclose':
  1517.                     _iDelta = event_.scale;
  1518.                     if (( _iDelta < 1 ) && (_iDelta % 1) < (1 - $.jGestures.defaults.thresholdPinchclose)) {
  1519.                         _$element.triggerHandler('pinchclose', _createOptions ({type: 'pinchclose', scale:_iDelta, vector: -1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event:event_, timestamp:_oDatajQueryGestures.oStartTouch.timestamp,description: 'pinch:-1:close' }) );
  1520.                     }
  1521.                 break;
  1522.  
  1523.                 case 'pinchopen':
  1524.                     _iDelta = event_.scale;
  1525.                     if ( ( _iDelta > 1 ) && (_iDelta % 1) > ($.jGestures.defaults.thresholdPinchopen) ) {
  1526.                         _$element.triggerHandler('pinchopen', _createOptions ({type: 'pinchopen', scale:_iDelta, vector: +1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event:event_, timestamp:_oDatajQueryGestures.oStartTouch.timestamp,description: 'pinch:+1:open'}) );
  1527.                     }
  1528.                 break;
  1529.  
  1530.                 case 'rotatecw':
  1531.                     _iDelta = event_.rotation;
  1532.                     if ( ( _iDelta > 1 ) && (_iDelta  > $.jGestures.defaults.thresholdRotatecw) ) {
  1533.                         _$element.triggerHandler('rotatecw', _createOptions ({type: 'rotatecw', rotation:_iDelta, vector: +1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event:event_, timestamp:_oDatajQueryGestures.oStartTouch.timestamp,description: 'rotate:+1:clockwise'}) );
  1534.                     }
  1535.                 break;
  1536.  
  1537.                 case 'rotateccw':
  1538.                     _iDelta = event_.rotation;
  1539.                     if ( ( _iDelta < 1 ) &&  ( -1*(_iDelta) > $.jGestures.defaults.thresholdRotateccw ) ) {
  1540.                             _$element.triggerHandler('rotateccw', _createOptions ({type: 'rotateccw', rotation:_iDelta, vector: -1, touches: null, startMove: _oDatajQueryGestures.oStartTouch, event:event_, timestamp:_oDatajQueryGestures.oStartTouch.timestamp,description: 'rotate:-1:counterclockwise'}) );
  1541.                         }
  1542.                 break;
  1543.  
  1544.                 }
  1545.             }
  1546.             _$element.triggerHandler($.jGestures.events.gestureendProcessed,event_);
  1547.         }
  1548.     }
  1549. )(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement