mangos 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,23 +13,7 @@ input[type="text"], select { padding: 1px; }
13
13
  .selector li:last-child { margin-right: 0; }
14
14
  .selector li.selected a { font-weight: bold; text-decoration: none; color: #000000; }
15
15
 
16
- /*
17
- #items-index body {
18
- background-image: -webkit-gradient(
19
- linear,
20
- left top,
21
- right bottom,
22
- color-stop(0.39, rgb(0,0,0)),
23
- color-stop(0.73, rgb(46,46,46))
24
- );
25
- background-image: -moz-linear-gradient(
26
- left top,
27
- rgb(0,0,0) 39%,
28
- rgb(46,46,46) 73%
29
- );
30
- }*/
31
-
32
- #page-back, #page-next {
16
+ #page-back, #page-next, #page-home {
33
17
  position: fixed;
34
18
  top: 0;
35
19
  bottom: 0;
@@ -37,9 +21,9 @@ input[type="text"], select { padding: 1px; }
37
21
  z-index: 10000;
38
22
  }
39
23
 
40
- #page-back:active, #page-next:active {
24
+ #page-back:active, #page-next:active, #page-home:active {
41
25
  background-color: #000000;
42
- opacity: 0.2;
26
+ opacity: 0.4;
43
27
  }
44
28
 
45
29
  #page-back {
@@ -50,3 +34,9 @@ input[type="text"], select { padding: 1px; }
50
34
  right: 0;
51
35
  }
52
36
 
37
+ #page-home {
38
+ left: 0;
39
+ height: 100px;
40
+ z-index: 10001;
41
+ }
42
+
@@ -9,7 +9,6 @@
9
9
  <link href="css/views.show.css" rel="stylesheet" type="text/css">
10
10
 
11
11
  <script src="js/lib/jquery-2.0.3.js" type="text/javascript"></script>
12
- <script src="js/lib/jquery.hammer.js" type="text/javascript"></script>
13
12
  <script src="js/lib/underscore.js" type="text/javascript"></script>
14
13
  <script src="js/framework.js" type="text/javascript"></script>
15
14
  <script src="js/controllers.index.js" type="text/javascript"></script>
@@ -50,6 +49,7 @@
50
49
 
51
50
  <div id="page-back"></div>
52
51
  <div id="page-next"></div>
52
+ <div id="page-home"></div>
53
53
 
54
54
  </body>
55
55
  </html>
@@ -1,17 +1,19 @@
1
1
  var store = null;
2
2
 
