1 var XUI_GestureUtils = {
\r
3 * get the center of all the touches
\r
4 * @param {Array} touches
\r
5 * @returns {Object} center
\r
7 getCenter : function( touches ){
\r
10 x, y, minX, minY, maxX, maxY;
\r
17 pageX : touches[ 0 ].pageX,
\r
18 pageY : touches[ 0 ].pageY
\r
22 pageX : ( touches[ 0 ].pageX + touches[ 1 ].pageX ) / 2,
\r
23 pageY : ( touches[ 0 ].pageY + touches[ 1 ].pageY ) / 2
\r
26 minX = minY = 1 / 0;
\r
27 maxX = maxY = - 1 / 0;
\r
28 for( ; i < l; ++i ){
\r
29 x = touches[ i ].pageX;
\r
30 minX = x < minX ? x : minX;
\r
31 maxX = maxX < x ? x : maxX;
\r
32 y = touches[ i ].pageY;
\r
33 minY = y < minY ? y : minY;
\r
34 maxY = maxY < y ? y : maxY;
\r
37 pageX : ( minX + maxX ) / 2 | 0,
\r
38 pageY : ( minY + maxY ) / 2 | 0
\r
43 * calculate the velocity between two points
\r
44 * @param {Number} deltaTime
\r
45 * @param {Number} deltaX
\r
46 * @param {Number} deltaY
\r
47 * @returns {Object} velocity
\r
49 getVelocity : function( deltaTime, deltaX, deltaY ) {
\r
51 x : Math.abs( deltaX / deltaTime ) || 0,
\r
52 y : Math.abs( deltaY / deltaTime ) || 0
\r
57 * calculate the angle between two coordinates
\r
58 * @param {Touch} touch1
\r
59 * @param {Touch} touch2
\r
60 * @returns {Number} angle
\r
62 getAngle : function( touch1, touch2 ){
\r
63 var y = touch2.pageY - touch1.pageY,
\r
64 x = touch2.pageX - touch1.pageX;
\r
65 return Math.atan2( y, x ) * 180 / Math.PI;
\r
69 * angle to direction define
\r
70 * @param {Touch} touch1
\r
71 * @param {Touch} touch2
\r
72 * @returns {String} direction constant, like 'left'
\r
74 getDirection : function( touch1, touch2 ){
\r
75 var x = touch1.pageX - touch2.pageX,
\r
76 y = touch1.pageY - touch2.pageY;
\r
77 return Math.abs( y ) <= Math.abs( x ) ?
\r
78 ( x > 0 ? 'left' : 'right' ) :
\r
79 ( y > 0 ? 'up' : 'down' );
\r
83 * calculate the distance between two touches
\r
84 * @param {Touch} touch1
\r
85 * @param {Touch} touch2
\r
86 * @returns {Number} distance
\r
88 getDistance : function( touch1, touch2 ){
\r
89 var x = touch2.pageX - touch1.pageX,
\r
90 y = touch2.pageY - touch1.pageY;
\r
91 return Math.sqrt( ( x * x ) + ( y * y ) );
\r
95 * calculate the scale factor between two touchLists (fingers)
\r
96 * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
\r
97 * @param {Array} start
\r
98 * @param {Array} end
\r
99 * @returns {Number} scale
\r
101 getScale : function( start, end ){
\r
102 // need two fingers...
\r
103 return ( 2 <= start.length && 2 <= end.length ) ?
\r
104 XUI_GestureUtils.getDistance( end[ 0 ], end[ 1 ] ) / XUI_GestureUtils.getDistance( start[ 0 ], start[ 1 ] ) :
\r
109 * calculate the rotation degrees between two touchLists (fingers)
\r
110 * @param {Array} start
\r
111 * @param {Array} end
\r
112 * @returns {Number} rotation
\r
114 getRotation : function getRotation( start, end ){
\r
115 // need two fingers
\r
116 return ( 2 <= start.length && 2 <= end.length ) ?
\r
117 XUI_GestureUtils.getAngle( end[ 1 ], end[ 0 ] ) - XUI_GestureUtils.getAngle( start[ 1 ], start[ 0 ] ) :
\r
122 * boolean if the direction is vertical
\r
123 * @param {String} direction
\r
124 * @returns {Boolean} is_vertical
\r
126 isVertical : function isVertical( direction ){
\r
127 return direction === 'up' || direction === 'down';
\r
131 var XUI_Gesture_POINTERS = {},
\r
132 XUI_Gesture_CAPTURED = {},
\r
133 XUI_Gesture_DEFAULTS = {};
\r
136 function XUI_Gesture_trigger( uinode, type, hammerEvent ){
\r
137 if( !uinode.gestureTypes[ type ] ) return X_CALLBACK_NONE;
\r
138 hammerEvent = X_Object_copy( hammerEvent );
\r
139 hammerEvent.type = type;
\r
140 return uinode[ 'dispatch' ]( hammerEvent ) || X_CALLBACK_NONE;
\r
143 function XUI_$UINodeBase_listen( type, arg1, arg2, arg3 ){
\r
144 var events, gestures, i, g;
\r
146 if( XUI_Event._START_POINTER <= type && type <= XUI_Event._END_POINTER ){
\r
147 if( this.phase < 3 ){
\r
148 if( !( events = this.reserveEvents ) ) this.reserveEvents = events = [];
\r
149 events[ events.length ] = [ type, arg1, arg2, arg3 ];
\r
153 if( this[ 'listening' ]( type, arg1, arg2, arg3 ) ){
\r
157 if( XUI_Event._START_XUI_EVENT < type && type < XUI_Event._END_XUI_EVENT ){
\r
158 gestures = XUI_Gesture_LIST;
\r
159 for( i = gestures.length; i; ){
\r
160 g = gestures[ --i ];
\r
161 if( g.startID <= type && type <= g.endID ){
\r
162 if( !this.gestureActivated ){
\r
163 this.gestureOptions = XUI_Gesture_DEFAULTS; //X_Object_override( X_Object_copy( XUI_Gesture_DEFAULTS ), opt_options );
\r
164 this.gestureActivated = {};
\r
165 this.gestureTypes = {};
\r
166 this.gestureTriggered = {};
\r
167 this.gestureCanceled = {};
\r
169 if( X_Object_isEmpty( this.gestureActivated ) ){
\r
170 this[ 'listen' ]( XUI_Event._POINTER_DOWN, this, XUI_Gesture_handleEvent );
\r
172 this.gestureActivated[ g.name ] = this.gestureTypes[ type ] = true;
\r
177 if( XUI_EVENT_COUNTER[ type ] ){
\r
178 ++XUI_EVENT_COUNTER[ type ];
\r
180 XUI_EVENT_COUNTER[ type ] = 1;
\r
181 XUI_xnodeIneraction[ 'listen' ]( XUI_Event.IdToName[ type ], X_UI_eventRellay );
\r
185 return X_EventDispatcher_listen.apply( this, arguments );
\r
188 function XUI_$UINodeBase_unlisten( type, arg1, arg2, arg3 ){
\r
189 var events, i, ev, gestures, active, g, f;
\r
191 if( XUI_Event._START_POINTER <= type && type <= XUI_Event._END_POINTER ){
\r
192 if( this.phase < 3 ){
\r
193 if( !( events = this.reserveEvents ) ) return this;
\r
194 for( i = events.length; i; ){
\r
195 ev = events[ --i ];
\r
196 if( ev[ 0 ] === type && ev[ 1 ] === arg1 && ev[ 2 ] === arg2 && ev[ 3 ] === arg3 ){
\r
197 events.split( i, 1 );
\r
204 if( !this[ 'listening' ]( type, arg1, arg2, arg3 ) ){
\r
208 if( XUI_Event._START_XUI_EVENT < type && type < XUI_Event._END_XUI_EVENT ){
\r
209 if( active = this.gestureActivated ){
\r
210 gestures = XUI_Gesture_LIST;
\r
211 for( i = gestures.length ; i; ){
\r
212 g = gestures[ --i ];
\r
213 if( g.startID <= type && type <= g.endID ){
\r
214 if( active[ g.name ] ){
\r
215 if( this.gestureTypes[ type ] ) delete this.gestureTypes[ type ];
\r
216 for( i = g.startID; i <= g.endID; ++i ){
\r
217 if( this.gestureTypes[ i ] ){
\r
223 delete active[ g.name ];
\r
225 if( X_Object_isEmpty( active ) ){
\r
226 this[ 'unlisten' ]( XUI_Event._POINTER_DOWN, this, XUI_Gesture_handleEvent );
\r
227 //delete this.gestureTriggered;
\r
228 //delete this.gestureCanceled;
\r
229 //delete this.gestureTypes;
\r
230 //delete this.gestureActivated;
\r
239 if( XUI_EVENT_COUNTER[ type ] === 1 ){
\r
240 XUI_xnodeIneraction[ 'unlisten' ]( XUI_Event.IdToName[ type ], X_UI_eventRellay );
\r
241 XUI_EVENT_COUNTER[ type ] = 0;
\r
243 if( XUI_EVENT_COUNTER[ type ] ){
\r
244 --XUI_EVENT_COUNTER[ type ];
\r
249 return X_EventDispatcher_unlisten.apply( this, arguments );
\r
252 function XUI_Gesture_handleEvent( e ){
\r
253 var gestures = XUI_Gesture_LIST,
\r
255 uid = e[ 'pointerId' ],
\r
256 isStart = type === XUI_Event._POINTER_DOWN,
\r
257 isEnd = type === XUI_Event._POINTER_UP || type === XUI_Event._POINTER_CANCEL || type === XUI_Event.POINTER_OUT,
\r
259 isMouse = e.pointerType === 'mouse',
\r
261 numTouches = 0,// count the total touches on the screen
\r
262 i, p, l, j, captured, hammerEvent, ret, activated, gesture, startEv,
\r
263 deltaTime, deltaX, deltaY, velocity, center, startCenter;
\r
265 if( !isStart && !hammer.gestureStartEvent ) return;
\r
268 if( XUI_Gesture_POINTERS[ uid ] ){
\r
269 delete XUI_Gesture_POINTERS[ uid ];
\r
270 if( XUI_Gesture_CAPTURED[ uid ] ) delete XUI_Gesture_CAPTURED[ uid ];
\r
273 XUI_Gesture_POINTERS[ uid ] = e;
\r
276 // mousebutton must be down or a touch event
\r
277 if( ( isEnd || !isMouse || e.button === 0 ) ){
\r
280 for( i in XUI_Gesture_POINTERS ){
\r
281 if( p = XUI_Gesture_POINTERS[ i ] ){
\r
282 // いずれかの hammer によって束縛されている場合、その束縛している hammer なら
\r
283 captured = XUI_Gesture_CAPTURED[ p[ 'pointerId' ] ];
\r
284 if( captured && captured !== hammer ){
\r
287 touches[ ++numTouches ] = p;
\r
292 // if we are in a end event, but when we remove one touch and
\r
293 // we still have enough, set eventType to move
\r
294 if( !numTouches ){ // no touches, force the end event
\r
298 // because touchend has no touches, and we often want to use these in our gestures,
\r
299 // we send the last move event as our eventData in touchend
\r
300 ( isEnd && hammer.gestureLastMoveEvent ) ? ( e = hammer.gestureLastMoveEvent ) : ( hammer.gestureLastMoveEvent = e ); // store the last move event
\r
302 hammerEvent = X_Object_copy( e );
\r
303 hammerEvent.touches = touches;
\r
305 if( isStart && !hammer.gestureStartEvent ){
\r
306 //console.log( '=- add -=' );
\r
307 // already busy with a Hammer.gesture detection on an element
\r
308 hammer.gestureStartEvent = hammerEvent;
\r
309 XUI_rootData[ 'listen' ]( [ XUI_Event._POINTER_MOVE, XUI_Event._POINTER_UP, XUI_Event._POINTER_CANCEL, XUI_Event.POINTER_OUT ], hammer, XUI_Gesture_handleEvent );
\r
312 startEv = hammer.gestureStartEvent;
\r
315 // if the touches change, set the new touches over the startEvent touches
\r
316 // this because touchevents don't have all the touches on touchstart, or the
\r
317 // user must place his fingers at the EXACT same time on the screen, which is not realistic
\r
318 // but, sometimes it happens that both fingers are touching at the EXACT same time
\r
319 if( startEv && ( numTouches !== startEv.touches.length || touches !== startEv.touches ) ){
\r
320 // extend 1 level deep to get the touchlist with the touch objects
\r
321 startEv.touches.length = i = 0;
\r
323 for( ; i < numTouches; ++i ){
\r
324 startEv.touches[ ++j ] = touches[ i ];
\r
328 deltaTime = hammerEvent.timestamp - startEv.timestamp;
\r
329 center = XUI_GestureUtils.getCenter( touches );
\r
330 startCenter = startEv.center;
\r
331 deltaX = startCenter ? ( center.pageX - startCenter.pageX ) : 0;
\r
332 deltaY = startCenter ? ( center.pageY - startCenter.pageY ) : 0;
\r
333 velocity = XUI_GestureUtils.getVelocity( deltaTime, deltaX, deltaY );
\r
335 X_Object_override( hammerEvent, {
\r
336 type : isEnd ? XUI_Event._POINTER_UP : type,
\r
338 deltaTime : deltaTime,
\r
343 velocityX : velocity.x,
\r
344 velocityY : velocity.y,
\r
347 distance : startCenter ? XUI_GestureUtils.getDistance( startCenter, center ) : 0,
\r
348 angle : startCenter ? XUI_GestureUtils.getAngle( startCenter, center ) : 0,
\r
349 direction : startCenter ? XUI_GestureUtils.getDirection( startCenter, center ) : 0,
\r
351 scale : XUI_GestureUtils.getScale( startEv.touches, touches ),
\r
352 rotation : XUI_GestureUtils.getRotation( startEv.touches, touches ),
\r
354 gestureStartEvent : startEv
\r
357 // store as previous event event
\r
358 hammer.gestureLastEvent = hammerEvent;
\r
359 activated = hammer.gestureActivated;
\r
360 //console.log( '... ' );
\r
361 // call Hammer.gesture handlers
\r
362 for( i = 0, l = gestures.length; i < l; ++i ){
\r
363 gesture = gestures[ i ];
\r
365 if( activated[ gesture.name ] && !hammer.gestureCanceled[ gesture.name ] ){
\r
366 //( console.log( '... ' + i + ' ' + gesture.name ) );
\r
367 // if a handler returns false, we stop with the detection
\r
368 ( ret |= ( gesture.handler( hammerEvent, hammer ) || X_CALLBACK_NONE ) );
\r
371 if( ret & X_CALLBACK_CAPTURE_POINTER ){
\r
372 for( i = touches.length; i; ){
\r
373 uid = touches[ --i ][ 'pointerId' ];
\r
374 XUI_Gesture_CAPTURED[ uid ] = hammer;
\r
375 //console.log( 'captured. ' + uid );
\r
379 if( ret & X_CALLBACK_STOP_NOW ){
\r
383 //console.log( '----' );
\r
388 if( isEnd || ( ret & X_CALLBACK_RELEASE_POINTER ) ){
\r
389 for( i = touches.length; i; ){
\r
390 uid = touches[ --i ][ 'pointerId' ];
\r
391 if( XUI_Gesture_CAPTURED[ uid ] === hammer ){
\r
392 //console.log( 'released. ' + uid );
\r
393 delete XUI_Gesture_CAPTURED[ uid ];
\r
399 //console.log( '=- clear -=' );
\r
400 XUI_rootData[ 'unlisten' ]( [ XUI_Event._POINTER_MOVE, XUI_Event._POINTER_UP, XUI_Event._POINTER_CANCEL, XUI_Event.POINTER_OUT ], hammer, XUI_Gesture_handleEvent );
\r
402 hammer.previous = {
\r
403 gestureCurrentName : hammer.gestureCurrentName,
\r
404 gestureStartEvent : hammer.gestureStartEvent,
\r
405 gestureLastEvent : hammer.gestureLastEvent,
\r
406 gestureLastMoveEvent : hammer.gestureLastMoveEvent
\r
409 X_Object_clear( hammer.gestureTriggered );
\r
410 X_Object_clear( hammer.gestureCanceled );
\r
412 delete hammer.gestureCurrentName;
\r
413 delete hammer.gestureStartEvent;
\r
414 delete hammer.gestureLastEvent;
\r
415 delete hammer.gestureLastMoveEvent;
\r
417 ret |= X_CALLBACK_RELEASE_POINTER;
\r
425 var XUI_Gesture_LIST = [
\r
428 * Called as first, tells the user has touched the screen
\r
435 // call preventDefault at touchstart, and makes the element blocking by
\r
436 // disabling the scrolling of the page, but it improves gestures like
\r
437 // transforming and dragging.
\r
438 // be careful with using this, it can be very annoying for users to be stuck
\r
440 prevent_default : false,
\r
442 // disable mouse events, so only touch (or pen!) input triggers events
\r
443 prevent_mouseevents : false
\r
445 handler : function( e, hammer ){
\r
446 if( hammer.gestureOptions.prevent_mouseevents && e[ 'pointerType' ] === 'mouse' ){
\r
447 return X_CALLBACK_STOP_NOW;
\r
450 //hammer.gestureOptions.prevent_default && e.preventDefault();
\r
452 return e.type === XUI_Event._POINTER_DOWN && XUI_Gesture_trigger( hammer, XUI_Event.TOUCH, e );
\r
458 * User want to scale or rotate with 2 fingers
\r
459 * @events transform, transformstart, transformend, pinch, pinchin, pinchout, rotate
\r
462 name : 'transform',
\r
464 startID : XUI_Event.TRANSFORM,
\r
465 endID : XUI_Event.ROTATE,
\r
467 // factor, no scale is 1, zoomin is to 0 and zoomout until higher then 1
\r
468 transform_min_scale : 0.01,
\r
469 // rotation in degrees
\r
470 transform_min_rotation : 1,
\r
471 // prevent default browser behavior when two touches are on the screen
\r
472 // but it makes the element a blocking element
\r
473 // when you are using the transform gesture, it is a good practice to set this true
\r
474 transform_always_block : false
\r
477 handler : function( e, hammer ){
\r
478 var transform = this, ret = X_CALLBACK_NONE, scale_threshold, rotation_threshold;
\r
480 // current gesture isnt drag, but dragged is true
\r
481 // this means an other gesture is busy. now call dragend
\r
482 if( hammer.gestureCurrentName !== transform.name && hammer.gestureTriggered[ transform.name ] ){
\r
483 ret = XUI_Gesture_trigger( hammer, XUI_Event.TRANSFORM_END, e );
\r
484 delete hammer.gestureTriggered[ transform.name ];
\r
488 // atleast multitouch
\r
489 if( e.touches.length < 2 ) return;
\r
491 // prevent default when two fingers are on the screen
\r
492 //hammer.gestureOptions.transform_always_block && e.preventDefault();
\r
495 case XUI_Event._POINTER_DOWN :
\r
496 //hammer.gestureTriggered[ transform.name ] = false;
\r
499 case XUI_Event._POINTER_MOVE:
\r
500 scale_threshold = Math.abs( 1 - e.scale );
\r
501 rotation_threshold = Math.abs( e.rotation );
\r
503 // when the distance we moved is too small we skip this gesture
\r
504 // or we can be already in dragging
\r
505 if( scale_threshold < hammer.gestureOptions.transform_min_scale && rotation_threshold < hammer.gestureOptions.transform_min_rotation ) return;
\r
507 // we are transforming!
\r
508 hammer.gestureCurrentName = transform.name;
\r
510 // first time, trigger dragstart event
\r
511 if( !hammer.gestureTriggered[ transform.name ] ){
\r
512 ret = XUI_Gesture_trigger( hammer, XUI_Event.TRANSFORM_START, e );
\r
513 if( ret & X_CALLBACK_PREVENT_DEFAULT ){
\r
514 hammer.gestureCanceled[ transform.name ] = true;
\r
517 hammer.gestureTriggered[ transform.name ] = true;
\r
521 ret |= XUI_Gesture_trigger( hammer, XUI_Event.TRANSFORM, e );
\r
522 // basic transform event
\r
524 // trigger rotate event
\r
525 if( hammer.gestureOptions.transform_min_rotation < rotation_threshold ){
\r
526 ret |= XUI_Gesture_trigger( hammer, XUI_Event.ROTATE, e );
\r
529 // trigger pinch event
\r
530 if( scale_threshold > hammer.gestureOptions.transform_min_scale ){
\r
531 ret |= XUI_Gesture_trigger( hammer, XUI_Event.PINCH, e );
\r
532 ret |= XUI_Gesture_trigger( hammer, e.scale < 1 ? XUI_Event.PINCH_IN : XUI_Event.PINCH_OUT, e );
\r
536 case XUI_Event.POINTER_OUT :
\r
537 case XUI_Event._POINTER_CANCEL :
\r
538 case XUI_Event._POINTER_UP :
\r
540 ret = hammer.gestureTriggered[ transform.name ] && XUI_Gesture_trigger( hammer, XUI_Event.TRANSFORM_END, e );
\r
541 hammer.gestureTriggered[ transform.name ] = false;
\r
550 * Move with x fingers (default 1) around on the page. Blocking the scrolling when
\r
551 * moving left and right is a good practice. When all the drag events are blocking
\r
552 * you disable scrolling on that area.
\r
553 * @events drag, dragstart, dragend, drapleft, dragright, dragup, dragdown
\r
558 startID : XUI_Event.DRAG,
\r
559 endID : XUI_Event.DRAG_DOWN,
\r
562 drag_min_distance : 10,
\r
563 // set 0 for unlimited, but this can conflict with transform
\r
564 drag_max_touches : 1,
\r
565 // prevent default browser behavior when dragging occurs
\r
566 // be careful with it, it makes the element a blocking element
\r
567 // when you are using the drag gesture, it is a good practice to set this true
\r
568 drag_block_horizontal : false,
\r
569 drag_block_vertical : false,
\r
570 // drag_lock_to_axis keeps the drag gesture on the axis that it started on,
\r
571 // It disallows vertical directions if the initial direction was horizontal, and vice versa.
\r
572 drag_lock_to_axis : false,
\r
573 // drag lock only kicks in when distance > drag_lock_min_distance
\r
574 // This way, locking occurs only when the distance has become large enough to reliably determine the direction
\r
575 drag_lock_min_distance : 25
\r
578 handler : function( e, hammer ){
\r
579 var drag = this, last_direction, ret;
\r
581 // current gesture isnt drag, but dragged is true
\r
582 // this means an other gesture is busy. now call dragend
\r
583 if( hammer.gestureCurrentName !== drag.name && hammer.gestureTriggered[ drag.name ] ){
\r
584 ret = XUI_Gesture_trigger( hammer, XUI_Event.DRAG_END, e );
\r
585 hammer.gestureTriggered[ drag.name ] = false;
\r
590 if( 0 < hammer.gestureOptions.drag_max_touches && hammer.gestureOptions.drag_max_touches < e.touches.length ) return;
\r
593 case XUI_Event._POINTER_DOWN :
\r
594 hammer.gestureTriggered[ drag.name ] = false;
\r
597 case XUI_Event._POINTER_MOVE :
\r
598 // when the distance we moved is too small we skip this gesture
\r
599 // or we can be already in dragging
\r
600 if( e.distance < hammer.gestureOptions.drag_min_distance && hammer.gestureCurrentName !== drag.name ) return;
\r
602 // we are dragging!
\r
603 hammer.gestureCurrentName = drag.name;
\r
605 // lock drag to axis?
\r
606 if( hammer.gestureLastEvent.drag_locked_to_axis || ( hammer.gestureOptions.drag_lock_to_axis && hammer.gestureOptions.drag_lock_min_distance <= e.distance ) ){
\r
607 e.drag_locked_to_axis = true;
\r
609 last_direction = hammer.gestureLastEvent.direction;
\r
610 if( e.drag_locked_to_axis && last_direction !== e.direction ){
\r
611 // keep direction on the axis that the drag gesture started on
\r
612 e.direction = XUI_GestureUtils.isVertical( last_direction ) ?
\r
613 ( e.deltaY < 0 ? 'up' : 'down' ) :
\r
614 ( e.deltaX < 0 ? 'left' : 'right' );
\r
617 ret = X_CALLBACK_NONE;
\r
619 // first time, trigger dragstart event
\r
620 if( !hammer.gestureTriggered[ drag.name ] ){
\r
621 ret = XUI_Gesture_trigger( hammer, XUI_Event.DRAG_START, e );
\r
622 //if( ret & X_CALLBACK_PREVENT_DEFAULT ){
\r
623 // hammer.gestureCanceled[ drag.name ] = true;
\r
626 ret |= X_CALLBACK_CAPTURE_POINTER;
\r
627 //console.log( '----- drag start ....' + e.type );
\r
628 hammer.gestureTriggered[ drag.name ] = true;
\r
632 //console.log( '----- drag ....' + e.type );
\r
633 // trigger normal event
\r
634 ret = XUI_Gesture_trigger( hammer, XUI_Event.DRAG, e ) | X_CALLBACK_CAPTURE_POINTER;
\r
636 // direction event, like dragdown
\r
637 ret |= XUI_Gesture_trigger( hammer,
\r
638 e.direction === 'up' ?
\r
639 XUI_Event.DRAG_UP :
\r
640 e.direction === 'down' ?
\r
641 XUI_Event.DRAG_DOWN :
\r
642 e.direction === 'left' ?
\r
643 XUI_Event.DRAG_LEFT :
\r
644 XUI_Event.DRAG_RIGHT,
\r
648 // block the browser events
\r
650 ( hammer.gestureOptions.drag_block_vertical && XUI_GestureUtils.isVertical( e.direction ) ) ||
\r
651 ( hammer.gestureOptions.drag_block_horizontal && !XUI_GestureUtils.isVertical( e.direction ) )
\r
652 ) && e.preventDefault(); */
\r
655 case XUI_Event.POINTER_OUT :
\r
656 //console.log( 'cancel!!' );
\r
657 case XUI_Event._POINTER_CANCEL :
\r
658 case XUI_Event._POINTER_UP:
\r
660 if( hammer.gestureTriggered[ drag.name ] ){
\r
661 ret = XUI_Gesture_trigger( hammer, XUI_Event.DRAG_END, e ) | X_CALLBACK_CAPTURE_POINTER;
\r
662 //console.log( '----- drag end ....' + e.type );
\r
663 hammer.gestureTriggered[ drag.name ] = false;
\r
673 * Quick touch at a place or double at the same place
\r
674 * @events tap, doubletap
\r
679 startID : XUI_Event.TAP,
\r
680 endID : XUI_Event.DOUBLE_TAP,
\r
682 tap_max_touchtime : 250,
\r
683 tap_max_distance : 3,
\r
685 doubletap_distance : 20,
\r
686 doubletap_interval : 300
\r
688 handler : function( e, hammer ){
\r
689 // previous gesture, for the double tap since these are two different gesture detections
\r
690 var prev = hammer.previous;
\r
692 if( e.type === XUI_Event._POINTER_MOVE && hammer.gestureOptions.tap_max_distance < e.distance ){
\r
693 hammer.gestureCanceled[ 'tap' ] = true;
\r
695 if( e.type === XUI_Event._POINTER_UP ){
\r
696 // when the touchtime is higher then the max touch time
\r
697 // or when the moving distance is too much
\r
698 if( hammer.gestureOptions.tap_max_touchtime < e.deltaTime || hammer.gestureOptions.tap_max_distance < e.distance ) return;
\r
700 // check if double tap
\r
701 if( prev && prev.gestureCurrentName === 'tap' && ( e.timestamp - prev.gestureLastEvent.timestamp ) < hammer.gestureOptions.doubletap_interval && e.distance < hammer.gestureOptions.doubletap_distance ){
\r
702 return XUI_Gesture_trigger( hammer, XUI_Event.DOUBLE_TAP, e );
\r
705 if( hammer.gestureOptions.tap_always ){
\r
706 hammer.gestureCurrentName = 'tap';
\r
707 //console.log( 'tap! ' + e.deltaTime + 'ms ' + e.type );
\r
708 return XUI_Gesture_trigger( hammer, XUI_Event.TAP, e );
\r
718 g = XUI_Gesture_LIST[ --i ];
\r
719 X_Object_override( XUI_Gesture_DEFAULTS, g.defaults );
\r
722 })( XUI_Gesture_LIST.length );
\r