Project

General

Profile

1
/*! UIkit 2.27.5 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
2
//  Based on Zeptos touch.js
3
//  https://raw.github.com/madrobby/zepto/master/src/touch.js
4
//  Zepto.js may be freely distributed under the MIT license.
5

    
6
;(function($){
7

    
8
  if ($.fn.swipeLeft) {
9
    return;
10
  }
11

    
12

    
13
  var touch = {}, touchTimeout, tapTimeout, swipeTimeout, longTapTimeout, longTapDelay = 750, gesture;
14
  var hasTouchEvents = 'ontouchstart' in window,
15
      hasPointerEvents = window.PointerEvent,
16
      hasTouch = hasTouchEvents
17
      || window.DocumentTouch && document instanceof DocumentTouch
18
      || navigator.msPointerEnabled && navigator.msMaxTouchPoints > 0 // IE 10
19
      || navigator.pointerEnabled && navigator.maxTouchPoints > 0; // IE >=11
20

    
21
  function swipeDirection(x1, x2, y1, y2) {
22
    return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down');
23
  }
24

    
25
  function longTap() {
26
    longTapTimeout = null;
27
    if (touch.last) {
28
      if ( touch.el !== undefined ) touch.el.trigger('longTap');
29
      touch = {};
30
    }
31
  }
32

    
33
  function cancelLongTap() {
34
    if (longTapTimeout) clearTimeout(longTapTimeout);
35
    longTapTimeout = null;
36
  }
37

    
38
  function cancelAll() {
39
    if (touchTimeout)   clearTimeout(touchTimeout);
40
    if (tapTimeout)     clearTimeout(tapTimeout);
41
    if (swipeTimeout)   clearTimeout(swipeTimeout);
42
    if (longTapTimeout) clearTimeout(longTapTimeout);
43
    touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null;
44
    touch = {};
45
  }
46

    
47
  function isPrimaryTouch(event){
48
    return event.pointerType == event.MSPOINTER_TYPE_TOUCH && event.isPrimary;
49
  }
50

    
51
  $(function(){
52
    var now, delta, deltaX = 0, deltaY = 0, firstTouch;
53

    
54
    if ('MSGesture' in window) {
55
      gesture = new MSGesture();
56
      gesture.target = document.body;
57
    }
58

    
59
    $(document)
60
      .on('MSGestureEnd gestureend', function(e){
61

    
62
        var swipeDirectionFromVelocity = e.originalEvent.velocityX > 1 ? 'Right' : e.originalEvent.velocityX < -1 ? 'Left' : e.originalEvent.velocityY > 1 ? 'Down' : e.originalEvent.velocityY < -1 ? 'Up' : null;
63

    
64
        if (swipeDirectionFromVelocity && touch.el !== undefined) {
65
          touch.el.trigger('swipe');
66
          touch.el.trigger('swipe'+ swipeDirectionFromVelocity);
67
        }
68
      })
69
      // MSPointerDown: for IE10
70
      // pointerdown: for IE11
71
      .on('touchstart MSPointerDown pointerdown', function(e){
72

    
73
        if(e.type == 'MSPointerDown' && !isPrimaryTouch(e.originalEvent)) return;
74

    
75
        firstTouch = (e.type == 'MSPointerDown' || e.type == 'pointerdown') ? e : e.originalEvent.touches[0];
76

    
77
        now      = Date.now();
78
        delta    = now - (touch.last || now);
79
        touch.el = $('tagName' in firstTouch.target ? firstTouch.target : firstTouch.target.parentNode);
80

    
81
        if(touchTimeout) clearTimeout(touchTimeout);
82

    
83
        touch.x1 = firstTouch.pageX;
84
        touch.y1 = firstTouch.pageY;
85

    
86
        if (delta > 0 && delta <= 250) touch.isDoubleTap = true;
87

    
88
        touch.last = now;
89
        longTapTimeout = setTimeout(longTap, longTapDelay);
90

    
91
        // adds the current touch contact for IE gesture recognition
92
        if (e.originalEvent && e.originalEvent.pointerId && gesture && ( e.type == 'MSPointerDown' || e.type == 'pointerdown' || e.type == 'touchstart' ) ) {
93
          gesture.addPointer(e.originalEvent.pointerId);
94
        }
95

    
96
      })
97
      // MSPointerMove: for IE10
98
      // pointermove: for IE11
99
      .on('touchmove MSPointerMove pointermove', function(e){
100

    
101
        if (e.type == 'MSPointerMove' && !isPrimaryTouch(e.originalEvent)) return;
102

    
103
        firstTouch = (e.type == 'MSPointerMove' || e.type == 'pointermove') ? e : e.originalEvent.touches[0];
104

    
105
        cancelLongTap();
106
        touch.x2 = firstTouch.pageX;
107
        touch.y2 = firstTouch.pageY;
108

    
109
        deltaX += Math.abs(touch.x1 - touch.x2);
110
        deltaY += Math.abs(touch.y1 - touch.y2);
111
      })
112
      // MSPointerUp: for IE10
113
      // pointerup: for IE11
114
      .on('touchend MSPointerUp pointerup', function(e){
115

    
116
        if (e.type == 'MSPointerUp' && !isPrimaryTouch(e.originalEvent)) return;
117

    
118
        cancelLongTap();
119

    
120
        // swipe
121
        if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) || (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)){
122

    
123
          swipeTimeout = setTimeout(function() {
124
            if ( touch.el !== undefined ) {
125
              touch.el.trigger('swipe');
126
              touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)));
127
            }
128
            touch = {};
129
          }, 0);
130

    
131
        // normal tap
132
        } else if ('last' in touch) {
133

    
134
          // don't fire tap when delta position changed by more than 30 pixels,
135
          // for instance when moving to a point and back to origin
136
          if (isNaN(deltaX) || (deltaX < 30 && deltaY < 30)) {
137
            // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
138
            // ('tap' fires before 'scroll')
139
            tapTimeout = setTimeout(function() {
140

    
141
              // trigger universal 'tap' with the option to cancelTouch()
142
              // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
143
              var event = $.Event('tap');
144
              event.cancelTouch = cancelAll;
145
              if ( touch.el !== undefined ) touch.el.trigger(event);
146

    
147
              // trigger double tap immediately
148
              if (touch.isDoubleTap) {
149
                if ( touch.el !== undefined ) touch.el.trigger('doubleTap');
150
                touch = {};
151
              }
152

    
153
              // trigger single tap after 250ms of inactivity
154
              else {
155
                touchTimeout = setTimeout(function(){
156
                  touchTimeout = null;
157
                  if ( touch.el !== undefined ) touch.el.trigger('singleTap');
158
                  touch = {};
159
                }, 250);
160
              }
161
            }, 0);
162
          } else {
163
            touch = {};
164
          }
165
          deltaX = deltaY = 0;
166
        }
167
      })
168
      // when the browser window loses focus,
169
      // for example when a modal dialog is shown,
170
      // cancel all ongoing events
171
      .on('touchcancel MSPointerCancel pointercancel', function(e){
172

    
173
        // Ignore pointercancel if the event supports touch events, to prevent pointercancel in swipe gesture
174
        if ((e.type == 'touchcancel' && hasTouchEvents && hasTouch) || (!hasTouchEvents && e.type == 'pointercancel' && hasPointerEvents)) {
175
          cancelAll();
176
        }
177

    
178
    });
179

    
180
    // scrolling the window indicates intention of the user
181
    // to scroll, not tap or swipe, so cancel all ongoing events
182
    $(window).on('scroll', cancelAll);
183
  });
184

    
185
  ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){
186
    $.fn[eventName] = function(callback){ return $(this).on(eventName, callback); };
187
  });
188
})(jQuery);
(29-29/32)