3
3
  $(function() {
4
- $(document).on("dragstart", "img", false);
5
-
6
4
  $("#page-back").click(function() {
7
5
  utils.page(utils.page() - 1);
8
6
  });
9
7
  $("#page-next").click(function() {
10
8
  utils.page(utils.page() + 1);
11
9
  });
10
+ $("#page-home").click(function() {
11
+ location.hash = lastControllerLocation;
12
+ });
12
13
 
13
14
  $(window).keydown(function(event) {
14
- if(event.keyCode == 39) {
15
+ if(event.keyCode == 39 || ((event.keyCode == 32 || event.keyCode == 13)
16
+ && utils.scrollDistanceFromBottom() <= 0)) {
15
17
  event.preventDefault();
16
18
  utils.page(utils.page() + 1);
17
19
  }
@@ -1,3 +1,5 @@
1
+ var lastControllerLocation = null;
2
+
1
3
  controllers.index = function(search, sort, sortDirection) {
2
4
  var _this = this;
3
5
 
@@ -41,6 +43,7 @@ controllers.index = function(search, sort, sortDirection) {
41
43
  console.log("starting index");
42
44
 
43
45
  $("#search").bind("keydown", function(event) {
46
+ event.stopPropagation();
44
47
  if(event.keyCode == 13) {
45
48
  event.preventDefault();
46
49
  utils.location({ params: [$("#search").val(), sort, sortDirection], hash: "1" });
@@ -61,14 +64,6 @@ controllers.index = function(search, sort, sortDirection) {
61
64
  utils.location({ params: [search, sort, $(this).data("sort-direction")], hash: "1" });
62
65
  });
63
66
 
64
- $("#view-index").hammer().on("drag swipeleft swiperight", function(event) {
65
- if(Hammer.utils.isVertical(event.gesture.direction)) return;
66
- event.gesture.preventDefault();
67
-
68
- if(event.type == 'swipeleft') utils.page(utils.page() + 1, pages);
69
- else if(event.type == 'swiperight') utils.page(utils.page() - 1, pages);
70
- });
71
-
72
67
  $("#view-index").show().addClass("current-view");
73
68
  }
74
69
 
@@ -93,8 +88,11 @@ controllers.index = function(search, sort, sortDirection) {
93
88
 
94
89
  this.render = function() {
95
90
  console.log("rendering");
91
+ window.scrollTo(0, 0);
92
+
96
93
  var booksPage = utils.paginate(books, perPage);
97
94
  addBooks(booksPage);
95
+ lastControllerLocation = location.hash;
98
96
  }
99
97
 
100
98
  this.destroy = function() {
@@ -104,7 +102,6 @@ controllers.index = function(search, sort, sortDirection) {
104
102
  $("a.sort").unbind("click");
105
103
  $("a.sort-direction").unbind("click");
106
104
  $("#items").empty();
107
- $("#view-index").hammer().off("swiperight").off("swipeleft").off("drag");
108
105
  $("#view-index").hide().removeClass("current-view");
109
106
  }
110
107
  }
@@ -22,32 +22,16 @@ controllers.show = function(key) {
22
22
 
23
23
  this.init = function() {
24
24
  console.log("starting show");
25
-
26
25
  $("#image").attr("src", "img/blank.png");
27
-
28
- $(window).bind("keydown.show", function(event)
29
- {
30
- if((event.keyCode == 32 || event.keyCode == 13) && utils.scrollDistanceFromBottom() <= 0)
31
- {
32
- event.preventDefault();
33
- utils.page(utils.page() + 1, book.pageUrls.length);
34
- }
35
- else if(event.keyCode == 8)
36
- {
37
- event.preventDefault();
38
- history.back();
39
- }
40
- });
41
-
42
26
  $("#view-show").show().addClass("current-view");
43
-
44
27
  //setTimeout(preloadImages, 5000);
45
28
  }
46
29
 
47
30
  this.render = function() {
31
+ window.scrollTo(0, 0);
32
+
48
33
  var index = utils.page();
49
34
 
50
- window.scrollTo(0, 0);
51
35
  _(5).times(function() {
52
36
  $("#image").attr('src', pageUrl(index));
53
37
  });
@@ -59,8 +43,6 @@ controllers.show = function(key) {
59
43
 
60
44
  this.destroy = function() {
61
45
  console.log("destroying show");
62
- $(window).unbind(".show");
63
- $("#view-show").unbind("click");
64
46
  $("#view-show").hide().removeClass("current-view");
65
47
  }
66
48
  }
@@ -1,3 +1,3 @@
1
1
  module Mangos
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mangos
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-21 00:00:00.000000000 Z
12
+ date: 2013-10-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -1106,7 +1106,6 @@ files:
1106
1106
  - app/js/lib/jquery-2.0.3.js
1107
1107
  - app/js/lib/jquery.ba-bbq.js
1108
1108
  - app/js/lib/jquery.colorbox.js
1109
- - app/js/lib/jquery.hammer.js
1110
1109
  - app/js/lib/underscore.js
1111
1110
  - bin/mangos
1112
1111
  - console
@@ -1,1529 +0,0 @@
1
- /*! Hammer.JS - v1.0.5 - 2013-04-07
2
- * http://eightmedia.github.com/hammer.js
3
- *
4
- * Copyright (c) 2013 Jorik Tangelder <j.tangelder@gmail.com>;
5
- * Licensed under the MIT license */
6
-
7
- (function(window, undefined) {
8
- 'use strict';
9
-
10
- /**
11
- * Hammer
12
- * use this to create instances
13
- * @param {HTMLElement} element
14
- * @param {Object} options
15
- * @returns {Hammer.Instance}
16
- * @constructor
17
- */
18
- var Hammer = function(element, options) {
19
- return new Hammer.Instance(element, options || {});
20
- };
21
-
22
- // default settings
23
- Hammer.defaults = {
24
- // add styles and attributes to the element to prevent the browser from doing
25
- // its native behavior. this doesnt prevent the scrolling, but cancels
26
- // the contextmenu, tap highlighting etc
27
- // set to false to disable this
28
- stop_browser_behavior: {
29
- // this also triggers onselectstart=false for IE
30
- userSelect: 'none',
31
- // this makes the element blocking in IE10 >, you could experiment with the value
32
- // see for more options this issue; https://github.com/EightMedia/hammer.js/issues/241
33
- touchAction: 'none',
34
- touchCallout: 'none',
35
- contentZooming: 'none',
36
- userDrag: 'none',
37
- tapHighlightColor: 'rgba(0,0,0,0)'
38
- }
39
-
40
- // more settings are defined per gesture at gestures.js
41
- };
42
-
43
- // detect touchevents
44
- Hammer.HAS_POINTEREVENTS = navigator.pointerEnabled || navigator.msPointerEnabled;
45
- Hammer.HAS_TOUCHEVENTS = ('ontouchstart' in window);
46
-
47
- // dont use mouseevents on mobile devices
48
- Hammer.MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
49
- Hammer.NO_MOUSEEVENTS = Hammer.HAS_TOUCHEVENTS && navigator.userAgent.match(Hammer.MOBILE_REGEX);
50
-
51
- // eventtypes per touchevent (start, move, end)
52
- // are filled by Hammer.event.determineEventTypes on setup
53
- Hammer.EVENT_TYPES = {};
54
-
55
- // direction defines
56
- Hammer.DIRECTION_DOWN = 'down';
57
- Hammer.DIRECTION_LEFT = 'left';
58
- Hammer.DIRECTION_UP = 'up';
59
- Hammer.DIRECTION_RIGHT = 'right';
60
-
61
- // pointer type
62
- Hammer.POINTER_MOUSE = 'mouse';
63
- Hammer.POINTER_TOUCH = 'touch';
64
- Hammer.POINTER_PEN = 'pen';
65
-
66
- // touch event defines
67
- Hammer.EVENT_START = 'start';
68
- Hammer.EVENT_MOVE = 'move';
69
- Hammer.EVENT_END = 'end';
70
-
71
- // hammer document where the base events are added at
72
- Hammer.DOCUMENT = document;
73
-
74
- // plugins namespace
75
- Hammer.plugins = {};
76
-
77
- // if the window events are set...
78
- Hammer.READY = false;
79
-
80
- /**
81
- * setup events to detect gestures on the document
82
- */
83
- function setup() {
84
- if(Hammer.READY) {
85
- return;
86
- }
87
-
88
- // find what eventtypes we add listeners to
89
- Hammer.event.determineEventTypes();
90
-
91
- // Register all gestures inside Hammer.gestures
92
- for(var name in Hammer.gestures) {
93
- if(Hammer.gestures.hasOwnProperty(name)) {
94
- Hammer.detection.register(Hammer.gestures[name]);
95
- }
96
- }
97
-
98
- // Add touch events on the document
99
- Hammer.event.onTouch(Hammer.DOCUMENT, Hammer.EVENT_MOVE, Hammer.detection.detect);
100
- Hammer.event.onTouch(Hammer.DOCUMENT, Hammer.EVENT_END, Hammer.detection.detect);
101
-
102
- // Hammer is ready...!
103
- Hammer.READY = true;
104
- }
105
-
106
- /**
107
- * create new hammer instance
108
- * all methods should return the instance itself, so it is chainable.
109
- * @param {HTMLElement} element
110
- * @param {Object} [options={}]
111
- * @returns {Hammer.Instance}
112
- * @constructor
113
- */
114
- Hammer.Instance = function(element, options) {
115
- var self = this;
116
-
117
- // setup HammerJS window events and register all gestures
118
- // this also sets up the default options
119
- setup();
120
-
121
- this.element = element;
122
-
123
- // start/stop detection option
124
- this.enabled = true;
125
-
126
- // merge options
127
- this.options = Hammer.utils.extend(
128
- Hammer.utils.extend({}, Hammer.defaults),
129
- options || {});
130
-
131
- // add some css to the element to prevent the browser from doing its native behavoir
132
- if(this.options.stop_browser_behavior) {
133
- Hammer.utils.stopDefaultBrowserBehavior(this.element, this.options.stop_browser_behavior);
134
- }
135
-
136
- // start detection on touchstart
137
- Hammer.event.onTouch(element, Hammer.EVENT_START, function(ev) {
138
- if(self.enabled) {
139
- Hammer.detection.startDetect(self, ev);
140
- }
141
- });
142
-
143
- // return instance
144
- return this;
145
- };
146
-
147
-
148
- Hammer.Instance.prototype = {
149
- /**
150
- * bind events to the instance
151
- * @param {String} gesture
152
- * @param {Function} handler
153
- * @returns {Hammer.Instance}
154
- */
155
- on: function onEvent(gesture, handler){
156
- var gestures = gesture.split(' ');
157
- for(var t=0; t<gestures.length; t++) {
158
- this.element.addEventListener(gestures[t], handler, false);
159
- }
160
- return this;
161
- },
162
-
163
-
164
- /**
165
- * unbind events to the instance
166
- * @param {String} gesture
167
- * @param {Function} handler
168
- * @returns {Hammer.Instance}
169
- */
170
- off: function offEvent(gesture, handler){
171
- var gestures = gesture.split(' ');
172
- for(var t=0; t<gestures.length; t++) {
173
- this.element.removeEventListener(gestures[t], handler, false);
174
- }
175
- return this;
176
- },
177
-
178
-
179
- /**
180
- * trigger gesture event
181
- * @param {String} gesture
182
- * @param {Object} eventData
183
- * @returns {Hammer.Instance}
184
- */
185
- trigger: function triggerEvent(gesture, eventData){
186
- // create DOM event
187
- var event = Hammer.DOCUMENT.createEvent('Event');
188
- event.initEvent(gesture, true, true);
189
- event.gesture = eventData;
190
-
191
- // trigger on the target if it is in the instance element,
192
- // this is for event delegation tricks
193
- var element = this.element;
194
- if(Hammer.utils.hasParent(eventData.target, element)) {
195
- element = eventData.target;
196
- }
197
-
198
- element.dispatchEvent(event);
199
- return this;
200
- },
201
-
202
-
203
- /**
204
- * enable of disable hammer.js detection
205
- * @param {Boolean} state
206
- * @returns {Hammer.Instance}
207
- */
208
- enable: function enable(state) {
209
- this.enabled = state;
210
- return this;
211
- }
212
- };
213
-
214
- /**
215
- * this holds the last move event,
216
- * used to fix empty touchend issue
217
- * see the onTouch event for an explanation
218
- * @type {Object}
219
- */
220
- var last_move_event = null;
221
-
222
-
223
- /**
224
- * when the mouse is hold down, this is true
225
- * @type {Boolean}
226
- */
227
- var enable_detect = false;
228
-
229
-
230
- /**
231
- * when touch events have been fired, this is true
232
- * @type {Boolean}
233
- */
234
- var touch_triggered = false;
235
-
236
-
237
- Hammer.event = {
238
- /**
239
- * simple addEventListener
240
- * @param {HTMLElement} element
241
- * @param {String} type
242
- * @param {Function} handler
243
- */
244
- bindDom: function(element, type, handler) {
245
- var types = type.split(' ');
246
- for(var t=0; t<types.length; t++) {
247
- element.addEventListener(types[t], handler, false);
248
- }
249
- },
250
-
251
-
252
- /**
253
- * touch events with mouse fallback
254
- * @param {HTMLElement} element
255
- * @param {String} eventType like Hammer.EVENT_MOVE
256
- * @param {Function} handler
257
- */
258
- onTouch: function onTouch(element, eventType, handler) {
259
- var self = this;
260
-
261
- this.bindDom(element, Hammer.EVENT_TYPES[eventType], function bindDomOnTouch(ev) {
262
- var sourceEventType = ev.type.toLowerCase();
263
-
264
- // onmouseup, but when touchend has been fired we do nothing.
265
- // this is for touchdevices which also fire a mouseup on touchend
266
- if(sourceEventType.match(/mouse/) && touch_triggered) {
267
- return;
268
- }
269
-
270
- // mousebutton must be down or a touch event
271
- else if( sourceEventType.match(/touch/) || // touch events are always on screen
272
- sourceEventType.match(/pointerdown/) || // pointerevents touch
273
- (sourceEventType.match(/mouse/) && ev.which === 1) // mouse is pressed
274
- ){
275
- enable_detect = true;
276
- }
277
-
278
- // we are in a touch event, set the touch triggered bool to true,
279
- // this for the conflicts that may occur on ios and android
280
- if(sourceEventType.match(/touch|pointer/)) {
281
- touch_triggered = true;
282
- }
283
-
284
- // count the total touches on the screen
285
- var count_touches = 0;
286
-
287
- // when touch has been triggered in this detection session
288
- // and we are now handling a mouse event, we stop that to prevent conflicts
289
- if(enable_detect) {
290
- // update pointerevent
291
- if(Hammer.HAS_POINTEREVENTS && eventType != Hammer.EVENT_END) {
292
- count_touches = Hammer.PointerEvent.updatePointer(eventType, ev);
293
- }
294
- // touch
295
- else if(sourceEventType.match(/touch/)) {
296
- count_touches = ev.touches.length;
297
- }
298
- // mouse
299
- else if(!touch_triggered) {
300
- count_touches = sourceEventType.match(/up/) ? 0 : 1;
301
- }
302
-
303
- // if we are in a end event, but when we remove one touch and
304
- // we still have enough, set eventType to move
305
- if(count_touches > 0 && eventType == Hammer.EVENT_END) {
306
- eventType = Hammer.EVENT_MOVE;
307
- }
308
- // no touches, force the end event
309
- else if(!count_touches) {
310
- eventType = Hammer.EVENT_END;
311
- }
312
-
313
- // because touchend has no touches, and we often want to use these in our gestures,
314
- // we send the last move event as our eventData in touchend
315
- if(!count_touches && last_move_event !== null) {
316
- ev = last_move_event;
317
- }
318
- // store the last move event
319
- else {
320
- last_move_event = ev;
321
- }
322
-
323
- // trigger the handler
324
- handler.call(Hammer.detection, self.collectEventData(element, eventType, ev));
325
-
326
- // remove pointerevent from list
327
- if(Hammer.HAS_POINTEREVENTS && eventType == Hammer.EVENT_END) {
328
- count_touches = Hammer.PointerEvent.updatePointer(eventType, ev);
329
- }
330
- }
331
-
332
- //debug(sourceEventType +" "+ eventType);
333
-
334
- // on the end we reset everything
335
- if(!count_touches) {
336
- last_move_event = null;
337
- enable_detect = false;
338
- touch_triggered = false;
339
- Hammer.PointerEvent.reset();
340
- }
341
- });
342
- },
343
-
344
-
345
- /**
346
- * we have different events for each device/browser
347
- * determine what we need and set them in the Hammer.EVENT_TYPES constant
348
- */
349
- determineEventTypes: function determineEventTypes() {
350
- // determine the eventtype we want to set
351
- var types;
352
-
353
- // pointerEvents magic
354
- if(Hammer.HAS_POINTEREVENTS) {
355
- types = Hammer.PointerEvent.getEvents();
356
- }
357
- // on Android, iOS, blackberry, windows mobile we dont want any mouseevents
358
- else if(Hammer.NO_MOUSEEVENTS) {
359
- types = [
360
- 'touchstart',
361
- 'touchmove',
362
- 'touchend touchcancel'];
363
- }
364
- // for non pointer events browsers and mixed browsers,
365
- // like chrome on windows8 touch laptop
366
- else {
367
- types = [
368
- 'touchstart mousedown',
369
- 'touchmove mousemove',
370
- 'touchend touchcancel mouseup'];
371
- }
372
-
373
- Hammer.EVENT_TYPES[Hammer.EVENT_START] = types[0];
374
- Hammer.EVENT_TYPES[Hammer.EVENT_MOVE] = types[1];
375
- Hammer.EVENT_TYPES[Hammer.EVENT_END] = types[2];
376
- },
377
-
378
-
379
- /**
380
- * create touchlist depending on the event
381
- * @param {Object} ev
382
- * @param {String} eventType used by the fakemultitouch plugin
383
- */
384
- getTouchList: function getTouchList(ev/*, eventType*/) {
385
- // get the fake pointerEvent touchlist
386
- if(Hammer.HAS_POINTEREVENTS) {
387
- return Hammer.PointerEvent.getTouchList();
388
- }
389
- // get the touchlist
390
- else if(ev.touches) {
391
- return ev.touches;
392
- }
393
- // make fake touchlist from mouse position
394
- else {
395
- return [{
396
- identifier: 1,
397
- pageX: ev.pageX,
398
- pageY: ev.pageY,
399
- target: ev.target
400
- }];
401
- }
402
- },
403
-
404
-
405
- /**
406
- * collect event data for Hammer js
407
- * @param {HTMLElement} element
408
- * @param {String} eventType like Hammer.EVENT_MOVE
409
- * @param {Object} eventData
410
- */
411
- collectEventData: function collectEventData(element, eventType, ev) {
412
- var touches = this.getTouchList(ev, eventType);
413
-
414
- // find out pointerType
415
- var pointerType = Hammer.POINTER_TOUCH;
416
- if(ev.type.match(/mouse/) || Hammer.PointerEvent.matchType(Hammer.POINTER_MOUSE, ev)) {
417
- pointerType = Hammer.POINTER_MOUSE;
418
- }
419
-
420
- return {
421
- center : Hammer.utils.getCenter(touches),
422
- timeStamp : new Date().getTime(),
423
- target : ev.target,
424
- touches : touches,
425
- eventType : eventType,
426
- pointerType : pointerType,
427
- srcEvent : ev,
428
-
429
- /**
430
- * prevent the browser default actions
431
- * mostly used to disable scrolling of the browser
432
- */
433
- preventDefault: function() {
434
- if(this.srcEvent.preventManipulation) {
435
- this.srcEvent.preventManipulation();
436
- }
437
-
438
- if(this.srcEvent.preventDefault) {
439
- this.srcEvent.preventDefault();
440
- }
441
- },
442
-
443
- /**
444
- * stop bubbling the event up to its parents
445
- */
446
- stopPropagation: function() {
447
- this.srcEvent.stopPropagation();
448
- },
449
-
450
- /**
451
- * immediately stop gesture detection
452
- * might be useful after a swipe was detected
453
- * @return {*}
454
- */
455
- stopDetect: function() {
456
- return Hammer.detection.stopDetect();
457
- }
458
- };
459
- }
460
- };
461
-
462
- Hammer.PointerEvent = {
463
- /**
464
- * holds all pointers
465
- * @type {Object}
466
- */
467
- pointers: {},
468
-
469
- /**
470
- * get a list of pointers
471
- * @returns {Array} touchlist
472
- */
473
- getTouchList: function() {
474
- var self = this;
475
- var touchlist = [];
476
-
477
- // we can use forEach since pointerEvents only is in IE10
478
- Object.keys(self.pointers).sort().forEach(function(id) {
479
- touchlist.push(self.pointers[id]);
480
- });
481
- return touchlist;
482
- },
483
-
484
- /**
485
- * update the position of a pointer
486
- * @param {String} type Hammer.EVENT_END
487
- * @param {Object} pointerEvent
488
- */
489
- updatePointer: function(type, pointerEvent) {
490
- if(type == Hammer.EVENT_END) {
491
- this.pointers = {};
492
- }
493
- else {
494
- pointerEvent.identifier = pointerEvent.pointerId;
495
- this.pointers[pointerEvent.pointerId] = pointerEvent;
496
- }
497
-
498
- return Object.keys(this.pointers).length;
499
- },
500
-
501
- /**
502
- * check if ev matches pointertype
503
- * @param {String} pointerType Hammer.POINTER_MOUSE
504
- * @param {PointerEvent} ev
505
- */
506
- matchType: function(pointerType, ev) {
507
- if(!ev.pointerType) {
508
- return false;
509
- }
510
-
511
- var types = {};
512
- types[Hammer.POINTER_MOUSE] = (ev.pointerType == ev.MSPOINTER_TYPE_MOUSE || ev.pointerType == Hammer.POINTER_MOUSE);
513
- types[Hammer.POINTER_TOUCH] = (ev.pointerType == ev.MSPOINTER_TYPE_TOUCH || ev.pointerType == Hammer.POINTER_TOUCH);
514
- types[Hammer.POINTER_PEN] = (ev.pointerType == ev.MSPOINTER_TYPE_PEN || ev.pointerType == Hammer.POINTER_PEN);
515
- return types[pointerType];
516
- },
517
-
518
-
519
- /**
520
- * get events
521
- */
522
- getEvents: function() {
523
- return [
524
- 'pointerdown MSPointerDown',
525
- 'pointermove MSPointerMove',
526
- 'pointerup pointercancel MSPointerUp MSPointerCancel'
527
- ];
528
- },
529
-
530
- /**
531
- * reset the list
532
- */
533
- reset: function() {
534
- this.pointers = {};
535
- }
536
- };
537
-
538
-
539
- Hammer.utils = {
540
- /**
541
- * extend method,
542
- * also used for cloning when dest is an empty object
543
- * @param {Object} dest
544
- * @param {Object} src
545
- * @parm {Boolean} merge do a merge
546
- * @returns {Object} dest
547
- */
548
- extend: function extend(dest, src, merge) {
549
- for (var key in src) {
550
- if(dest[key] !== undefined && merge) {
551
- continue;
552
- }
553
- dest[key] = src[key];
554
- }
555
- return dest;
556
- },
557
-
558
-
559
- /**
560
- * find if a node is in the given parent
561
- * used for event delegation tricks
562
- * @param {HTMLElement} node
563
- * @param {HTMLElement} parent
564
- * @returns {boolean} has_parent
565
- */
566
- hasParent: function(node, parent) {
567
- while(node){
568
- if(node == parent) {
569
- return true;
570
- }
571
- node = node.parentNode;
572
- }
573
- return false;
574
- },
575
-
576
-
577
- /**
578
- * get the center of all the touches
579
- * @param {Array} touches
580
- * @returns {Object} center
581
- */
582
- getCenter: function getCenter(touches) {
583
- var valuesX = [], valuesY = [];
584
-
585
- for(var t= 0,len=touches.length; t<len; t++) {
586
- valuesX.push(touches[t].pageX);
587
- valuesY.push(touches[t].pageY);
588
- }
589
-
590
- return {
591
- pageX: ((Math.min.apply(Math, valuesX) + Math.max.apply(Math, valuesX)) / 2),
592
- pageY: ((Math.min.apply(Math, valuesY) + Math.max.apply(Math, valuesY)) / 2)
593
- };
594
- },
595
-
596
-
597
- /**
598
- * calculate the velocity between two points
599
- * @param {Number} delta_time
600
- * @param {Number} delta_x
601
- * @param {Number} delta_y
602
- * @returns {Object} velocity
603
- */
604
- getVelocity: function getVelocity(delta_time, delta_x, delta_y) {
605
- return {
606
- x: Math.abs(delta_x / delta_time) || 0,
607
- y: Math.abs(delta_y / delta_time) || 0
608
- };
609
- },
610
-
611
-
612
- /**
613
- * calculate the angle between two coordinates
614
- * @param {Touch} touch1
615
- * @param {Touch} touch2
616
- * @returns {Number} angle
617
- */
618
- getAngle: function getAngle(touch1, touch2) {
619
- var y = touch2.pageY - touch1.pageY,
620
- x = touch2.pageX - touch1.pageX;
621
- return Math.atan2(y, x) * 180 / Math.PI;
622
- },
623
-
624
-
625
- /**
626
- * angle to direction define
627
- * @param {Touch} touch1
628
- * @param {Touch} touch2
629
- * @returns {String} direction constant, like Hammer.DIRECTION_LEFT
630
- */
631
- getDirection: function getDirection(touch1, touch2) {
632
- var x = Math.abs(touch1.pageX - touch2.pageX),
633
- y = Math.abs(touch1.pageY - touch2.pageY);
634
-
635
- if(x >= y) {
636
- return touch1.pageX - touch2.pageX > 0 ? Hammer.DIRECTION_LEFT : Hammer.DIRECTION_RIGHT;
637
- }
638
- else {
639
- return touch1.pageY - touch2.pageY > 0 ? Hammer.DIRECTION_UP : Hammer.DIRECTION_DOWN;
640
- }
641
- },
642
-
643
-
644
- /**
645
- * calculate the distance between two touches
646
- * @param {Touch} touch1
647
- * @param {Touch} touch2
648
- * @returns {Number} distance
649
- */
650
- getDistance: function getDistance(touch1, touch2) {
651
- var x = touch2.pageX - touch1.pageX,
652
- y = touch2.pageY - touch1.pageY;
653
- return Math.sqrt((x*x) + (y*y));
654
- },
655
-
656
-
657
- /**
658
- * calculate the scale factor between two touchLists (fingers)
659
- * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
660
- * @param {Array} start
661
- * @param {Array} end
662
- * @returns {Number} scale
663
- */
664
- getScale: function getScale(start, end) {
665
- // need two fingers...
666
- if(start.length >= 2 && end.length >= 2) {
667
- return this.getDistance(end[0], end[1]) /
668
- this.getDistance(start[0], start[1]);
669
- }
670
- return 1;
671
- },
672
-
673
-
674
- /**
675
- * calculate the rotation degrees between two touchLists (fingers)
676
- * @param {Array} start
677
- * @param {Array} end
678
- * @returns {Number} rotation
679
- */
680
- getRotation: function getRotation(start, end) {
681
- // need two fingers
682
- if(start.length >= 2 && end.length >= 2) {
683
- return this.getAngle(end[1], end[0]) -
684
- this.getAngle(start[1], start[0]);
685
- }
686
- return 0;
687
- },
688
-
689
-
690
- /**
691
- * boolean if the direction is vertical
692
- * @param {String} direction
693
- * @returns {Boolean} is_vertical
694
- */
695
- isVertical: function isVertical(direction) {
696
- return (direction == Hammer.DIRECTION_UP || direction == Hammer.DIRECTION_DOWN);
697
- },
698
-
699
-
700
- /**
701
- * stop browser default behavior with css props
702
- * @param {HtmlElement} element
703
- * @param {Object} css_props
704
- */
705
- stopDefaultBrowserBehavior: function stopDefaultBrowserBehavior(element, css_props) {
706
- var prop,
707
- vendors = ['webkit','khtml','moz','ms','o',''];
708
-
709
- if(!css_props || !element.style) {
710
- return;
711
- }
712
-
713
- // with css properties for modern browsers
714
- for(var i = 0; i < vendors.length; i++) {
715
- for(var p in css_props) {
716
- if(css_props.hasOwnProperty(p)) {
717
- prop = p;
718
-
719
- // vender prefix at the property
720
- if(vendors[i]) {
721
- prop = vendors[i] + prop.substring(0, 1).toUpperCase() + prop.substring(1);
722
- }
723
-
724
- // set the style
725
- element.style[prop] = css_props[p];
726
- }
727
- }
728
- }
729
-
730
- // also the disable onselectstart
731
- if(css_props.userSelect == 'none') {
732
- element.onselectstart = function() {
733
- return false;
734
- };
735
- }
736
- }
737
- };
738
-
739
- Hammer.detection = {
740
- // contains all registred Hammer.gestures in the correct order
741
- gestures: [],
742
-
743
- // data of the current Hammer.gesture detection session
744
- current: null,
745
-
746
- // the previous Hammer.gesture session data
747
- // is a full clone of the previous gesture.current object
748
- previous: null,
749
-
750
- // when this becomes true, no gestures are fired
751
- stopped: false,
752
-
753
-
754
- /**
755
- * start Hammer.gesture detection
756
- * @param {Hammer.Instance} inst
757
- * @param {Object} eventData
758
- */
759
- startDetect: function startDetect(inst, eventData) {
760
- // already busy with a Hammer.gesture detection on an element
761
- if(this.current) {
762
- return;
763
- }
764
-
765
- this.stopped = false;
766
-
767
- this.current = {
768
- inst : inst, // reference to HammerInstance we're working for
769
- startEvent : Hammer.utils.extend({}, eventData), // start eventData for distances, timing etc
770
- lastEvent : false, // last eventData
771
- name : '' // current gesture we're in/detected, can be 'tap', 'hold' etc
772
- };
773
-
774
- this.detect(eventData);
775
- },
776
-
777
-
778
- /**
779
- * Hammer.gesture detection
780
- * @param {Object} eventData
781
- * @param {Object} eventData
782
- */
783
- detect: function detect(eventData) {
784
- if(!this.current || this.stopped) {
785
- return;
786
- }
787
-
788
- // extend event data with calculations about scale, distance etc
789
- eventData = this.extendEventData(eventData);
790
-
791
- // instance options
792
- var inst_options = this.current.inst.options;
793
-
794
- // call Hammer.gesture handlers
795
- for(var g=0,len=this.gestures.length; g<len; g++) {
796
- var gesture = this.gestures[g];
797
-
798
- // only when the instance options have enabled this gesture
799
- if(!this.stopped && inst_options[gesture.name] !== false) {
800
- // if a handler returns false, we stop with the detection
801
- if(gesture.handler.call(gesture, eventData, this.current.inst) === false) {
802
- this.stopDetect();
803
- break;
804
- }
805
- }
806
- }
807
-
808
- // store as previous event event
809
- if(this.current) {
810
- this.current.lastEvent = eventData;
811
- }
812
-
813
- // endevent, but not the last touch, so dont stop
814
- if(eventData.eventType == Hammer.EVENT_END && !eventData.touches.length-1) {
815
- this.stopDetect();
816
- }
817
-
818
- return eventData;
819
- },
820
-
821
-
822
- /**
823
- * clear the Hammer.gesture vars
824
- * this is called on endDetect, but can also be used when a final Hammer.gesture has been detected
825
- * to stop other Hammer.gestures from being fired
826
- */
827
- stopDetect: function stopDetect() {
828
- // clone current data to the store as the previous gesture
829
- // used for the double tap gesture, since this is an other gesture detect session
830
- this.previous = Hammer.utils.extend({}, this.current);
831
-
832
- // reset the current
833
- this.current = null;
834
-
835
- // stopped!
836
- this.stopped = true;
837
- },
838
-
839
-
840
- /**
841
- * extend eventData for Hammer.gestures
842
- * @param {Object} ev
843
- * @returns {Object} ev
844
- */
845
- extendEventData: function extendEventData(ev) {
846
- var startEv = this.current.startEvent;
847
-
848
- // if the touches change, set the new touches over the startEvent touches
849
- // this because touchevents don't have all the touches on touchstart, or the
850
- // user must place his fingers at the EXACT same time on the screen, which is not realistic
851
- // but, sometimes it happens that both fingers are touching at the EXACT same time
852
- if(startEv && (ev.touches.length != startEv.touches.length || ev.touches === startEv.touches)) {
853
- // extend 1 level deep to get the touchlist with the touch objects
854
- startEv.touches = [];
855
- for(var i=0,len=ev.touches.length; i<len; i++) {
856
- startEv.touches.push(Hammer.utils.extend({}, ev.touches[i]));
857
- }
858
- }
859
-
860
- var delta_time = ev.timeStamp - startEv.timeStamp,
861
- delta_x = ev.center.pageX - startEv.center.pageX,
862
- delta_y = ev.center.pageY - startEv.center.pageY,
863
- velocity = Hammer.utils.getVelocity(delta_time, delta_x, delta_y);
864
-
865
- Hammer.utils.extend(ev, {
866
- deltaTime : delta_time,
867
-
868
- deltaX : delta_x,
869
- deltaY : delta_y,
870
-
871
- velocityX : velocity.x,
872
- velocityY : velocity.y,
873
-
874
- distance : Hammer.utils.getDistance(startEv.center, ev.center),
875
- angle : Hammer.utils.getAngle(startEv.center, ev.center),
876
- direction : Hammer.utils.getDirection(startEv.center, ev.center),
877
-
878
- scale : Hammer.utils.getScale(startEv.touches, ev.touches),
879
- rotation : Hammer.utils.getRotation(startEv.touches, ev.touches),
880
-
881
- startEvent : startEv
882
- });
883
-
884
- return ev;
885
- },
886
-
887
-
888
- /**
889
- * register new gesture
890
- * @param {Object} gesture object, see gestures.js for documentation
891
- * @returns {Array} gestures
892
- */
893
- register: function register(gesture) {
894
- // add an enable gesture options if there is no given
895
- var options = gesture.defaults || {};
896
- if(options[gesture.name] === undefined) {
897
- options[gesture.name] = true;
898
- }
899
-
900
- // extend Hammer default options with the Hammer.gesture options
901
- Hammer.utils.extend(Hammer.defaults, options, true);
902
-
903
- // set its index
904
- gesture.index = gesture.index || 1000;
905
-
906
- // add Hammer.gesture to the list
907
- this.gestures.push(gesture);
908
-
909
- // sort the list by index
910
- this.gestures.sort(function(a, b) {
911
- if (a.index < b.index) {
912
- return -1;
913
- }
914
- if (a.index > b.index) {
915
- return 1;
916
- }
917
- return 0;
918
- });
919
-
920
- return this.gestures;
921
- }
922
- };
923
-
924
-
925
- Hammer.gestures = Hammer.gestures || {};
926
-
927
- /**
928
- * Custom gestures
929
- * ==============================
930
- *
931
- * Gesture object
932
- * --------------------
933
- * The object structure of a gesture:
934
- *
935
- * { name: 'mygesture',
936
- * index: 1337,
937
- * defaults: {
938
- * mygesture_option: true
939
- * }
940
- * handler: function(type, ev, inst) {
941
- * // trigger gesture event
942
- * inst.trigger(this.name, ev);
943
- * }
944
- * }
945
-
946
- * @param {String} name
947
- * this should be the name of the gesture, lowercase
948
- * it is also being used to disable/enable the gesture per instance config.
949
- *
950
- * @param {Number} [index=1000]
951
- * the index of the gesture, where it is going to be in the stack of gestures detection
952
- * like when you build an gesture that depends on the drag gesture, it is a good
953
- * idea to place it after the index of the drag gesture.
954
- *
955
- * @param {Object} [defaults={}]
956
- * the default settings of the gesture. these are added to the instance settings,
957
- * and can be overruled per instance. you can also add the name of the gesture,
958
- * but this is also added by default (and set to true).
959
- *
960
- * @param {Function} handler
961
- * this handles the gesture detection of your custom gesture and receives the
962
- * following arguments:
963
- *
964
- * @param {Object} eventData
965
- * event data containing the following properties:
966
- * timeStamp {Number} time the event occurred
967
- * target {HTMLElement} target element
968
- * touches {Array} touches (fingers, pointers, mouse) on the screen
969
- * pointerType {String} kind of pointer that was used. matches Hammer.POINTER_MOUSE|TOUCH
970
- * center {Object} center position of the touches. contains pageX and pageY
971
- * deltaTime {Number} the total time of the touches in the screen
972
- * deltaX {Number} the delta on x axis we haved moved
973
- * deltaY {Number} the delta on y axis we haved moved
974
- * velocityX {Number} the velocity on the x
975
- * velocityY {Number} the velocity on y
976
- * angle {Number} the angle we are moving
977
- * direction {String} the direction we are moving. matches Hammer.DIRECTION_UP|DOWN|LEFT|RIGHT
978
- * distance {Number} the distance we haved moved
979
- * scale {Number} scaling of the touches, needs 2 touches
980
- * rotation {Number} rotation of the touches, needs 2 touches *
981
- * eventType {String} matches Hammer.EVENT_START|MOVE|END
982
- * srcEvent {Object} the source event, like TouchStart or MouseDown *
983
- * startEvent {Object} contains the same properties as above,
984
- * but from the first touch. this is used to calculate
985
- * distances, deltaTime, scaling etc
986
- *
987
- * @param {Hammer.Instance} inst
988
- * the instance we are doing the detection for. you can get the options from
989
- * the inst.options object and trigger the gesture event by calling inst.trigger
990
- *
991
- *
992
- * Handle gestures
993
- * --------------------
994
- * inside the handler you can get/set Hammer.detection.current. This is the current
995
- * detection session. It has the following properties
996
- * @param {String} name
997
- * contains the name of the gesture we have detected. it has not a real function,
998
- * only to check in other gestures if something is detected.
999
- * like in the drag gesture we set it to 'drag' and in the swipe gesture we can
1000
- * check if the current gesture is 'drag' by accessing Hammer.detection.current.name
1001
- *
1002
- * @readonly
1003
- * @param {Hammer.Instance} inst
1004
- * the instance we do the detection for
1005
- *
1006
- * @readonly
1007
- * @param {Object} startEvent
1008
- * contains the properties of the first gesture detection in this session.
1009
- * Used for calculations about timing, distance, etc.
1010
- *
1011
- * @readonly
1012
- * @param {Object} lastEvent
1013
- * contains all the properties of the last gesture detect in this session.
1014
- *
1015
- * after the gesture detection session has been completed (user has released the screen)
1016
- * the Hammer.detection.current object is copied into Hammer.detection.previous,
1017
- * this is usefull for gestures like doubletap, where you need to know if the
1018
- * previous gesture was a tap
1019
- *
1020
- * options that have been set by the instance can be received by calling inst.options
1021
- *
1022
- * You can trigger a gesture event by calling inst.trigger("mygesture", event).
1023
- * The first param is the name of your gesture, the second the event argument
1024
- *
1025
- *
1026
- * Register gestures
1027
- * --------------------
1028
- * When an gesture is added to the Hammer.gestures object, it is auto registered
1029
- * at the setup of the first Hammer instance. You can also call Hammer.detection.register
1030
- * manually and pass your gesture object as a param
1031
- *
1032
- */
1033
-
1034
- /**
1035
- * Hold
1036
- * Touch stays at the same place for x time
1037
- * @events hold
1038
- */
1039
- Hammer.gestures.Hold = {
1040
- name: 'hold',
1041
- index: 10,
1042
- defaults: {
1043
- hold_timeout : 500,
1044
- hold_threshold : 1
1045
- },
1046
- timer: null,
1047
- handler: function holdGesture(ev, inst) {
1048
- switch(ev.eventType) {
1049
- case Hammer.EVENT_START:
1050
- // clear any running timers
1051
- clearTimeout(this.timer);
1052
-
1053
- // set the gesture so we can check in the timeout if it still is
1054
- Hammer.detection.current.name = this.name;
1055
-
1056
- // set timer and if after the timeout it still is hold,
1057
- // we trigger the hold event
1058
- this.timer = setTimeout(function() {
1059
- if(Hammer.detection.current.name == 'hold') {
1060
- inst.trigger('hold', ev);
1061
- }
1062
- }, inst.options.hold_timeout);
1063
- break;
1064
-
1065
- // when you move or end we clear the timer
1066
- case Hammer.EVENT_MOVE:
1067
- if(ev.distance > inst.options.hold_threshold) {
1068
- clearTimeout(this.timer);
1069
- }
1070
- break;
1071
-
1072
- case Hammer.EVENT_END:
1073
- clearTimeout(this.timer);
1074
- break;
1075
- }
1076
- }
1077
- };
1078
-
1079
-
1080
- /**
1081
- * Tap/DoubleTap
1082
- * Quick touch at a place or double at the same place
1083
- * @events tap, doubletap
1084
- */
1085
- Hammer.gestures.Tap = {
1086
- name: 'tap',
1087
- index: 100,
1088
- defaults: {
1089
- tap_max_touchtime : 250,
1090
- tap_max_distance : 10,
1091
- tap_always : true,
1092
- doubletap_distance : 20,
1093
- doubletap_interval : 300
1094
- },
1095
- handler: function tapGesture(ev, inst) {
1096
- if(ev.eventType == Hammer.EVENT_END) {
1097
- // previous gesture, for the double tap since these are two different gesture detections
1098
- var prev = Hammer.detection.previous,
1099
- did_doubletap = false;
1100
-
1101
- // when the touchtime is higher then the max touch time
1102
- // or when the moving distance is too much
1103
- if(ev.deltaTime > inst.options.tap_max_touchtime ||
1104
- ev.distance > inst.options.tap_max_distance) {
1105
- return;
1106
- }
1107
-
1108
- // check if double tap
1109
- if(prev && prev.name == 'tap' &&
1110
- (ev.timeStamp - prev.lastEvent.timeStamp) < inst.options.doubletap_interval &&
1111
- ev.distance < inst.options.doubletap_distance) {
1112
- inst.trigger('doubletap', ev);
1113
- did_doubletap = true;
1114
- }
1115
-
1116
- // do a single tap
1117
- if(!did_doubletap || inst.options.tap_always) {
1118
- Hammer.detection.current.name = 'tap';
1119
- inst.trigger(Hammer.detection.current.name, ev);
1120
- }
1121
- }
1122
- }
1123
- };
1124
-
1125
-
1126
- /**
1127
- * Swipe
1128
- * triggers swipe events when the end velocity is above the threshold
1129
- * @events swipe, swipeleft, swiperight, swipeup, swipedown
1130
- */
1131
- Hammer.gestures.Swipe = {
1132
- name: 'swipe',
1133
- index: 40,
1134
- defaults: {
1135
- // set 0 for unlimited, but this can conflict with transform
1136
- swipe_max_touches : 1,
1137
- swipe_velocity : 0.7
1138
- },
1139
- handler: function swipeGesture(ev, inst) {
1140
- if(ev.eventType == Hammer.EVENT_END) {
1141
- // max touches
1142
- if(inst.options.swipe_max_touches > 0 &&
1143
- ev.touches.length > inst.options.swipe_max_touches) {
1144
- return;
1145
- }
1146
-
1147
- // when the distance we moved is too small we skip this gesture
1148
- // or we can be already in dragging
1149
- if(ev.velocityX > inst.options.swipe_velocity ||
1150
- ev.velocityY > inst.options.swipe_velocity) {
1151
- // trigger swipe events
1152
- inst.trigger(this.name, ev);
1153
- inst.trigger(this.name + ev.direction, ev);
1154
- }
1155
- }
1156
- }
1157
- };
1158
-
1159
-
1160
- /**
1161
- * Drag
1162
- * Move with x fingers (default 1) around on the page. Blocking the scrolling when
1163
- * moving left and right is a good practice. When all the drag events are blocking
1164
- * you disable scrolling on that area.
1165
- * @events drag, drapleft, dragright, dragup, dragdown
1166
- */
1167
- Hammer.gestures.Drag = {
1168
- name: 'drag',
1169
- index: 50,
1170
- defaults: {
1171
- drag_min_distance : 10,
1172
- // set 0 for unlimited, but this can conflict with transform
1173
- drag_max_touches : 1,
1174
- // prevent default browser behavior when dragging occurs
1175
- // be careful with it, it makes the element a blocking element
1176
- // when you are using the drag gesture, it is a good practice to set this true
1177
- drag_block_horizontal : false,
1178
- drag_block_vertical : false,
1179
- // drag_lock_to_axis keeps the drag gesture on the axis that it started on,
1180
- // It disallows vertical directions if the initial direction was horizontal, and vice versa.
1181
- drag_lock_to_axis : false,
1182
- // drag lock only kicks in when distance > drag_lock_min_distance
1183
- // This way, locking occurs only when the distance has become large enough to reliably determine the direction
1184
- drag_lock_min_distance : 25
1185
- },
1186
- triggered: false,
1187
- handler: function dragGesture(ev, inst) {
1188
- // current gesture isnt drag, but dragged is true
1189
- // this means an other gesture is busy. now call dragend
1190
- if(Hammer.detection.current.name != this.name && this.triggered) {
1191
- inst.trigger(this.name +'end', ev);
1192
- this.triggered = false;
1193
- return;
1194
- }
1195
-
1196
- // max touches
1197
- if(inst.options.drag_max_touches > 0 &&
1198
- ev.touches.length > inst.options.drag_max_touches) {
1199
- return;
1200
- }
1201
-
1202
- switch(ev.eventType) {
1203
- case Hammer.EVENT_START:
1204
- this.triggered = false;
1205
- break;
1206
-
1207
- case Hammer.EVENT_MOVE:
1208
- // when the distance we moved is too small we skip this gesture
1209
- // or we can be already in dragging
1210
- if(ev.distance < inst.options.drag_min_distance &&
1211
- Hammer.detection.current.name != this.name) {
1212
- return;
1213
- }
1214
-
1215
- // we are dragging!
1216
- Hammer.detection.current.name = this.name;
1217
-
1218
- // lock drag to axis?
1219
- if(Hammer.detection.current.lastEvent.drag_locked_to_axis || (inst.options.drag_lock_to_axis && inst.options.drag_lock_min_distance<=ev.distance)) {
1220
- ev.drag_locked_to_axis = true;
1221
- }
1222
- var last_direction = Hammer.detection.current.lastEvent.direction;
1223
- if(ev.drag_locked_to_axis && last_direction !== ev.direction) {
1224
- // keep direction on the axis that the drag gesture started on
1225
- if(Hammer.utils.isVertical(last_direction)) {
1226
- ev.direction = (ev.deltaY < 0) ? Hammer.DIRECTION_UP : Hammer.DIRECTION_DOWN;
1227
- }
1228
- else {
1229
- ev.direction = (ev.deltaX < 0) ? Hammer.DIRECTION_LEFT : Hammer.DIRECTION_RIGHT;
1230
- }
1231
- }
1232
-
1233
- // first time, trigger dragstart event
1234
- if(!this.triggered) {
1235
- inst.trigger(this.name +'start', ev);
1236
- this.triggered = true;
1237
- }
1238
-
1239
- // trigger normal event
1240
- inst.trigger(this.name, ev);
1241
-
1242
- // direction event, like dragdown
1243
- inst.trigger(this.name + ev.direction, ev);
1244
-
1245
- // block the browser events
1246
- if( (inst.options.drag_block_vertical && Hammer.utils.isVertical(ev.direction)) ||
1247
- (inst.options.drag_block_horizontal && !Hammer.utils.isVertical(ev.direction))) {
1248
- ev.preventDefault();
1249
- }
1250
- break;
1251
-
1252
- case Hammer.EVENT_END:
1253
- // trigger dragend
1254
- if(this.triggered) {
1255
- inst.trigger(this.name +'end', ev);
1256
- }
1257
-
1258
- this.triggered = false;
1259
- break;
1260
- }
1261
- }
1262
- };
1263
-
1264
-
1265
- /**
1266
- * Transform
1267
- * User want to scale or rotate with 2 fingers
1268
- * @events transform, pinch, pinchin, pinchout, rotate
1269
- */
1270
- Hammer.gestures.Transform = {
1271
- name: 'transform',
1272
- index: 45,
1273
- defaults: {
1274
- // factor, no scale is 1, zoomin is to 0 and zoomout until higher then 1
1275
- transform_min_scale : 0.01,
1276
- // rotation in degrees
1277
- transform_min_rotation : 1,
1278
- // prevent default browser behavior when two touches are on the screen
1279
- // but it makes the element a blocking element
1280
- // when you are using the transform gesture, it is a good practice to set this true
1281
- transform_always_block : false
1282
- },
1283
- triggered: false,
1284
- handler: function transformGesture(ev, inst) {
1285
- // current gesture isnt drag, but dragged is true
1286
- // this means an other gesture is busy. now call dragend
1287
- if(Hammer.detection.current.name != this.name && this.triggered) {
1288
- inst.trigger(this.name +'end', ev);
1289
- this.triggered = false;
1290
- return;
1291
- }
1292
-
1293
- // atleast multitouch
1294
- if(ev.touches.length < 2) {
1295
- return;
1296
- }
1297
-
1298
- // prevent default when two fingers are on the screen
1299
- if(inst.options.transform_always_block) {
1300
- ev.preventDefault();
1301
- }
1302
-
1303
- switch(ev.eventType) {
1304
- case Hammer.EVENT_START:
1305
- this.triggered = false;
1306
- break;
1307
-
1308
- case Hammer.EVENT_MOVE:
1309
- var scale_threshold = Math.abs(1-ev.scale);
1310
- var rotation_threshold = Math.abs(ev.rotation);
1311
-
1312
- // when the distance we moved is too small we skip this gesture
1313
- // or we can be already in dragging
1314
- if(scale_threshold < inst.options.transform_min_scale &&
1315
- rotation_threshold < inst.options.transform_min_rotation) {
1316
- return;
1317
- }
1318
-
1319
- // we are transforming!
1320
- Hammer.detection.current.name = this.name;
1321
-
1322
- // first time, trigger dragstart event
1323
- if(!this.triggered) {
1324
- inst.trigger(this.name +'start', ev);
1325
- this.triggered = true;
1326
- }
1327
-
1328
- inst.trigger(this.name, ev); // basic transform event
1329
-
1330
- // trigger rotate event
1331
- if(rotation_threshold > inst.options.transform_min_rotation) {
1332
- inst.trigger('rotate', ev);
1333
- }
1334
-
1335
- // trigger pinch event
1336
- if(scale_threshold > inst.options.transform_min_scale) {
1337
- inst.trigger('pinch', ev);
1338
- inst.trigger('pinch'+ ((ev.scale < 1) ? 'in' : 'out'), ev);
1339
- }
1340
- break;
1341
-
1342
- case Hammer.EVENT_END:
1343
- // trigger dragend
1344
- if(this.triggered) {
1345
- inst.trigger(this.name +'end', ev);
1346
- }
1347
-
1348
- this.triggered = false;
1349
- break;
1350
- }
1351
- }
1352
- };
1353
-
1354
-
1355
- /**
1356
- * Touch
1357
- * Called as first, tells the user has touched the screen
1358
- * @events touch
1359
- */
1360
- Hammer.gestures.Touch = {
1361
- name: 'touch',
1362
- index: -Infinity,
1363
- defaults: {
1364
- // call preventDefault at touchstart, and makes the element blocking by
1365
- // disabling the scrolling of the page, but it improves gestures like
1366
- // transforming and dragging.
1367
- // be careful with using this, it can be very annoying for users to be stuck
1368
- // on the page
1369
- prevent_default: false,
1370
-
1371
- // disable mouse events, so only touch (or pen!) input triggers events
1372
- prevent_mouseevents: false
1373
- },
1374
- handler: function touchGesture(ev, inst) {
1375
- if(inst.options.prevent_mouseevents && ev.pointerType == Hammer.POINTER_MOUSE) {
1376
- ev.stopDetect();
1377
- return;
1378
- }
1379
-
1380
- if(inst.options.prevent_default) {
1381
- ev.preventDefault();
1382
- }
1383
-
1384
- if(ev.eventType == Hammer.EVENT_START) {
1385
- inst.trigger(this.name, ev);
1386
- }
1387
- }
1388
- };
1389
-
1390
-
1391
- /**
1392
- * Release
1393
- * Called as last, tells the user has released the screen
1394
- * @events release
1395
- */
1396
- Hammer.gestures.Release = {
1397
- name: 'release',
1398
- index: Infinity,
1399
- handler: function releaseGesture(ev, inst) {
1400
- if(ev.eventType == Hammer.EVENT_END) {
1401
- inst.trigger(this.name, ev);
1402
- }
1403
- }
1404
- };
1405
-
1406
- // node export
1407
- if(typeof module === 'object' && typeof module.exports === 'object'){
1408
- module.exports = Hammer;
1409
- }
1410
- // just window export
1411
- else {
1412
- window.Hammer = Hammer;
1413
-
1414
- // requireJS module definition
1415
- if(typeof window.define === 'function' && window.define.amd) {
1416
- window.define('hammer', [], function() {
1417
- return Hammer;
1418
- });
1419
- }
1420
- }
1421
- })(this);
1422
-
1423
- (function($, undefined) {
1424
- 'use strict';
1425
-
1426
- // no jQuery or Zepto!
1427
- if($ === undefined) {
1428
- return;
1429
- }
1430
-
1431
- /**
1432
- * bind dom events
1433
- * this overwrites addEventListener
1434
- * @param {HTMLElement} element
1435
- * @param {String} eventTypes
1436
- * @param {Function} handler
1437
- */
1438
- Hammer.event.bindDom = function(element, eventTypes, handler) {
1439
- $(element).on(eventTypes, function(ev) {
1440
- var data = ev.originalEvent || ev;
1441
-
1442
- // IE pageX fix
1443
- if(data.pageX === undefined) {
1444
- data.pageX = ev.pageX;
1445
- data.pageY = ev.pageY;
1446
- }
1447
-
1448
- // IE target fix
1449
- if(!data.target) {
1450
- data.target = ev.target;
1451
- }
1452
-
1453
- // IE button fix
1454
- if(data.which === undefined) {
1455
- data.which = data.button;
1456
- }
1457
-
1458
- // IE preventDefault
1459
- if(!data.preventDefault) {
1460
- data.preventDefault = ev.preventDefault;
1461
- }
1462
-
1463
- // IE stopPropagation
1464
- if(!data.stopPropagation) {
1465
- data.stopPropagation = ev.stopPropagation;
1466
- }
1467
-
1468
- handler.call(this, data);
1469
- });
1470
- };
1471
-
1472
- /**
1473
- * the methods are called by the instance, but with the jquery plugin
1474
- * we use the jquery event methods instead.
1475
- * @this {Hammer.Instance}
1476
- * @return {jQuery}
1477
- */
1478
- Hammer.Instance.prototype.on = function(types, handler) {
1479
- return $(this.element).on(types, handler);
1480
- };
1481
- Hammer.Instance.prototype.off = function(types, handler) {
1482
- return $(this.element).off(types, handler);
1483
- };
1484
-
1485
-
1486
- /**
1487
- * trigger events
1488
- * this is called by the gestures to trigger an event like 'tap'
1489
- * @this {Hammer.Instance}
1490
- * @param {String} gesture
1491
- * @param {Object} eventData
1492
- * @return {jQuery}
1493
- */
1494
- Hammer.Instance.prototype.trigger = function(gesture, eventData){
1495
- var el = $(this.element);
1496
- if(el.has(eventData.target).length) {
1497
- el = $(eventData.target);
1498
- }
1499
-
1500
- return el.trigger({
1501
- type: gesture,
1502
- gesture: eventData
1503
- });
1504
- };
1505
-
1506
-
1507
- /**
1508
- * jQuery plugin
1509
- * create instance of Hammer and watch for gestures,
1510
- * and when called again you can change the options
1511
- * @param {Object} [options={}]
1512
- * @return {jQuery}
1513
- */
1514
- $.fn.hammer = function(options) {
1515
- return this.each(function() {
1516
- var el = $(this);
1517
- var inst = el.data('hammer');
1518
- // start new hammer instance
1519
- if(!inst) {
1520
- el.data('hammer', new Hammer(this, options || {}));
1521
- }
1522
- // change the options
1523
- else if(inst && options) {
1524
- Hammer.utils.extend(inst.options, options);
1525
- }
1526
- });
1527
- };
1528
-
1529
- })(window.jQuery || window.Zepto);