2013-05-01 08:46:16 +04:00
/ *
2013-05-14 08:00:24 +04:00
* OpenSeadragon - MouseTracker
2013-05-01 08:46:16 +04:00
*
* Copyright ( C ) 2009 CodePlex Foundation
2013-05-14 07:32:09 +04:00
* Copyright ( C ) 2010 - 2013 OpenSeadragon contributors
2013-05-01 08:46:16 +04:00
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are
* met :
*
* - Redistributions of source code must retain the above copyright notice ,
* this list of conditions and the following disclaimer .
*
* - Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
*
* - Neither the name of CodePlex Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED
* TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR
* PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* /
2013-09-06 04:20:17 +04:00
( function ( $ ) {
2013-09-06 21:43:39 +04:00
// dictionary from hash to private properties
2014-04-15 05:17:18 +04:00
var THIS = { } ;
2011-12-06 07:50:25 +04:00
2014-03-21 22:45:20 +04:00
2012-01-25 23:14:02 +04:00
/ * *
2013-11-16 10:19:53 +04:00
* @ class MouseTracker
2014-04-22 20:23:56 +04:00
* @ classdesc Provides simplified handling of common pointer device ( mouse , touch , pen , etc . ) gestures
* and keyboard events on a specified element .
2013-11-16 10:19:53 +04:00
* @ memberof OpenSeadragon
2013-09-06 21:43:39 +04:00
* @ param { Object } options
* Allows configurable properties to be entirely specified by passing
* an options object to the constructor . The constructor also supports
2013-11-25 20:48:44 +04:00
* the original positional arguments 'element' , 'clickTimeThreshold' ,
2013-09-06 21:43:39 +04:00
* and 'clickDistThreshold' in that order .
* @ param { Element | String } options . element
2014-04-01 20:32:04 +04:00
* A reference to an element or an element id for which the pointer / key
2013-09-06 21:43:39 +04:00
* events will be monitored .
* @ param { Number } options . clickTimeThreshold
2014-04-22 20:23:56 +04:00
* The number of milliseconds within which a pointer down - up event combination
* will be treated as a click gesture .
2013-09-06 21:43:39 +04:00
* @ param { Number } options . clickDistThreshold
2014-04-22 20:23:56 +04:00
* The maximum distance allowed between a pointer down event and a pointer up event
* to be treated as a click gesture .
* @ param { Number } options . dblClickTimeThreshold
* The number of milliseconds within which two pointer down - up event combinations
* will be treated as a double - click gesture .
* @ param { Number } options . dblClickDistThreshold
* The maximum distance allowed between two pointer click events
* to be treated as a click gesture .
2013-11-25 20:48:44 +04:00
* @ param { Number } [ options . stopDelay = 50 ]
2014-04-01 20:32:04 +04:00
* The number of milliseconds without pointer move before the stop
2013-10-23 00:54:04 +04:00
* event is fired .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . enterHandler = null ]
2014-04-01 20:32:04 +04:00
* An optional handler for pointer enter .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . exitHandler = null ]
2014-04-01 20:32:04 +04:00
* An optional handler for pointer exit .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . pressHandler = null ]
2014-04-01 20:32:04 +04:00
* An optional handler for pointer press .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . releaseHandler = null ]
2014-04-01 20:32:04 +04:00
* An optional handler for pointer release .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . moveHandler = null ]
2014-04-01 20:32:04 +04:00
* An optional handler for pointer move .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . scrollHandler = null ]
2014-04-01 20:32:04 +04:00
* An optional handler for mouse wheel scroll .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . clickHandler = null ]
2014-04-01 20:32:04 +04:00
* An optional handler for pointer click .
2014-04-22 20:23:56 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . dblClickHandler = null ]
* An optional handler for pointer double - click .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . dragHandler = null ]
2014-03-10 22:49:51 +04:00
* An optional handler for the drag gesture .
2014-03-30 04:02:24 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . dragEndHandler = null ]
* An optional handler for after a drag gesture .
2014-03-10 22:49:51 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . pinchHandler = null ]
* An optional handler for the pinch gesture .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . keyHandler = null ]
2013-09-06 21:43:39 +04:00
* An optional handler for keypress .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . focusHandler = null ]
2013-09-06 21:43:39 +04:00
* An optional handler for focus .
2013-11-25 20:48:44 +04:00
* @ param { OpenSeadragon . EventHandler } [ options . blurHandler = null ]
2013-09-06 21:43:39 +04:00
* An optional handler for blur .
2013-09-12 21:05:50 +04:00
* @ param { Object } [ options . userData = null ]
* Arbitrary object to be passed unchanged to any attached handler methods .
2013-09-06 21:43:39 +04:00
* /
2012-02-03 04:12:45 +04:00
$ . MouseTracker = function ( options ) {
2013-09-06 04:20:17 +04:00
var args = arguments ;
2012-02-03 04:12:45 +04:00
2013-09-06 04:20:17 +04:00
if ( ! $ . isPlainObject ( options ) ) {
2012-02-03 04:12:45 +04:00
options = {
2013-09-20 20:58:18 +04:00
element : args [ 0 ] ,
clickTimeThreshold : args [ 1 ] ,
clickDistThreshold : args [ 2 ]
2012-02-03 04:12:45 +04:00
} ;
}
2013-11-25 20:48:44 +04:00
this . hash = Math . random ( ) ; // An unique hash for this tracker.
/ * *
2014-04-01 20:32:04 +04:00
* The element for which pointer events are being monitored .
2013-11-25 20:48:44 +04:00
* @ member { Element } element
* @ memberof OpenSeadragon . MouseTracker #
* /
2012-02-03 04:12:45 +04:00
this . element = $ . getElement ( options . element ) ;
2013-11-25 20:48:44 +04:00
/ * *
2014-04-22 20:23:56 +04:00
* The number of milliseconds within which a pointer down - up event combination
* will be treated as a click gesture .
2013-11-25 20:48:44 +04:00
* @ member { Number } clickTimeThreshold
* @ memberof OpenSeadragon . MouseTracker #
* /
2014-08-06 00:56:18 +04:00
this . clickTimeThreshold = options . clickTimeThreshold || $ . DEFAULT _SETTINGS . clickTimeThreshold ;
2013-11-25 20:48:44 +04:00
/ * *
2014-04-22 20:23:56 +04:00
* The maximum distance allowed between a pointer down event and a pointer up event
* to be treated as a click gesture .
2013-11-25 20:48:44 +04:00
* @ member { Number } clickDistThreshold
* @ memberof OpenSeadragon . MouseTracker #
* /
2014-08-06 00:56:18 +04:00
this . clickDistThreshold = options . clickDistThreshold || $ . DEFAULT _SETTINGS . clickDistThreshold ;
2014-04-22 20:23:56 +04:00
/ * *
* The number of milliseconds within which two pointer down - up event combinations
* will be treated as a double - click gesture .
* @ member { Number } dblClickTimeThreshold
* @ memberof OpenSeadragon . MouseTracker #
* /
2014-08-06 00:56:18 +04:00
this . dblClickTimeThreshold = options . dblClickTimeThreshold || $ . DEFAULT _SETTINGS . dblClickTimeThreshold ;
2014-04-22 20:23:56 +04:00
/ * *
* The maximum distance allowed between two pointer click events
* to be treated as a click gesture .
* @ member { Number } clickDistThreshold
* @ memberof OpenSeadragon . MouseTracker #
* /
2014-08-06 00:56:18 +04:00
this . dblClickDistThreshold = options . dblClickDistThreshold || $ . DEFAULT _SETTINGS . dblClickDistThreshold ;
2014-04-22 20:23:56 +04:00
this . userData = options . userData || null ;
this . stopDelay = options . stopDelay || 50 ;
this . enterHandler = options . enterHandler || null ;
this . exitHandler = options . exitHandler || null ;
this . pressHandler = options . pressHandler || null ;
this . releaseHandler = options . releaseHandler || null ;
this . moveHandler = options . moveHandler || null ;
this . scrollHandler = options . scrollHandler || null ;
this . clickHandler = options . clickHandler || null ;
this . dblClickHandler = options . dblClickHandler || null ;
this . dragHandler = options . dragHandler || null ;
this . dragEndHandler = options . dragEndHandler || null ;
this . pinchHandler = options . pinchHandler || null ;
this . stopHandler = options . stopHandler || null ;
this . keyHandler = options . keyHandler || null ;
this . focusHandler = options . focusHandler || null ;
this . blurHandler = options . blurHandler || null ;
2012-02-03 04:12:45 +04:00
//Store private properties in a scope sealed hash map
var _this = this ;
2012-02-10 07:16:09 +04:00
2012-02-03 04:12:45 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* @ private
* @ property { Boolean } tracking
2014-04-15 05:17:18 +04:00
* Are we currently tracking pointer events for this element .
2013-09-06 21:43:39 +04:00
* @ property { Boolean } capturing
2014-04-01 20:32:04 +04:00
* Are we curruently capturing mouse events ( legacy mouse events only ) .
2013-09-06 21:43:39 +04:00
* /
2013-09-20 20:58:18 +04:00
THIS [ this . hash ] = {
2014-03-10 22:49:51 +04:00
click : function ( event ) { onClick ( _this , event ) ; } ,
2014-04-22 20:23:56 +04:00
dblclick : function ( event ) { onDblClick ( _this , event ) ; } ,
2014-03-10 22:49:51 +04:00
keypress : function ( event ) { onKeyPress ( _this , event ) ; } ,
focus : function ( event ) { onFocus ( _this , event ) ; } ,
blur : function ( event ) { onBlur ( _this , event ) ; } ,
2014-03-21 22:45:20 +04:00
2013-10-23 23:58:36 +04:00
wheel : function ( event ) { onWheel ( _this , event ) ; } ,
mousewheel : function ( event ) { onMouseWheel ( _this , event ) ; } ,
DOMMouseScroll : function ( event ) { onMouseWheel ( _this , event ) ; } ,
2013-10-25 00:39:00 +04:00
MozMousePixelScroll : function ( event ) { onMouseWheel ( _this , event ) ; } ,
2014-03-21 22:45:20 +04:00
2014-04-16 00:04:08 +04:00
mouseover : function ( event ) { onMouseOver ( _this , event ) ; } ,
mouseout : function ( event ) { onMouseOut ( _this , event ) ; } ,
2014-03-21 22:45:20 +04:00
mousedown : function ( event ) { onMouseDown ( _this , event ) ; } ,
mouseup : function ( event ) { onMouseUp ( _this , event ) ; } ,
mouseupcaptured : function ( event ) { onMouseUpCaptured ( _this , event ) ; } ,
mousemove : function ( event ) { onMouseMove ( _this , event ) ; } ,
mousemovecaptured : function ( event ) { onMouseMoveCaptured ( _this , event ) ; } ,
2014-09-13 03:22:55 +04:00
2014-03-21 22:45:20 +04:00
touchenter : function ( event ) { onTouchEnter ( _this , event ) ; } ,
touchleave : function ( event ) { onTouchLeave ( _this , event ) ; } ,
touchstart : function ( event ) { onTouchStart ( _this , event ) ; } ,
touchend : function ( event ) { onTouchEnd ( _this , event ) ; } ,
touchmove : function ( event ) { onTouchMove ( _this , event ) ; } ,
touchcancel : function ( event ) { onTouchCancel ( _this , event ) ; } ,
gesturestart : function ( event ) { onGestureStart ( _this , event ) ; } ,
gesturechange : function ( event ) { onGestureChange ( _this , event ) ; } ,
2014-08-05 08:41:07 +04:00
pointerover : function ( event ) { onPointerOver ( _this , event ) ; } ,
MSPointerOver : function ( event ) { onPointerOver ( _this , event ) ; } ,
pointerout : function ( event ) { onPointerOut ( _this , event ) ; } ,
MSPointerOut : function ( event ) { onPointerOut ( _this , event ) ; } ,
2014-09-24 01:31:53 +04:00
2014-03-10 22:49:51 +04:00
pointerdown : function ( event ) { onPointerDown ( _this , event ) ; } ,
MSPointerDown : function ( event ) { onPointerDown ( _this , event ) ; } ,
pointerup : function ( event ) { onPointerUp ( _this , event ) ; } ,
MSPointerUp : function ( event ) { onPointerUp ( _this , event ) ; } ,
pointermove : function ( event ) { onPointerMove ( _this , event ) ; } ,
MSPointerMove : function ( event ) { onPointerMove ( _this , event ) ; } ,
pointercancel : function ( event ) { onPointerCancel ( _this , event ) ; } ,
MSPointerCancel : function ( event ) { onPointerCancel ( _this , event ) ; } ,
2014-08-05 08:41:07 +04:00
pointerupcaptured : function ( event ) { onPointerUpCaptured ( _this , event ) ; } ,
pointermovecaptured : function ( event ) { onPointerMoveCaptured ( _this , event ) ; } ,
2014-03-21 22:45:20 +04:00
tracking : false ,
2014-04-15 05:17:18 +04:00
// Active pointers lists. Array of GesturePointList objects, one for each pointer device type.
// GesturePointList objects are added each time a pointer is tracked by a new pointer device type (see getActivePointersListByType()).
// Active pointers are any pointer being tracked for this element which are in the hit-test area
// of the element (for hover-capable devices) and/or have contact or a button press initiated in the element.
activePointersLists : [ ] ,
2014-08-06 00:56:18 +04:00
// Legacy mouse capture tracking
2013-09-10 01:27:58 +04:00
capturing : false ,
2014-03-31 23:54:37 +04:00
2014-08-06 00:56:18 +04:00
// Pointer event model capture tracking
pointerCaptureCount : 0 ,
2014-04-22 20:23:56 +04:00
// Tracking for double-click gesture
lastClickPos : null ,
dblClickTimeOut : null ,
2014-03-10 22:49:51 +04:00
// Tracking for pinch gesture
2014-03-21 22:45:20 +04:00
pinchGPoints : [ ] ,
2014-03-10 22:49:51 +04:00
lastPinchDist : 0 ,
currentPinchDist : 0 ,
2014-03-15 01:15:09 +04:00
lastPinchCenter : null ,
2014-03-30 04:02:24 +04:00
currentPinchCenter : null
2012-02-02 01:56:04 +04:00
} ;
} ;
2011-12-06 07:50:25 +04:00
2013-11-16 10:19:53 +04:00
$ . MouseTracker . prototype = /** @lends OpenSeadragon.MouseTracker.prototype */ {
2011-12-06 07:50:25 +04:00
2013-08-08 11:49:24 +04:00
/ * *
2014-04-01 20:32:04 +04:00
* Clean up any events or objects created by the tracker .
2013-09-06 21:43:39 +04:00
* @ function
* /
2013-09-06 04:20:17 +04:00
destroy : function ( ) {
2013-08-08 11:49:24 +04:00
stopTracking ( this ) ;
this . element = null ;
2014-06-18 21:35:23 +04:00
THIS [ this . hash ] = null ;
delete THIS [ this . hash ] ;
2013-08-08 11:49:24 +04:00
} ,
2012-02-02 01:56:04 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* Are we currently tracking events on this element .
* @ deprecated Just use this . tracking
* @ function
* @ returns { Boolean } Are we currently tracking events on this element .
* /
2012-02-02 01:56:04 +04:00
isTracking : function ( ) {
2013-09-20 20:58:18 +04:00
return THIS [ this . hash ] . tracking ;
2012-02-02 01:56:04 +04:00
} ,
/ * *
2013-09-06 21:43:39 +04:00
* Enable or disable whether or not we are tracking events on this element .
* @ function
* @ param { Boolean } track True to start tracking , false to stop tracking .
* @ returns { OpenSeadragon . MouseTracker } Chainable .
* /
2012-02-02 01:56:04 +04:00
setTracking : function ( track ) {
if ( track ) {
2012-02-03 04:12:45 +04:00
startTracking ( this ) ;
2011-12-14 05:04:38 +04:00
} else {
2012-02-03 04:12:45 +04:00
stopTracking ( this ) ;
2011-12-14 05:04:38 +04:00
}
2012-02-03 04:12:45 +04:00
//chain
return this ;
2012-02-02 01:56:04 +04:00
} ,
2013-06-19 21:33:25 +04:00
2014-04-15 05:17:18 +04:00
/ * *
* Returns the { @ link OpenSeadragon . MouseTracker . GesturePointList | GesturePointList } for the given pointer device type ,
* creating and caching a new { @ link OpenSeadragon . MouseTracker . GesturePointList | GesturePointList } if one doesn ' t already exist for the type .
* @ function
* @ param { String } type - The pointer device type : "mouse" , "touch" , "pen" , etc .
* @ returns { OpenSeadragon . MouseTracker . GesturePointList }
* /
getActivePointersListByType : function ( type ) {
var delegate = THIS [ this . hash ] ,
i ,
len = delegate . activePointersLists . length ,
list ;
for ( i = 0 ; i < len ; i ++ ) {
if ( delegate . activePointersLists [ i ] . type === type ) {
return delegate . activePointersLists [ i ] ;
}
}
list = new $ . MouseTracker . GesturePointList ( type ) ;
delegate . activePointersLists . push ( list ) ;
return list ;
} ,
2012-02-02 01:56:04 +04:00
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2013-10-11 04:00:15 +04:00
* @ param { OpenSeadragon . Point } event . position
2013-09-12 21:05:50 +04:00
* The position of the event relative to the tracked element .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . buttons
* Current buttons pressed .
* Combination of bit flags 0 : none , 1 : primary ( or touch contact ) , 2 : secondary , 4 : aux ( often middle ) , 8 : X1 ( often back ) , 16 : X2 ( often forward ) , 32 : pen eraser .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . insideElementPressed
2013-09-12 21:05:50 +04:00
* True if the left mouse button is currently being pressed and was
* initiated inside the tracked element , otherwise false .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . buttonDownAny
2014-04-15 05:17:18 +04:00
* Was the button down anywhere in the screen during the event . < span style = "color:red;" > Deprecated . Use buttons instead . < / s p a n >
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . isTouchEvent
2014-03-21 22:45:20 +04:00
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . < / s p a n >
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
enterHandler : function ( ) { } ,
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2013-10-11 04:00:15 +04:00
* @ param { OpenSeadragon . Point } event . position
2013-09-12 21:05:50 +04:00
* The position of the event relative to the tracked element .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . buttons
* Current buttons pressed .
* Combination of bit flags 0 : none , 1 : primary ( or touch contact ) , 2 : secondary , 4 : aux ( often middle ) , 8 : X1 ( often back ) , 16 : X2 ( often forward ) , 32 : pen eraser .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . insideElementPressed
2013-09-12 21:05:50 +04:00
* True if the left mouse button is currently being pressed and was
* initiated inside the tracked element , otherwise false .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . buttonDownAny
2014-04-15 05:17:18 +04:00
* Was the button down anywhere in the screen during the event . < span style = "color:red;" > Deprecated . Use buttons instead . < / s p a n >
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . isTouchEvent
2014-03-21 22:45:20 +04:00
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . < / s p a n >
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
exitHandler : function ( ) { } ,
2011-12-06 07:50:25 +04:00
2012-02-02 01:56:04 +04:00
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2013-10-11 04:00:15 +04:00
* @ param { OpenSeadragon . Point } event . position
2013-09-12 21:05:50 +04:00
* The position of the event relative to the tracked element .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . buttons
* Current buttons pressed .
* Combination of bit flags 0 : none , 1 : primary ( or touch contact ) , 2 : secondary , 4 : aux ( often middle ) , 8 : X1 ( often back ) , 16 : X2 ( often forward ) , 32 : pen eraser .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . isTouchEvent
2014-03-21 22:45:20 +04:00
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . < / s p a n >
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
pressHandler : function ( ) { } ,
2012-02-02 01:56:04 +04:00
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2013-10-11 04:00:15 +04:00
* @ param { OpenSeadragon . Point } event . position
2013-09-12 21:05:50 +04:00
* The position of the event relative to the tracked element .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . buttons
* Current buttons pressed .
* Combination of bit flags 0 : none , 1 : primary ( or touch contact ) , 2 : secondary , 4 : aux ( often middle ) , 8 : X1 ( often back ) , 16 : X2 ( often forward ) , 32 : pen eraser .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . insideElementPressed
2013-09-12 21:05:50 +04:00
* True if the left mouse button is currently being pressed and was
* initiated inside the tracked element , otherwise false .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . insideElementReleased
2014-04-15 05:17:18 +04:00
* True if the cursor inside the tracked element when the button was released .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . isTouchEvent
2014-03-21 22:45:20 +04:00
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . < / s p a n >
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
releaseHandler : function ( ) { } ,
2011-12-06 07:50:25 +04:00
2012-02-02 01:56:04 +04:00
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2013-10-11 04:00:15 +04:00
* @ param { OpenSeadragon . Point } event . position
2013-09-12 21:05:50 +04:00
* The position of the event relative to the tracked element .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . buttons
* Current buttons pressed .
* Combination of bit flags 0 : none , 1 : primary ( or touch contact ) , 2 : secondary , 4 : aux ( often middle ) , 8 : X1 ( often back ) , 16 : X2 ( often forward ) , 32 : pen eraser .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . isTouchEvent
2014-03-21 22:45:20 +04:00
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . < / s p a n >
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
moveHandler : function ( ) { } ,
2011-12-06 07:50:25 +04:00
2012-02-02 01:56:04 +04:00
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2013-10-11 04:00:15 +04:00
* @ param { OpenSeadragon . Point } event . position
2013-09-12 21:05:50 +04:00
* The position of the event relative to the tracked element .
2013-10-11 04:00:15 +04:00
* @ param { Number } event . scroll
2013-09-12 21:05:50 +04:00
* The scroll delta for the event .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . shift
2013-09-12 21:05:50 +04:00
* True if the shift key was pressed during this event .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . isTouchEvent
2014-03-21 22:45:20 +04:00
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . Touch devices no longer generate scroll event . < / s p a n >
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
scrollHandler : function ( ) { } ,
2011-12-06 07:50:25 +04:00
2012-02-02 01:56:04 +04:00
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2013-10-11 04:00:15 +04:00
* @ param { OpenSeadragon . Point } event . position
2013-09-12 21:05:50 +04:00
* The position of the event relative to the tracked element .
2014-04-15 05:17:18 +04:00
* @ param { Boolean } event . quick
2014-04-22 20:23:56 +04:00
* True only if the clickDistThreshold and clickTimeThreshold are both passed . Useful for ignoring drag events .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . shift
2013-09-12 21:05:50 +04:00
* True if the shift key was pressed during this event .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . isTouchEvent
2014-03-21 22:45:20 +04:00
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . < / s p a n >
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
clickHandler : function ( ) { } ,
2011-12-06 07:50:25 +04:00
2014-04-22 20:23:56 +04:00
/ * *
* Implement or assign implementation to these handlers during or after
* calling the constructor .
* @ function
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
* A reference to the tracker instance .
* @ param { String } event . pointerType
* "mouse" , "touch" , "pen" , etc .
* @ param { OpenSeadragon . Point } event . position
* The position of the event relative to the tracked element .
* @ param { Boolean } event . shift
* True if the shift key was pressed during this event .
* @ param { Boolean } event . isTouchEvent
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . < / s p a n >
* @ param { Object } event . originalEvent
* The original event object .
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
* @ param { Object } event . userData
* Arbitrary user - defined object .
* /
dblClickHandler : function ( ) { } ,
2012-02-02 01:56:04 +04:00
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2013-10-11 04:00:15 +04:00
* @ param { OpenSeadragon . Point } event . position
2013-09-12 21:05:50 +04:00
* The position of the event relative to the tracked element .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . buttons
* Current buttons pressed .
* Combination of bit flags 0 : none , 1 : primary ( or touch contact ) , 2 : secondary , 4 : aux ( often middle ) , 8 : X1 ( often back ) , 16 : X2 ( often forward ) , 32 : pen eraser .
2013-10-11 04:00:15 +04:00
* @ param { OpenSeadragon . Point } event . delta
2014-03-30 04:02:24 +04:00
* The x , y components of the difference between the current position and the last drag event position . Useful for ignoring or weighting the events .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . speed
2014-03-30 04:02:24 +04:00
* Current computed speed , in pixels per second .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . direction
2014-03-30 04:02:24 +04:00
* Current computed direction , expressed as an angle counterclockwise relative to the positive X axis ( - pi to pi , in radians ) . Only valid if speed > 0.
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . shift
2013-09-12 21:05:50 +04:00
* True if the shift key was pressed during this event .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . isTouchEvent
2014-03-21 22:45:20 +04:00
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . < / s p a n >
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
dragHandler : function ( ) { } ,
2011-12-06 07:50:25 +04:00
2014-03-10 22:49:51 +04:00
/ * *
* Implement or assign implementation to these handlers during or after
* calling the constructor .
* @ function
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2014-03-10 22:49:51 +04:00
* @ param { OpenSeadragon . Point } event . position
* The position of the event relative to the tracked element .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . speed
2014-03-30 04:02:24 +04:00
* Speed at the end of a drag gesture , in pixels per second .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . direction
2014-03-30 04:02:24 +04:00
* Direction at the end of a drag gesture , expressed as an angle counterclockwise relative to the positive X axis ( - pi to pi , in radians ) . Only valid if speed > 0.
2014-03-10 22:49:51 +04:00
* @ param { Boolean } event . shift
* True if the shift key was pressed during this event .
* @ param { Boolean } event . isTouchEvent
2014-03-21 22:45:20 +04:00
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . < / s p a n >
2014-03-10 22:49:51 +04:00
* @ param { Object } event . originalEvent
* The original event object .
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
* @ param { Object } event . userData
* Arbitrary user - defined object .
* /
2014-03-30 04:02:24 +04:00
dragEndHandler : function ( ) { } ,
2014-03-10 22:49:51 +04:00
/ * *
* Implement or assign implementation to these handlers during or after
* calling the constructor .
* @ function
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2014-03-30 04:02:24 +04:00
* @ param { Array . < OpenSeadragon . MouseTracker . GesturePoint > } event . gesturePoints
* Gesture points associated with the gesture . Velocity data can be found here .
* @ param { OpenSeadragon . Point } event . lastCenter
* The previous center point of the two pinch contact points relative to the tracked element .
* @ param { OpenSeadragon . Point } event . center
* The center point of the two pinch contact points relative to the tracked element .
* @ param { Number } event . lastDistance
* The previous distance between the two pinch contact points in CSS pixels .
* @ param { Number } event . distance
* The distance between the two pinch contact points in CSS pixels .
2014-03-10 22:49:51 +04:00
* @ param { Boolean } event . shift
* True if the shift key was pressed during this event .
* @ param { Object } event . originalEvent
* The original event object .
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
* @ param { Object } event . userData
* Arbitrary user - defined object .
* /
2014-03-30 04:02:24 +04:00
pinchHandler : function ( ) { } ,
2014-03-10 22:49:51 +04:00
2012-03-16 19:36:28 +04:00
/ * *
2013-10-23 00:54:04 +04:00
* Implement or assign implementation to these handlers during or after
* calling the constructor .
* @ function
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
* A reference to the tracker instance .
2014-03-30 04:02:24 +04:00
* @ param { String } event . pointerType
2014-04-15 05:17:18 +04:00
* "mouse" , "touch" , "pen" , etc .
2013-10-23 00:54:04 +04:00
* @ param { OpenSeadragon . Point } event . position
* The position of the event relative to the tracked element .
2014-04-15 05:17:18 +04:00
* @ param { Number } event . buttons
* Current buttons pressed .
* Combination of bit flags 0 : none , 1 : primary ( or touch contact ) , 2 : secondary , 4 : aux ( often middle ) , 8 : X1 ( often back ) , 16 : X2 ( often forward ) , 32 : pen eraser .
2013-10-23 00:54:04 +04:00
* @ param { Boolean } event . isTouchEvent
2014-03-21 22:45:20 +04:00
* True if the original event is a touch event , otherwise false . < span style = "color:red;" > Deprecated . Use pointerType and / or originalEvent instead . < / s p a n >
2013-10-23 00:54:04 +04:00
* @ param { Object } event . originalEvent
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-23 00:54:04 +04:00
* @ param { Object } event . userData
* Arbitrary user - defined object .
* /
stopHandler : function ( ) { } ,
2012-03-16 19:36:28 +04:00
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2013-10-11 04:00:15 +04:00
* @ param { Number } event . keyCode
2013-09-12 21:05:50 +04:00
* The key code that was pressed .
2013-10-11 04:00:15 +04:00
* @ param { Boolean } event . shift
2013-09-12 21:05:50 +04:00
* True if the shift key was pressed during this event .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
keyHandler : function ( ) { } ,
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
focusHandler : function ( ) { } ,
/ * *
2013-10-31 05:28:10 +04:00
* Implement or assign implementation to these handlers during or after
2013-09-06 21:43:39 +04:00
* calling the constructor .
* @ function
2013-10-11 04:00:15 +04:00
* @ param { Object } event
* @ param { OpenSeadragon . MouseTracker } event . eventSource
2013-09-06 21:43:39 +04:00
* A reference to the tracker instance .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . originalEvent
2013-09-12 21:05:50 +04:00
* The original event object .
2013-11-18 18:56:32 +04:00
* @ param { Boolean } event . preventDefaultAction
* Set to true to prevent the tracker subscriber from performing its default action ( subscriber implementation dependent ) . Default : false .
2013-10-11 04:00:15 +04:00
* @ param { Object } event . userData
2013-09-12 21:05:50 +04:00
* Arbitrary user - defined object .
2013-09-06 21:43:39 +04:00
* /
2013-09-06 04:20:17 +04:00
blurHandler : function ( ) { }
2012-02-03 04:12:45 +04:00
} ;
2012-02-02 01:56:04 +04:00
2014-03-10 22:49:51 +04:00
2014-03-30 04:02:24 +04:00
/ * *
* Provides continuous computation of velocity ( speed and direction ) of active pointers .
2014-04-15 05:17:18 +04:00
* This is a singleton , used by all MouseTracker instances , as it is unlikely there will ever be more than
2014-03-30 04:02:24 +04:00
* two active gesture pointers at a time .
2014-04-01 20:32:04 +04:00
*
2014-04-15 05:17:18 +04:00
* @ private
2014-04-01 20:32:04 +04:00
* @ member gesturePointVelocityTracker
* @ memberof OpenSeadragon . MouseTracker
2014-03-30 04:02:24 +04:00
* /
$ . MouseTracker . gesturePointVelocityTracker = ( function ( ) {
var trackerPoints = [ ] ,
intervalId = 0 ,
lastTime = 0 ;
// Generates a unique identifier for a tracked gesture point
var _generateGuid = function ( tracker , gPoint ) {
return tracker . hash . toString ( ) + gPoint . type + gPoint . id . toString ( ) ;
} ;
// Interval timer callback. Computes velocity for all tracked gesture points.
var _doTracking = function ( ) {
var i ,
len = trackerPoints . length ,
trackPoint ,
gPoint ,
now = $ . now ( ) ,
elapsedTime ,
distance ,
speed ;
elapsedTime = now - lastTime ;
lastTime = now ;
for ( i = 0 ; i < len ; i ++ ) {
trackPoint = trackerPoints [ i ] ;
gPoint = trackPoint . gPoint ;
// Math.atan2 gives us just what we need for a velocity vector, as we can simply
// use cos()/sin() to extract the x/y velocity components.
gPoint . direction = Math . atan2 ( gPoint . currentPos . y - trackPoint . lastPos . y , gPoint . currentPos . x - trackPoint . lastPos . x ) ;
// speed = distance / elapsed time
distance = trackPoint . lastPos . distanceTo ( gPoint . currentPos ) ;
trackPoint . lastPos = gPoint . currentPos ;
speed = 1000 * distance / ( elapsedTime + 1 ) ;
// Simple biased average, favors the most recent speed computation. Smooths out erratic gestures a bit.
gPoint . speed = 0.75 * speed + 0.25 * gPoint . speed ;
}
} ;
// Public. Add a gesture point to be tracked
var addPoint = function ( tracker , gPoint ) {
var guid = _generateGuid ( tracker , gPoint ) ;
trackerPoints . push (
{
guid : guid ,
gPoint : gPoint ,
lastPos : gPoint . currentPos
} ) ;
2014-04-15 05:17:18 +04:00
// Only fire up the interval timer when there's gesture pointers to track
2014-03-30 04:02:24 +04:00
if ( trackerPoints . length === 1 ) {
lastTime = $ . now ( ) ;
intervalId = window . setInterval ( _doTracking , 50 ) ;
}
} ;
// Public. Stop tracking a gesture point
var removePoint = function ( tracker , gPoint ) {
var guid = _generateGuid ( tracker , gPoint ) ,
i ,
len = trackerPoints . length ;
for ( i = 0 ; i < len ; i ++ ) {
if ( trackerPoints [ i ] . guid === guid ) {
trackerPoints . splice ( i , 1 ) ;
2014-04-15 05:17:18 +04:00
// Only run the interval timer if theres gesture pointers to track
2014-03-30 04:02:24 +04:00
len -- ;
if ( len === 0 ) {
window . clearInterval ( intervalId ) ;
}
break ;
}
}
} ;
return {
addPoint : addPoint ,
removePoint : removePoint
} ;
} ) ( ) ;
2014-04-03 19:50:25 +04:00
///////////////////////////////////////////////////////////////////////////////
2014-04-15 05:17:18 +04:00
// Pointer event model and feature detection
2014-04-03 19:50:25 +04:00
///////////////////////////////////////////////////////////////////////////////
2014-12-30 23:57:17 +03:00
$ . MouseTracker . captureElement = document ;
2013-10-23 23:58:36 +04:00
/ * *
2014-03-10 22:49:51 +04:00
* Detect available mouse wheel event name .
2013-10-23 23:58:36 +04:00
* /
2013-10-24 00:55:52 +04:00
$ . MouseTracker . wheelEventName = ( $ . Browser . vendor == $ . BROWSERS . IE && $ . Browser . version > 8 ) ||
( 'onwheel' in document . createElement ( 'div' ) ) ? 'wheel' : // Modern browsers support 'wheel'
document . onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least 'mousewheel'
'DOMMouseScroll' ; // Assume old Firefox
2013-10-23 23:58:36 +04:00
2014-05-03 10:01:38 +04:00
/ * *
* Detect legacy mouse capture support .
* /
$ . MouseTracker . supportsMouseCapture = ( function ( ) {
var divElement = document . createElement ( 'div' ) ;
return $ . isFunction ( divElement . setCapture ) && $ . isFunction ( divElement . releaseCapture ) ;
} ( ) ) ;
2014-03-10 22:49:51 +04:00
/ * *
2014-03-30 04:02:24 +04:00
* Detect browser pointer device event model ( s ) and build appropriate list of events to subscribe to .
2014-03-10 22:49:51 +04:00
* /
2014-04-22 20:23:56 +04:00
$ . MouseTracker . subscribeEvents = [ "click" , "dblclick" , "keypress" , "focus" , "blur" , $ . MouseTracker . wheelEventName ] ;
2014-03-10 22:49:51 +04:00
if ( $ . MouseTracker . wheelEventName == "DOMMouseScroll" ) {
// Older Firefox
$ . MouseTracker . subscribeEvents . push ( "MozMousePixelScroll" ) ;
}
if ( window . PointerEvent ) {
// IE11 and other W3C Pointer Event implementations (see http://www.w3.org/TR/pointerevents)
2014-08-05 08:41:07 +04:00
$ . MouseTracker . subscribeEvents . push ( "pointerover" , "pointerout" , "pointerdown" , "pointerup" , "pointermove" , "pointercancel" ) ;
2014-03-10 22:49:51 +04:00
$ . MouseTracker . unprefixedPointerEvents = true ;
if ( navigator . maxTouchPoints ) {
$ . MouseTracker . maxTouchPoints = navigator . maxTouchPoints ;
2014-04-15 05:17:18 +04:00
} else {
2014-03-10 22:49:51 +04:00
$ . MouseTracker . maxTouchPoints = 0 ;
}
2014-08-05 08:41:07 +04:00
$ . MouseTracker . haveTouchEnter = false ;
$ . MouseTracker . haveMouseEnter = false ;
2014-04-15 05:17:18 +04:00
} else if ( window . MSPointerEvent ) {
2014-03-10 22:49:51 +04:00
// IE10
2014-08-05 08:41:07 +04:00
$ . MouseTracker . subscribeEvents . push ( "MSPointerOver" , "MSPointerOut" , "MSPointerDown" , "MSPointerUp" , "MSPointerMove" , "MSPointerCancel" ) ;
2014-03-10 22:49:51 +04:00
$ . MouseTracker . unprefixedPointerEvents = false ;
if ( navigator . msMaxTouchPoints ) {
$ . MouseTracker . maxTouchPoints = navigator . msMaxTouchPoints ;
2014-04-15 05:17:18 +04:00
} else {
2014-03-10 22:49:51 +04:00
$ . MouseTracker . maxTouchPoints = 0 ;
}
2014-08-05 08:41:07 +04:00
$ . MouseTracker . haveTouchEnter = false ;
$ . MouseTracker . haveMouseEnter = false ;
2014-04-15 05:17:18 +04:00
} else {
2014-04-02 05:27:54 +04:00
// Legacy W3C mouse events
2014-08-06 00:56:18 +04:00
$ . MouseTracker . subscribeEvents . push ( "mouseover" , "mouseout" , "mousedown" , "mouseup" , "mousemove" ) ;
$ . MouseTracker . haveMouseEnter = false ;
2014-03-10 22:49:51 +04:00
if ( 'ontouchstart' in window ) {
// iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505)
2014-03-30 04:02:24 +04:00
$ . MouseTracker . subscribeEvents . push ( "touchstart" , "touchend" , "touchmove" , "touchcancel" ) ;
if ( 'ontouchenter' in window ) {
$ . MouseTracker . subscribeEvents . push ( "touchenter" , "touchleave" ) ;
$ . MouseTracker . haveTouchEnter = true ;
2014-04-15 05:17:18 +04:00
} else {
2014-03-30 04:02:24 +04:00
$ . MouseTracker . haveTouchEnter = false ;
}
2014-04-15 05:17:18 +04:00
} else {
$ . MouseTracker . haveTouchEnter = false ;
2014-03-21 22:45:20 +04:00
}
if ( 'ongesturestart' in window ) {
// iOS (see https://developer.apple.com/library/safari/documentation/UserExperience/Reference/GestureEventClassReference/GestureEvent/GestureEvent.html)
// Subscribe to these to prevent default gesture handling
$ . MouseTracker . subscribeEvents . push ( "gesturestart" , "gesturechange" ) ;
2014-03-10 22:49:51 +04:00
}
$ . MouseTracker . mousePointerId = "legacy-mouse" ;
$ . MouseTracker . maxTouchPoints = 10 ;
}
2014-04-03 19:50:25 +04:00
///////////////////////////////////////////////////////////////////////////////
// Classes and typedefs
///////////////////////////////////////////////////////////////////////////////
2014-03-30 04:02:24 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* Represents a point of contact on the screen made by a mouse cursor , pen , touch , or other pointer device .
2014-03-30 04:02:24 +04:00
*
* @ typedef { Object } GesturePoint
* @ memberof OpenSeadragon . MouseTracker
*
* @ property { Number } id
* Identifier unique from all other active GesturePoints for a given pointer device .
* @ property { String } type
2014-04-15 05:17:18 +04:00
* The pointer device type : "mouse" , "touch" , "pen" , etc .
* @ property { Boolean } captured
* True if events for the gesture point are captured to the tracked element .
2014-04-01 20:32:04 +04:00
* @ property { Boolean } isPrimary
* True if the gesture point is a master pointer amongst the set of active pointers for each pointer type . True for mouse and primary ( first ) touch / pen pointers .
2014-03-30 04:02:24 +04:00
* @ property { Boolean } insideElementPressed
2014-04-01 20:32:04 +04:00
* True if button pressed or contact point initiated inside the screen area of the tracked element .
2014-03-30 04:02:24 +04:00
* @ property { Boolean } insideElement
2014-04-01 20:32:04 +04:00
* True if pointer or contact point is currently inside the bounds of the tracked element .
2014-03-30 04:02:24 +04:00
* @ property { Number } speed
2014-04-01 20:32:04 +04:00
* Current computed speed , in pixels per second .
2014-03-30 04:02:24 +04:00
* @ property { Number } direction
2014-04-01 20:32:04 +04:00
* Current computed direction , expressed as an angle counterclockwise relative to the positive X axis ( - pi to pi , in radians ) . Only valid if speed > 0.
2014-04-15 05:17:18 +04:00
* @ property { OpenSeadragon . Point } contactPos
* The initial pointer contact position , relative to the page including any scrolling . Only valid if the pointer has contact ( pressed , touch contact , pen contact ) .
* @ property { Number } contactTime
* The initial pointer contact time , in milliseconds . Only valid if the pointer has contact ( pressed , touch contact , pen contact ) .
2014-03-30 04:02:24 +04:00
* @ property { OpenSeadragon . Point } lastPos
* The last pointer position , relative to the page including any scrolling .
* @ property { Number } lastTime
* The last pointer contact time , in milliseconds .
* @ property { OpenSeadragon . Point } currentPos
* The current pointer position , relative to the page including any scrolling .
* @ property { Number } currentTime
* The current pointer contact time , in milliseconds .
* /
2014-04-15 05:17:18 +04:00
/ * *
2014-03-30 04:02:24 +04:00
* @ class GesturePointList
2014-04-15 05:17:18 +04:00
* @ classdesc Provides an abstraction for a set of active { @ link OpenSeadragon . MouseTracker . GesturePoint | GesturePoint } objects for a given pointer device type .
* Active pointers are any pointer being tracked for this element which are in the hit - test area
* of the element ( for hover - capable devices ) and / or have contact or a button press initiated in the element .
2014-03-30 04:02:24 +04:00
* @ memberof OpenSeadragon . MouseTracker
2014-04-15 05:17:18 +04:00
* @ param { String } type - The pointer device type : "mouse" , "touch" , "pen" , etc .
2014-03-30 04:02:24 +04:00
* /
2014-04-15 05:17:18 +04:00
$ . MouseTracker . GesturePointList = function ( type ) {
2014-03-30 04:02:24 +04:00
this . _gPoints = [ ] ;
2014-04-15 05:17:18 +04:00
/ * *
* The pointer device type : "mouse" , "touch" , "pen" , etc .
* @ member { String } type
* @ memberof OpenSeadragon . MouseTracker . GesturePointList #
* /
this . type = type ;
/ * *
* Current buttons pressed for the device .
* Combination of bit flags 0 : none , 1 : primary ( or touch contact ) , 2 : secondary , 4 : aux ( often middle ) , 8 : X1 ( often back ) , 16 : X2 ( often forward ) , 32 : pen eraser .
* @ member { Number } buttons
* @ memberof OpenSeadragon . MouseTracker . GesturePointList #
* /
this . buttons = 0 ;
/ * *
* Current number of contact points ( touch points , mouse down , etc . ) for the device .
* @ member { Number } contacts
* @ memberof OpenSeadragon . MouseTracker . GesturePointList #
* /
this . contacts = 0 ;
2014-04-22 20:23:56 +04:00
/ * *
* Current number of clicks for the device . Used for multiple click gesture tracking .
* @ member { Number } clicks
* @ memberof OpenSeadragon . MouseTracker . GesturePointList #
* /
this . clicks = 0 ;
2014-03-30 04:02:24 +04:00
} ;
$ . MouseTracker . GesturePointList . prototype = /** @lends OpenSeadragon.MouseTracker.GesturePointList.prototype */ {
/ * *
* @ function
* @ returns { Number } Number of gesture points in the list .
* /
getLength : function ( ) {
return this . _gPoints . length ;
} ,
/ * *
* @ function
* @ returns { Array . < OpenSeadragon . MouseTracker . GesturePoint > } The list of gesture points in the list as an array ( read - only ) .
* /
asArray : function ( ) {
return this . _gPoints ;
} ,
/ * *
* @ function
* @ param { OpenSeadragon . MouseTracker . GesturePoint } gesturePoint - A gesture point to add to the list .
* @ returns { Number } Number of gesture points in the list .
* /
add : function ( gp ) {
return this . _gPoints . push ( gp ) ;
} ,
/ * *
* @ function
* @ param { Number } id - The id of the gesture point to remove from the list .
* @ returns { Number } Number of gesture points in the list .
* /
removeById : function ( id ) {
var i ,
len = this . _gPoints . length ;
for ( i = 0 ; i < len ; i ++ ) {
if ( this . _gPoints [ i ] . id === id ) {
this . _gPoints . splice ( i , 1 ) ;
break ;
}
}
return this . _gPoints . length ;
} ,
2014-04-01 20:32:04 +04:00
/ * *
* @ function
* @ param { Number } index - The index of the gesture point to retrieve from the list .
* @ returns { OpenSeadragon . MouseTracker . GesturePoint | null } The gesture point at the given index , or null if not found .
* /
getByIndex : function ( index ) {
if ( index < this . _gPoints . length ) {
return this . _gPoints [ index ] ;
}
return null ;
} ,
2014-03-30 04:02:24 +04:00
/ * *
* @ function
* @ param { Number } id - The id of the gesture point to retrieve from the list .
* @ returns { OpenSeadragon . MouseTracker . GesturePoint | null } The gesture point with the given id , or null if not found .
* /
getById : function ( id ) {
var i ,
len = this . _gPoints . length ;
for ( i = 0 ; i < len ; i ++ ) {
if ( this . _gPoints [ i ] . id === id ) {
return this . _gPoints [ i ] ;
}
}
return null ;
2014-04-01 20:32:04 +04:00
} ,
/ * *
* @ function
* @ returns { OpenSeadragon . MouseTracker . GesturePoint | null } The primary gesture point in the list , or null if not found .
* /
getPrimary : function ( id ) {
var i ,
len = this . _gPoints . length ;
for ( i = 0 ; i < len ; i ++ ) {
if ( this . _gPoints [ i ] . isPrimary ) {
return this . _gPoints [ i ] ;
}
}
return null ;
2014-03-30 04:02:24 +04:00
}
} ;
2014-04-03 19:50:25 +04:00
///////////////////////////////////////////////////////////////////////////////
// Utility functions
///////////////////////////////////////////////////////////////////////////////
2014-12-30 23:57:17 +03:00
/ * *
* Removes all tracked pointers .
* @ private
* @ inner
* /
function clearTrackedPointers ( tracker ) {
var delegate = THIS [ tracker . hash ] ,
i ,
pointerListCount = delegate . activePointersLists . length ;
if ( delegate . pointerCaptureCount > 0 ) {
$ . removeEvent (
$ . MouseTracker . captureElement ,
'mousemove' ,
delegate . mousemovecaptured ,
true
) ;
$ . removeEvent (
$ . MouseTracker . captureElement ,
'mouseup' ,
delegate . mouseupcaptured ,
true
) ;
$ . removeEvent (
$ . MouseTracker . captureElement ,
$ . MouseTracker . unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove' ,
delegate . pointermovecaptured ,
true
) ;
$ . removeEvent (
$ . MouseTracker . captureElement ,
$ . MouseTracker . unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp' ,
delegate . pointerupcaptured ,
true
) ;
delegate . pointerCaptureCount = 0 ;
}
for ( i = 0 ; i < pointerListCount ; i ++ ) {
delegate . activePointersLists . pop ( ) ;
}
}
2012-02-03 04:12:45 +04:00
/ * *
2014-04-03 19:50:25 +04:00
* Starts tracking pointer events on the tracked element .
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2012-02-03 04:12:45 +04:00
function startTracking ( tracker ) {
2014-03-10 22:49:51 +04:00
var delegate = THIS [ tracker . hash ] ,
2013-06-19 21:33:25 +04:00
event ,
2012-02-03 04:12:45 +04:00
i ;
if ( ! delegate . tracking ) {
2014-03-10 22:49:51 +04:00
for ( i = 0 ; i < $ . MouseTracker . subscribeEvents . length ; i ++ ) {
event = $ . MouseTracker . subscribeEvents [ i ] ;
2013-06-19 21:33:25 +04:00
$ . addEvent (
tracker . element ,
event ,
2013-09-20 20:58:18 +04:00
delegate [ event ] ,
2012-02-03 04:12:45 +04:00
false
) ;
2011-12-06 07:50:25 +04:00
}
2014-09-24 01:31:53 +04:00
2014-12-30 23:57:17 +03:00
clearTrackedPointers ( tracker ) ;
2014-09-13 03:01:19 +04:00
2012-02-03 04:12:45 +04:00
delegate . tracking = true ;
}
2013-01-29 21:32:58 +04:00
}
2011-12-06 07:50:25 +04:00
2012-02-03 04:12:45 +04:00
/ * *
2014-04-03 19:50:25 +04:00
* Stops tracking pointer events on the tracked element .
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2012-02-03 04:12:45 +04:00
function stopTracking ( tracker ) {
2014-03-10 22:49:51 +04:00
var delegate = THIS [ tracker . hash ] ,
2013-06-19 21:33:25 +04:00
event ,
2012-02-03 04:12:45 +04:00
i ;
2013-06-19 21:33:25 +04:00
2012-02-03 04:12:45 +04:00
if ( delegate . tracking ) {
2014-03-10 22:49:51 +04:00
for ( i = 0 ; i < $ . MouseTracker . subscribeEvents . length ; i ++ ) {
event = $ . MouseTracker . subscribeEvents [ i ] ;
2013-06-19 21:33:25 +04:00
$ . removeEvent (
tracker . element ,
event ,
2013-09-20 20:58:18 +04:00
delegate [ event ] ,
2012-02-03 04:12:45 +04:00
false
) ;
2011-12-06 07:50:25 +04:00
}
2014-12-30 23:57:17 +03:00
clearTrackedPointers ( tracker ) ;
2014-09-13 03:01:19 +04:00
2012-02-03 04:12:45 +04:00
delegate . tracking = false ;
}
2013-01-29 21:32:58 +04:00
}
2011-12-06 07:50:25 +04:00
2012-02-03 04:12:45 +04:00
/ * *
2014-08-06 21:49:42 +04:00
* Begin capturing pointer events to the tracked element .
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2014-08-06 21:49:42 +04:00
function capturePointer ( tracker , isLegacyMouse ) {
2014-08-06 00:56:18 +04:00
var delegate = THIS [ tracker . hash ] ;
delegate . pointerCaptureCount ++ ;
if ( delegate . pointerCaptureCount === 1 ) {
// We emulate mouse capture by hanging listeners on the window object.
// (Note we listen on the capture phase so the captured handlers will get called first)
$ . addEvent (
2014-12-30 23:57:17 +03:00
$ . MouseTracker . captureElement ,
2014-08-06 21:49:42 +04:00
isLegacyMouse ? 'mouseup' : ( $ . MouseTracker . unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp' ) ,
isLegacyMouse ? delegate . mouseupcaptured : delegate . pointerupcaptured ,
2014-08-06 00:56:18 +04:00
true
) ;
$ . addEvent (
2014-12-30 23:57:17 +03:00
$ . MouseTracker . captureElement ,
2014-08-06 21:49:42 +04:00
isLegacyMouse ? 'mousemove' : ( $ . MouseTracker . unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove' ) ,
isLegacyMouse ? delegate . mousemovecaptured : delegate . pointermovecaptured ,
2014-08-06 00:56:18 +04:00
true
) ;
}
}
/ * *
2014-08-06 21:49:42 +04:00
* Stop capturing pointer events to the tracked element .
2014-08-06 00:56:18 +04:00
* @ private
* @ inner
* /
2014-08-06 21:49:42 +04:00
function releasePointer ( tracker , isLegacyMouse ) {
2014-08-06 00:56:18 +04:00
var delegate = THIS [ tracker . hash ] ;
delegate . pointerCaptureCount -- ;
if ( delegate . pointerCaptureCount === 0 ) {
// We emulate mouse capture by hanging listeners on the window object.
// (Note we listen on the capture phase so the captured handlers will get called first)
$ . removeEvent (
2014-12-30 23:57:17 +03:00
$ . MouseTracker . captureElement ,
2014-08-06 21:49:42 +04:00
isLegacyMouse ? 'mousemove' : ( $ . MouseTracker . unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove' ) ,
isLegacyMouse ? delegate . mousemovecaptured : delegate . pointermovecaptured ,
2014-08-06 00:56:18 +04:00
true
) ;
$ . removeEvent (
2014-12-30 23:57:17 +03:00
$ . MouseTracker . captureElement ,
2014-08-06 21:49:42 +04:00
isLegacyMouse ? 'mouseup' : ( $ . MouseTracker . unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp' ) ,
isLegacyMouse ? delegate . mouseupcaptured : delegate . pointerupcaptured ,
2014-08-06 00:56:18 +04:00
true
) ;
2012-02-03 04:12:45 +04:00
}
2013-01-29 21:32:58 +04:00
}
2011-12-06 07:50:25 +04:00
2012-02-10 07:16:09 +04:00
2014-03-10 22:49:51 +04:00
/ * *
2014-04-03 19:50:25 +04:00
* Gets a W3C Pointer Events model compatible pointer type string from a DOM pointer event .
2014-04-15 05:17:18 +04:00
* IE10 used a long integer value , but the W3C specification ( and IE11 + ) use a string "mouse" , "touch" , "pen" , etc .
2014-03-10 22:49:51 +04:00
* @ private
* @ inner
* /
function getPointerType ( event ) {
var pointerTypeStr ;
if ( $ . MouseTracker . unprefixedPointerEvents ) {
pointerTypeStr = event . pointerType ;
2014-04-15 05:17:18 +04:00
} else {
2014-03-10 22:49:51 +04:00
// IE10
// MSPOINTER_TYPE_TOUCH: 0x00000002
// MSPOINTER_TYPE_PEN: 0x00000003
// MSPOINTER_TYPE_MOUSE: 0x00000004
switch ( event . pointerType )
{
case 0x00000002 :
pointerTypeStr = 'touch' ;
break ;
case 0x00000003 :
pointerTypeStr = 'pen' ;
break ;
case 0x00000004 :
pointerTypeStr = 'mouse' ;
break ;
default :
pointerTypeStr = '' ;
2011-12-06 07:50:25 +04:00
}
2012-02-03 04:12:45 +04:00
}
2014-03-10 22:49:51 +04:00
return pointerTypeStr ;
2013-01-29 21:32:58 +04:00
}
2011-12-06 07:50:25 +04:00
2012-02-10 07:16:09 +04:00
2012-03-16 19:36:28 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2014-03-10 22:49:51 +04:00
function getMouseAbsolute ( event ) {
return $ . getMousePosition ( event ) ;
2013-01-29 21:32:58 +04:00
}
2012-03-16 19:36:28 +04:00
2014-03-10 22:49:51 +04:00
/ * *
* @ private
* @ inner
* /
function getMouseRelative ( event , element ) {
2014-03-31 23:54:37 +04:00
return getPointRelativeToAbsolute ( getMouseAbsolute ( event ) , element ) ;
2014-03-10 22:49:51 +04:00
}
2012-03-16 19:36:28 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2014-03-31 23:54:37 +04:00
function getPointRelativeToAbsolute ( point , element ) {
2014-03-10 22:49:51 +04:00
var offset = $ . getElementOffset ( element ) ;
return point . minus ( offset ) ;
}
2014-03-15 01:15:09 +04:00
/ * *
* @ private
* @ inner
* /
function getCenterPoint ( point1 , point2 ) {
return new $ . Point ( ( point1 . x + point2 . x ) / 2 , ( point1 . y + point2 . y ) / 2 ) ;
}
2014-03-10 22:49:51 +04:00
2014-04-03 19:50:25 +04:00
///////////////////////////////////////////////////////////////////////////////
2014-04-15 05:17:18 +04:00
// Device-specific DOM event handlers
2014-04-03 19:50:25 +04:00
///////////////////////////////////////////////////////////////////////////////
2014-03-10 22:49:51 +04:00
/ * *
* @ private
* @ inner
* /
function onClick ( tracker , event ) {
if ( tracker . clickHandler ) {
$ . cancelEvent ( event ) ;
2012-03-16 19:36:28 +04:00
}
2013-01-29 21:32:58 +04:00
}
2012-03-16 19:36:28 +04:00
2013-06-19 21:33:25 +04:00
2014-04-22 20:23:56 +04:00
/ * *
* @ private
* @ inner
* /
function onDblClick ( tracker , event ) {
if ( tracker . dblClickHandler ) {
$ . cancelEvent ( event ) ;
}
}
2012-03-16 19:36:28 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2013-09-06 04:20:17 +04:00
function onKeyPress ( tracker , event ) {
2012-03-21 05:58:23 +04:00
//console.log( "keypress %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey );
2012-03-20 23:30:29 +04:00
var propagate ;
2012-03-16 19:36:28 +04:00
if ( tracker . keyHandler ) {
2014-03-10 22:49:51 +04:00
event = $ . getEvent ( event ) ;
2013-06-19 21:33:25 +04:00
propagate = tracker . keyHandler (
2013-09-06 04:20:17 +04:00
{
2013-11-05 00:41:45 +04:00
eventSource : tracker ,
position : getMouseRelative ( event , tracker . element ) ,
keyCode : event . keyCode ? event . keyCode : event . charCode ,
shift : event . shiftKey ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
2013-09-06 04:20:17 +04:00
}
2012-04-11 01:02:24 +04:00
) ;
2013-09-06 04:20:17 +04:00
if ( ! propagate ) {
2012-04-11 01:02:24 +04:00
$ . cancelEvent ( event ) ;
2012-03-16 19:36:28 +04:00
}
}
2013-01-29 21:32:58 +04:00
}
2012-03-16 19:36:28 +04:00
2012-02-03 04:12:45 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2014-03-10 22:49:51 +04:00
function onFocus ( tracker , event ) {
//console.log( "focus %s", event );
var propagate ;
if ( tracker . focusHandler ) {
event = $ . getEvent ( event ) ;
propagate = tracker . focusHandler (
2013-09-06 04:20:17 +04:00
{
2013-11-05 00:41:45 +04:00
eventSource : tracker ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
2013-09-06 04:20:17 +04:00
}
2012-04-11 01:02:24 +04:00
) ;
2013-09-06 04:20:17 +04:00
if ( propagate === false ) {
2012-04-11 01:02:24 +04:00
$ . cancelEvent ( event ) ;
2011-12-06 07:50:25 +04:00
}
2012-02-03 04:12:45 +04:00
}
2013-01-29 21:32:58 +04:00
}
2011-12-06 07:50:25 +04:00
2012-02-10 07:16:09 +04:00
2012-02-03 04:12:45 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2014-03-10 22:49:51 +04:00
function onBlur ( tracker , event ) {
//console.log( "blur %s", event );
var propagate ;
if ( tracker . blurHandler ) {
event = $ . getEvent ( event ) ;
propagate = tracker . blurHandler (
2013-09-06 04:20:17 +04:00
{
2013-11-05 00:41:45 +04:00
eventSource : tracker ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
2013-09-06 04:20:17 +04:00
}
2012-04-11 01:02:24 +04:00
) ;
2013-09-06 04:20:17 +04:00
if ( propagate === false ) {
2012-04-11 01:02:24 +04:00
$ . cancelEvent ( event ) ;
2011-12-06 07:50:25 +04:00
}
2012-02-03 04:12:45 +04:00
}
2013-01-29 21:32:58 +04:00
}
2011-12-06 07:50:25 +04:00
2012-02-10 07:16:09 +04:00
2012-02-03 04:12:45 +04:00
/ * *
2014-03-10 22:49:51 +04:00
* Handler for 'wheel' events
*
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2014-03-10 22:49:51 +04:00
function onWheel ( tracker , event ) {
handleWheelEvent ( tracker , event , event ) ;
}
2011-12-06 07:50:25 +04:00
2013-09-06 04:20:17 +04:00
2014-03-10 22:49:51 +04:00
/ * *
* Handler for 'mousewheel' , 'DOMMouseScroll' , and 'MozMousePixelScroll' events
*
* @ private
* @ inner
* /
function onMouseWheel ( tracker , event ) {
event = $ . getEvent ( event ) ;
2013-09-12 21:05:50 +04:00
2014-03-10 22:49:51 +04:00
// Simulate a 'wheel' event
var simulatedEvent = {
target : event . target || event . srcElement ,
type : "wheel" ,
shiftKey : event . shiftKey || false ,
clientX : event . clientX ,
clientY : event . clientY ,
pageX : event . pageX ? event . pageX : event . clientX ,
pageY : event . pageY ? event . pageY : event . clientY ,
deltaMode : event . type == "MozMousePixelScroll" ? 0 : 1 , // 0=pixel, 1=line, 2=page
deltaX : 0 ,
deltaZ : 0
} ;
2013-02-13 07:40:08 +04:00
2014-03-10 22:49:51 +04:00
// Calculate deltaY
if ( $ . MouseTracker . wheelEventName == "mousewheel" ) {
simulatedEvent . deltaY = - 1 / $ . DEFAULT _SETTINGS . pixelsPerWheelLine * event . wheelDelta ;
} else {
simulatedEvent . deltaY = event . detail ;
2012-02-03 04:12:45 +04:00
}
2011-12-06 07:50:25 +04:00
2014-03-10 22:49:51 +04:00
handleWheelEvent ( tracker , simulatedEvent , event ) ;
}
2012-02-03 04:12:45 +04:00
2012-02-02 01:56:04 +04:00
2014-04-15 05:17:18 +04:00
/ * *
* Handles 'wheel' events .
* The event may be simulated by the legacy mouse wheel event handler ( onMouseWheel ( ) ) .
*
* @ private
* @ inner
* /
function handleWheelEvent ( tracker , event , originalEvent ) {
var nDelta = 0 ,
propagate ;
// The nDelta variable is gated to provide smooth z-index scrolling
// since the mouse wheel allows for substantial deltas meant for rapid
// y-index scrolling.
// event.deltaMode: 0=pixel, 1=line, 2=page
// TODO: Deltas in pixel mode should be accumulated then a scroll value computed after $.DEFAULT_SETTINGS.pixelsPerWheelLine threshold reached
nDelta = event . deltaY < 0 ? 1 : - 1 ;
if ( tracker . scrollHandler ) {
propagate = tracker . scrollHandler (
{
eventSource : tracker ,
pointerType : 'mouse' ,
position : getMouseRelative ( event , tracker . element ) ,
scroll : nDelta ,
shift : event . shiftKey ,
isTouchEvent : false ,
originalEvent : originalEvent ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( originalEvent ) ;
}
}
}
2014-04-16 00:04:08 +04:00
/ * *
* @ private
* @ inner
* /
function isParentChild ( parent , child )
{
if ( parent === child ) {
return false ;
}
while ( child && child !== parent ) {
child = child . parentNode ;
}
return child === parent ;
}
/ * *
* @ private
* @ inner
* /
function onMouseOver ( tracker , event ) {
var gPoint ;
event = $ . getEvent ( event ) ;
2014-08-06 03:17:40 +04:00
if ( this === event . relatedTarget || isParentChild ( event . currentTarget , event . relatedTarget ) ) {
2014-04-16 00:04:08 +04:00
return ;
}
gPoint = {
id : $ . MouseTracker . mousePointerId ,
type : 'mouse' ,
isPrimary : true ,
currentPos : getMouseAbsolute ( event ) ,
currentTime : $ . now ( )
} ;
updatePointersEnter ( tracker , event , [ gPoint ] ) ;
}
/ * *
* @ private
* @ inner
* /
function onMouseOut ( tracker , event ) {
var gPoint ;
event = $ . getEvent ( event ) ;
2014-08-06 03:17:40 +04:00
if ( this === event . relatedTarget || isParentChild ( event . currentTarget , event . relatedTarget ) ) {
2014-04-16 00:04:08 +04:00
return ;
}
gPoint = {
id : $ . MouseTracker . mousePointerId ,
type : 'mouse' ,
isPrimary : true ,
currentPos : getMouseAbsolute ( event ) ,
currentTime : $ . now ( )
} ;
updatePointersExit ( tracker , event , [ gPoint ] ) ;
}
2012-02-10 07:16:09 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2014-03-10 22:49:51 +04:00
function onMouseDown ( tracker , event ) {
2014-03-31 23:54:37 +04:00
var gPoint ;
2014-03-10 22:49:51 +04:00
2014-03-30 04:02:24 +04:00
event = $ . getEvent ( event ) ;
2014-03-10 22:49:51 +04:00
2014-03-21 22:45:20 +04:00
gPoint = {
2014-03-10 22:49:51 +04:00
id : $ . MouseTracker . mousePointerId ,
type : 'mouse' ,
2014-04-01 20:32:04 +04:00
isPrimary : true ,
2014-03-31 23:54:37 +04:00
currentPos : getMouseAbsolute ( event ) ,
currentTime : $ . now ( )
2014-03-10 22:49:51 +04:00
} ;
2013-09-06 04:20:17 +04:00
2014-04-15 05:17:18 +04:00
if ( updatePointersDown ( tracker , event , [ gPoint ] , event . button ) ) {
$ . stopEvent ( event ) ;
2014-08-06 21:49:42 +04:00
capturePointer ( tracker , true ) ;
2014-04-15 05:17:18 +04:00
}
2012-02-10 07:16:09 +04:00
2014-04-22 20:23:56 +04:00
if ( tracker . clickHandler || tracker . dblClickHandler || tracker . pressHandler || tracker . dragHandler || tracker . dragEndHandler ) {
2014-03-10 22:49:51 +04:00
$ . cancelEvent ( event ) ;
2012-02-10 07:16:09 +04:00
}
2014-03-10 22:49:51 +04:00
}
/ * *
* @ private
* @ inner
* /
function onMouseUp ( tracker , event ) {
2014-04-15 05:17:18 +04:00
handleMouseUp ( tracker , event ) ;
2013-01-29 21:32:58 +04:00
}
2012-02-10 07:16:09 +04:00
2012-02-03 04:12:45 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* This handler is attached to the window object ( on the capture phase ) to emulate mouse capture .
* onMouseUp is still attached to the tracked element , so stop propagation to avoid processing twice .
*
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2014-04-02 05:27:54 +04:00
function onMouseUpCaptured ( tracker , event ) {
handleMouseUp ( tracker , event ) ;
2014-04-15 05:17:18 +04:00
$ . stopEvent ( event ) ;
}
2011-12-06 07:50:25 +04:00
2014-04-15 05:17:18 +04:00
/ * *
* @ private
* @ inner
* /
function handleMouseUp ( tracker , event ) {
var gPoint ;
event = $ . getEvent ( event ) ;
gPoint = {
id : $ . MouseTracker . mousePointerId ,
type : 'mouse' ,
isPrimary : true ,
currentPos : getMouseAbsolute ( event ) ,
currentTime : $ . now ( )
} ;
if ( updatePointersUp ( tracker , event , [ gPoint ] , event . button ) ) {
2014-08-06 21:49:42 +04:00
releasePointer ( tracker , true ) ;
2014-04-02 05:27:54 +04:00
}
}
2012-02-03 04:12:45 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2013-09-06 04:20:17 +04:00
function onMouseMove ( tracker , event ) {
2014-04-15 05:17:18 +04:00
handleMouseMove ( tracker , event ) ;
2014-03-31 23:54:37 +04:00
}
2014-03-10 22:49:51 +04:00
2013-10-23 00:54:04 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* This handler is attached to the window object ( on the capture phase ) to emulate mouse capture .
* onMouseMove is still attached to the tracked element , so stop propagation to avoid processing twice .
*
2013-10-23 00:54:04 +04:00
* @ private
* @ inner
* /
2014-03-10 22:49:51 +04:00
function onMouseMoveCaptured ( tracker , event ) {
handleMouseMove ( tracker , event ) ;
2014-04-15 05:17:18 +04:00
$ . stopEvent ( event ) ;
}
/ * *
* @ private
* @ inner
* /
function handleMouseMove ( tracker , event ) {
var gPoint ;
event = $ . getEvent ( event ) ;
gPoint = {
id : $ . MouseTracker . mousePointerId ,
type : 'mouse' ,
isPrimary : true ,
currentPos : getMouseAbsolute ( event ) ,
currentTime : $ . now ( )
} ;
updatePointersMove ( tracker , event , [ gPoint ] ) ;
2013-09-06 04:20:17 +04:00
}
2014-03-10 22:49:51 +04:00
2012-02-03 04:12:45 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2014-03-21 22:45:20 +04:00
function onTouchEnter ( tracker , event ) {
2014-03-31 23:54:37 +04:00
var i ,
2014-03-21 22:45:20 +04:00
touchCount = event . changedTouches . length ,
gPoints = [ ] ;
2014-03-10 22:49:51 +04:00
2014-03-21 22:45:20 +04:00
for ( i = 0 ; i < touchCount ; i ++ ) {
gPoints . push ( {
id : event . changedTouches [ i ] . identifier ,
type : 'touch' ,
2014-04-15 05:17:18 +04:00
// isPrimary not set - let the updatePointers functions determine it
2014-03-31 23:54:37 +04:00
currentPos : getMouseAbsolute ( event . changedTouches [ i ] ) ,
currentTime : $ . now ( )
2014-03-21 22:45:20 +04:00
} ) ;
}
2014-03-10 22:49:51 +04:00
2014-04-16 00:04:08 +04:00
updatePointersEnter ( tracker , event , gPoints ) ;
2013-10-23 23:58:36 +04:00
}
/ * *
* @ private
* @ inner
* /
2014-03-21 22:45:20 +04:00
function onTouchLeave ( tracker , event ) {
2014-03-31 23:54:37 +04:00
var i ,
2014-03-10 22:49:51 +04:00
touchCount = event . changedTouches . length ,
2014-03-21 22:45:20 +04:00
gPoints = [ ] ;
2014-03-10 22:49:51 +04:00
2014-03-21 22:45:20 +04:00
for ( i = 0 ; i < touchCount ; i ++ ) {
gPoints . push ( {
id : event . changedTouches [ i ] . identifier ,
type : 'touch' ,
2014-04-15 05:17:18 +04:00
// isPrimary not set - let the updatePointers functions determine it
2014-03-31 23:54:37 +04:00
currentPos : getMouseAbsolute ( event . changedTouches [ i ] ) ,
currentTime : $ . now ( )
2014-03-21 22:45:20 +04:00
} ) ;
}
2014-04-16 00:04:08 +04:00
updatePointersExit ( tracker , event , gPoints ) ;
2014-03-21 22:45:20 +04:00
}
/ * *
* @ private
* @ inner
* /
function onTouchStart ( tracker , event ) {
2014-04-15 05:17:18 +04:00
var time ,
2014-03-21 22:45:20 +04:00
i ,
touchCount = event . changedTouches . length ,
gPoints = [ ] ;
time = $ . now ( ) ;
2014-03-10 22:49:51 +04:00
for ( i = 0 ; i < touchCount ; i ++ ) {
2014-03-21 22:45:20 +04:00
gPoints . push ( {
2014-03-10 22:49:51 +04:00
id : event . changedTouches [ i ] . identifier ,
type : 'touch' ,
2014-04-15 05:17:18 +04:00
// isPrimary not set - let the updatePointers functions determine it
2014-03-31 23:54:37 +04:00
currentPos : getMouseAbsolute ( event . changedTouches [ i ] ) ,
2014-03-10 22:49:51 +04:00
currentTime : time
} ) ;
}
2013-10-23 23:58:36 +04:00
2014-04-15 05:17:18 +04:00
// simulate touchenter if not natively available
if ( ! $ . MouseTracker . haveTouchEnter ) {
2014-04-16 00:04:08 +04:00
updatePointersEnter ( tracker , event , gPoints ) ;
2014-04-15 05:17:18 +04:00
}
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
if ( updatePointersDown ( tracker , event , gPoints , 0 ) ) { // 0 means primary button press/release or touch contact
// Touch event model start, end, and move events are always captured so we don't need to capture explicitly
2014-12-30 23:57:17 +03:00
$ . stopEvent ( event ) ;
2014-03-21 22:45:20 +04:00
}
2014-04-15 05:17:18 +04:00
$ . cancelEvent ( event ) ;
2014-03-10 22:49:51 +04:00
}
/ * *
* @ private
* @ inner
* /
function onTouchEnd ( tracker , event ) {
2014-04-15 05:17:18 +04:00
var time ,
2014-03-10 22:49:51 +04:00
i ,
touchCount = event . changedTouches . length ,
2014-03-21 22:45:20 +04:00
gPoints = [ ] ;
2014-03-10 22:49:51 +04:00
time = $ . now ( ) ;
for ( i = 0 ; i < touchCount ; i ++ ) {
2014-03-21 22:45:20 +04:00
gPoints . push ( {
2014-03-10 22:49:51 +04:00
id : event . changedTouches [ i ] . identifier ,
type : 'touch' ,
2014-04-15 05:17:18 +04:00
// isPrimary not set - let the updatePointers functions determine it
2014-03-31 23:54:37 +04:00
currentPos : getMouseAbsolute ( event . changedTouches [ i ] ) ,
2014-03-10 22:49:51 +04:00
currentTime : time
} ) ;
}
2014-04-15 05:17:18 +04:00
// Touch event model start, end, and move events are always captured so we don't need to release capture.
// We'll ignore the should-release-capture return value here
updatePointersUp ( tracker , event , gPoints , 0 ) ; // 0 means primary button press/release or touch contact
2014-04-01 20:32:04 +04:00
2014-04-15 05:17:18 +04:00
// simulate touchleave if not natively available
if ( ! $ . MouseTracker . haveTouchEnter && touchCount > 0 ) {
2014-04-16 00:04:08 +04:00
updatePointersExit ( tracker , event , gPoints ) ;
2014-03-10 22:49:51 +04:00
}
2014-04-15 05:17:18 +04:00
$ . cancelEvent ( event ) ;
2014-03-10 22:49:51 +04:00
}
/ * *
* @ private
* @ inner
* /
function onTouchMove ( tracker , event ) {
2014-03-31 23:54:37 +04:00
var i ,
2014-03-10 22:49:51 +04:00
touchCount = event . changedTouches . length ,
2014-03-21 22:45:20 +04:00
gPoints = [ ] ;
2014-03-10 22:49:51 +04:00
for ( i = 0 ; i < touchCount ; i ++ ) {
2014-03-21 22:45:20 +04:00
gPoints . push ( {
2014-03-10 22:49:51 +04:00
id : event . changedTouches [ i ] . identifier ,
type : 'touch' ,
2014-04-15 05:17:18 +04:00
// isPrimary not set - let the updatePointers functions determine it
2014-03-31 23:54:37 +04:00
currentPos : getMouseAbsolute ( event . changedTouches [ i ] ) ,
currentTime : $ . now ( )
2014-03-10 22:49:51 +04:00
} ) ;
2013-10-23 23:58:36 +04:00
}
2014-04-15 05:17:18 +04:00
updatePointersMove ( tracker , event , gPoints ) ;
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
$ . cancelEvent ( event ) ;
2013-10-23 23:58:36 +04:00
}
2014-03-21 22:45:20 +04:00
/ * *
* @ private
* @ inner
* /
function onTouchCancel ( tracker , event ) {
2014-03-31 23:54:37 +04:00
var i ,
2014-03-21 22:45:20 +04:00
touchCount = event . changedTouches . length ,
gPoints = [ ] ;
for ( i = 0 ; i < touchCount ; i ++ ) {
gPoints . push ( {
id : event . changedTouches [ i ] . identifier ,
2014-06-14 13:15:40 +04:00
type : 'touch'
2014-03-21 22:45:20 +04:00
} ) ;
}
2014-04-15 05:17:18 +04:00
updatePointersCancel ( tracker , event , gPoints ) ;
2014-03-21 22:45:20 +04:00
}
2014-03-14 21:42:22 +04:00
/ * *
* @ private
* @ inner
* /
function onGestureStart ( tracker , event ) {
event . stopPropagation ( ) ;
event . preventDefault ( ) ;
return false ;
}
/ * *
* @ private
* @ inner
* /
function onGestureChange ( tracker , event ) {
event . stopPropagation ( ) ;
event . preventDefault ( ) ;
return false ;
}
2014-08-05 08:41:07 +04:00
/ * *
* @ private
* @ inner
* /
function onPointerOver ( tracker , event ) {
var gPoint ;
2014-08-06 03:17:40 +04:00
if ( this === event . relatedTarget || isParentChild ( event . currentTarget , event . relatedTarget ) ) {
2014-08-05 08:41:07 +04:00
return ;
}
gPoint = {
id : event . pointerId ,
type : getPointerType ( event ) ,
isPrimary : event . isPrimary ,
currentPos : getMouseAbsolute ( event ) ,
currentTime : $ . now ( )
} ;
updatePointersEnter ( tracker , event , [ gPoint ] ) ;
}
/ * *
* @ private
* @ inner
* /
function onPointerOut ( tracker , event ) {
var gPoint ;
2014-08-06 03:17:40 +04:00
if ( this === event . relatedTarget || isParentChild ( event . currentTarget , event . relatedTarget ) ) {
2014-08-05 08:41:07 +04:00
return ;
}
gPoint = {
id : event . pointerId ,
type : getPointerType ( event ) ,
isPrimary : event . isPrimary ,
currentPos : getMouseAbsolute ( event ) ,
currentTime : $ . now ( )
} ;
updatePointersExit ( tracker , event , [ gPoint ] ) ;
}
2014-03-21 22:45:20 +04:00
/ * *
* @ private
* @ inner
* /
function onPointerDown ( tracker , event ) {
2014-03-31 23:54:37 +04:00
var gPoint ;
2014-03-21 22:45:20 +04:00
gPoint = {
id : event . pointerId ,
type : getPointerType ( event ) ,
2014-04-01 20:32:04 +04:00
isPrimary : event . isPrimary ,
2014-03-31 23:54:37 +04:00
currentPos : getMouseAbsolute ( event ) ,
currentTime : $ . now ( )
2014-03-21 22:45:20 +04:00
} ;
2014-04-15 05:17:18 +04:00
if ( updatePointersDown ( tracker , event , [ gPoint ] , event . button ) ) {
2014-08-06 21:49:42 +04:00
capturePointer ( tracker , false ) ;
2014-03-30 04:02:24 +04:00
$ . stopEvent ( event ) ;
2014-04-15 05:17:18 +04:00
}
2014-04-22 20:23:56 +04:00
if ( tracker . clickHandler || tracker . dblClickHandler || tracker . pressHandler || tracker . dragHandler || tracker . dragEndHandler || tracker . pinchHandler ) {
2014-03-30 04:02:24 +04:00
$ . cancelEvent ( event ) ;
2014-03-21 22:45:20 +04:00
}
}
/ * *
* @ private
* @ inner
* /
function onPointerUp ( tracker , event ) {
2014-08-05 08:41:07 +04:00
handlePointerUp ( tracker , event ) ;
}
/ * *
* This handler is attached to the window object ( on the capture phase ) to emulate mouse capture .
* onPointerUp is still attached to the tracked element , so stop propagation to avoid processing twice .
*
* @ private
* @ inner
* /
function onPointerUpCaptured ( tracker , event ) {
2014-08-06 00:56:18 +04:00
var pointsList = tracker . getActivePointersListByType ( getPointerType ( event ) ) ;
if ( pointsList . getById ( event . pointerId ) ) {
handlePointerUp ( tracker , event ) ;
}
2014-08-05 08:41:07 +04:00
$ . stopEvent ( event ) ;
}
/ * *
* @ private
* @ inner
* /
function handlePointerUp ( tracker , event ) {
2014-03-31 23:54:37 +04:00
var gPoint ;
2014-03-21 22:45:20 +04:00
gPoint = {
id : event . pointerId ,
type : getPointerType ( event ) ,
2014-04-01 20:32:04 +04:00
isPrimary : event . isPrimary ,
2014-03-31 23:54:37 +04:00
currentPos : getMouseAbsolute ( event ) ,
currentTime : $ . now ( )
2014-03-21 22:45:20 +04:00
} ;
2014-04-15 05:17:18 +04:00
if ( updatePointersUp ( tracker , event , [ gPoint ] , event . button ) ) {
2014-08-06 21:49:42 +04:00
releasePointer ( tracker , false ) ;
2014-08-06 00:56:18 +04:00
//$.stopEvent( event );
2014-03-21 22:45:20 +04:00
}
}
/ * *
* @ private
* @ inner
* /
function onPointerMove ( tracker , event ) {
2014-08-05 08:41:07 +04:00
handlePointerMove ( tracker , event ) ;
}
/ * *
* This handler is attached to the window object ( on the capture phase ) to emulate mouse capture .
* onPointerMove is still attached to the tracked element , so stop propagation to avoid processing twice .
*
* @ private
* @ inner
* /
function onPointerMoveCaptured ( tracker , event ) {
2014-08-06 00:56:18 +04:00
var pointsList = tracker . getActivePointersListByType ( getPointerType ( event ) ) ;
if ( pointsList . getById ( event . pointerId ) ) {
handlePointerMove ( tracker , event ) ;
}
2014-08-05 08:41:07 +04:00
$ . stopEvent ( event ) ;
}
/ * *
* @ private
* @ inner
* /
function handlePointerMove ( tracker , event ) {
2014-03-21 22:45:20 +04:00
// Pointer changed coordinates, button state, pressure, tilt, or contact geometry (e.g. width and height)
2014-03-31 23:54:37 +04:00
var gPoint ;
2014-03-21 22:45:20 +04:00
gPoint = {
id : event . pointerId ,
type : getPointerType ( event ) ,
2014-04-01 20:32:04 +04:00
isPrimary : event . isPrimary ,
2014-03-31 23:54:37 +04:00
currentPos : getMouseAbsolute ( event ) ,
currentTime : $ . now ( )
2014-03-21 22:45:20 +04:00
} ;
2014-04-15 05:17:18 +04:00
updatePointersMove ( tracker , event , [ gPoint ] ) ;
2014-03-21 22:45:20 +04:00
}
/ * *
* @ private
* @ inner
* /
function onPointerCancel ( tracker , event ) {
2014-03-31 23:54:37 +04:00
var gPoint ;
2014-03-21 22:45:20 +04:00
gPoint = {
id : event . pointerId ,
2014-06-14 13:15:40 +04:00
type : getPointerType ( event )
2014-03-21 22:45:20 +04:00
} ;
2014-04-15 05:17:18 +04:00
updatePointersCancel ( tracker , event , [ gPoint ] ) ;
2014-03-21 22:45:20 +04:00
}
2014-04-03 19:50:25 +04:00
///////////////////////////////////////////////////////////////////////////////
2014-04-15 05:17:18 +04:00
// Device-agnostic DOM event handlers
2014-04-03 19:50:25 +04:00
///////////////////////////////////////////////////////////////////////////////
2013-10-23 23:58:36 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* @ function
2013-10-23 23:58:36 +04:00
* @ private
* @ inner
2014-04-15 05:17:18 +04:00
* @ param { OpenSeadragon . MouseTracker . GesturePointList } pointsList
* The GesturePointList to track the pointer in .
* @ param { OpenSeadragon . MouseTracker . GesturePoint } gPoint
* Gesture point to track .
* @ returns { Number } Number of gesture points in pointsList .
2013-10-23 23:58:36 +04:00
* /
2014-04-15 05:17:18 +04:00
function startTrackingPointer ( pointsList , gPoint ) {
2011-12-06 07:50:25 +04:00
2014-04-15 05:17:18 +04:00
// If isPrimary is not known for the pointer then set it according to our rules:
// true if the first pointer in the gesture, otherwise false
if ( ! gPoint . hasOwnProperty ( 'isPrimary' ) ) {
if ( pointsList . getLength ( ) === 0 ) {
gPoint . isPrimary = true ;
} else {
gPoint . isPrimary = false ;
2011-12-06 07:50:25 +04:00
}
2012-02-03 04:12:45 +04:00
}
2014-04-15 05:17:18 +04:00
gPoint . speed = 0 ;
gPoint . direction = 0 ;
gPoint . contactPos = gPoint . currentPos ;
gPoint . contactTime = gPoint . currentTime ;
gPoint . lastPos = gPoint . currentPos ;
gPoint . lastTime = gPoint . currentTime ;
return pointsList . add ( gPoint ) ;
2013-01-29 21:32:58 +04:00
}
2012-02-03 04:12:45 +04:00
2012-02-10 07:16:09 +04:00
2012-02-03 04:12:45 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* @ function
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
2014-04-15 05:17:18 +04:00
* @ param { OpenSeadragon . MouseTracker . GesturePointList } pointsList
* The GesturePointList to stop tracking the pointer on .
* @ param { OpenSeadragon . MouseTracker . GesturePoint } gPoint
* Gesture point to stop tracking .
* @ returns { Number } Number of gesture points in pointsList .
2013-09-06 21:43:39 +04:00
* /
2014-04-15 05:17:18 +04:00
function stopTrackingPointer ( pointsList , gPoint ) {
var listLength ,
primaryPoint ;
if ( pointsList . getById ( gPoint . id ) ) {
listLength = pointsList . removeById ( gPoint . id ) ;
// If isPrimary is not known for the pointer and we just removed the primary pointer from the list then we need to set another pointer as primary
if ( ! gPoint . hasOwnProperty ( 'isPrimary' ) ) {
primaryPoint = pointsList . getPrimary ( ) ;
if ( ! primaryPoint ) {
primaryPoint = pointsList . getByIndex ( 0 ) ;
if ( primaryPoint ) {
primaryPoint . isPrimary = true ;
}
}
}
} else {
listLength = pointsList . getLength ( ) ;
}
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
return listLength ;
}
2013-09-06 04:20:17 +04:00
2012-02-03 04:12:45 +04:00
2014-03-10 22:49:51 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* @ function
2014-03-10 22:49:51 +04:00
* @ private
* @ inner
2014-04-15 05:17:18 +04:00
* @ param { OpenSeadragon . MouseTracker } tracker
* A reference to the MouseTracker instance .
* @ param { Object } event
* A reference to the originating DOM event .
* @ param { Array . < OpenSeadragon . MouseTracker . GesturePoint > } gPoints
* Gesture points associated with the event .
2014-03-10 22:49:51 +04:00
* /
2014-04-16 00:04:08 +04:00
function updatePointersEnter ( tracker , event , gPoints ) {
2014-04-15 05:17:18 +04:00
var pointsList = tracker . getActivePointersListByType ( gPoints [ 0 ] . type ) ,
2014-03-10 22:49:51 +04:00
i ,
2014-03-21 22:45:20 +04:00
gPointCount = gPoints . length ,
curGPoint ,
updateGPoint ,
2014-03-10 22:49:51 +04:00
propagate ;
2012-02-03 04:12:45 +04:00
2014-04-15 05:17:18 +04:00
for ( i = 0 ; i < gPointCount ; i ++ ) {
curGPoint = gPoints [ i ] ;
updateGPoint = pointsList . getById ( curGPoint . id ) ;
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
if ( updateGPoint ) {
// Already tracking the pointer...update it
updateGPoint . insideElement = true ;
updateGPoint . lastPos = updateGPoint . currentPos ;
updateGPoint . lastTime = updateGPoint . currentTime ;
updateGPoint . currentPos = curGPoint . currentPos ;
updateGPoint . currentTime = curGPoint . currentTime ;
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
curGPoint = updateGPoint ;
} else {
// Initialize for tracking and add to the tracking list
curGPoint . captured = false ;
curGPoint . insideElementPressed = false ;
curGPoint . insideElement = true ;
startTrackingPointer ( pointsList , curGPoint ) ;
}
// Enter
if ( tracker . enterHandler ) {
propagate = tracker . enterHandler (
{
eventSource : tracker ,
pointerType : curGPoint . type ,
position : getPointRelativeToAbsolute ( curGPoint . currentPos , tracker . element ) ,
buttons : pointsList . buttons ,
insideElementPressed : curGPoint . insideElementPressed ,
2014-04-16 17:40:19 +04:00
buttonDownAny : pointsList . buttons !== 0 ,
2014-04-15 05:17:18 +04:00
isTouchEvent : curGPoint . type === 'touch' ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
2014-03-10 22:49:51 +04:00
}
2014-04-15 05:17:18 +04:00
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
2013-09-06 04:20:17 +04:00
}
2011-12-06 07:50:25 +04:00
}
2012-02-02 01:56:04 +04:00
}
2013-01-29 21:32:58 +04:00
}
2011-12-06 07:50:25 +04:00
2012-02-10 07:16:09 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* @ function
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
2014-04-15 05:17:18 +04:00
* @ param { OpenSeadragon . MouseTracker } tracker
* A reference to the MouseTracker instance .
* @ param { Object } event
* A reference to the originating DOM event .
* @ param { Array . < OpenSeadragon . MouseTracker . GesturePoint > } gPoints
* Gesture points associated with the event .
2013-09-06 21:43:39 +04:00
* /
2014-04-16 00:04:08 +04:00
function updatePointersExit ( tracker , event , gPoints ) {
2014-03-10 22:49:51 +04:00
var delegate = THIS [ tracker . hash ] ,
2014-04-15 05:17:18 +04:00
pointsList = tracker . getActivePointersListByType ( gPoints [ 0 ] . type ) ,
2014-03-10 22:49:51 +04:00
i ,
2014-03-21 22:45:20 +04:00
gPointCount = gPoints . length ,
curGPoint ,
updateGPoint ,
2014-03-10 22:49:51 +04:00
propagate ;
2012-02-10 07:16:09 +04:00
2014-04-15 05:17:18 +04:00
for ( i = 0 ; i < gPointCount ; i ++ ) {
curGPoint = gPoints [ i ] ;
updateGPoint = pointsList . getById ( curGPoint . id ) ;
2013-08-16 21:09:49 +04:00
2014-04-15 05:17:18 +04:00
if ( updateGPoint ) {
// Already tracking the pointer. If captured then update it, else stop tracking it
if ( updateGPoint . captured ) {
2014-03-30 04:02:24 +04:00
updateGPoint . insideElement = false ;
updateGPoint . lastPos = updateGPoint . currentPos ;
updateGPoint . lastTime = updateGPoint . currentTime ;
updateGPoint . currentPos = curGPoint . currentPos ;
updateGPoint . currentTime = curGPoint . currentTime ;
2014-04-15 05:17:18 +04:00
} else {
stopTrackingPointer ( pointsList , updateGPoint ) ;
2014-03-30 04:02:24 +04:00
}
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
curGPoint = updateGPoint ;
}
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
// Exit
if ( tracker . exitHandler ) {
propagate = tracker . exitHandler (
{
eventSource : tracker ,
pointerType : curGPoint . type ,
position : getPointRelativeToAbsolute ( curGPoint . currentPos , tracker . element ) ,
buttons : pointsList . buttons ,
insideElementPressed : updateGPoint ? updateGPoint . insideElementPressed : false ,
2014-04-16 17:40:19 +04:00
buttonDownAny : pointsList . buttons !== 0 ,
2014-04-15 05:17:18 +04:00
isTouchEvent : curGPoint . type === 'touch' ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
2014-03-30 04:02:24 +04:00
}
2014-04-15 05:17:18 +04:00
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
2014-03-10 22:49:51 +04:00
}
2012-02-10 07:16:09 +04:00
}
}
2013-01-29 21:32:58 +04:00
}
2012-02-10 07:16:09 +04:00
2014-03-10 22:49:51 +04:00
2012-02-03 04:12:45 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* @ function
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
2014-04-15 05:17:18 +04:00
* @ param { OpenSeadragon . MouseTracker } tracker
* A reference to the MouseTracker instance .
* @ param { Object } event
* A reference to the originating DOM event .
* @ param { Array . < OpenSeadragon . MouseTracker . GesturePoint > } gPoints
* Gesture points associated with the event .
* @ param { Number } buttonChanged
* The button involved in the event : - 1 : none , 0 : primary , 1 : aux , 2 : secondary , 3 : X1 , 4 : X2 , 5 : pen eraser .
* Note on chorded button presses ( a button pressed when another button is already pressed ) : In the W3C Pointer Events model ,
* only one pointerdown / pointerup event combo is fired . Chorded button state changes instead fire pointermove events .
*
* @ returns { Boolean } True if pointers should be captured to the tracked element , otherwise false .
2013-09-06 21:43:39 +04:00
* /
2014-04-15 05:17:18 +04:00
function updatePointersDown ( tracker , event , gPoints , buttonChanged ) {
2014-03-10 22:49:51 +04:00
var delegate = THIS [ tracker . hash ] ,
2014-04-15 05:17:18 +04:00
propagate ,
pointsList = tracker . getActivePointersListByType ( gPoints [ 0 ] . type ) ,
2014-03-10 22:49:51 +04:00
i ,
2014-03-21 22:45:20 +04:00
gPointCount = gPoints . length ,
curGPoint ,
2014-04-15 05:17:18 +04:00
updateGPoint ;
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
if ( typeof event . buttons !== 'undefined' ) {
pointsList . buttons = event . buttons ;
} else {
if ( buttonChanged === 0 ) {
// Primary
pointsList . buttons |= 1 ;
} else if ( buttonChanged === 1 ) {
// Aux
pointsList . buttons |= 4 ;
} else if ( buttonChanged === 2 ) {
// Secondary
pointsList . buttons |= 2 ;
} else if ( buttonChanged === 3 ) {
// X1 (Back)
pointsList . buttons |= 8 ;
} else if ( buttonChanged === 4 ) {
// X2 (Forward)
pointsList . buttons |= 16 ;
} else if ( buttonChanged === 5 ) {
// Pen Eraser
pointsList . buttons |= 32 ;
}
}
2014-03-30 04:02:24 +04:00
2014-04-15 05:17:18 +04:00
// Only capture and track primary button, pen, and touch contacts
//if ( buttonChanged !== 0 ) {
2014-04-16 06:19:47 +04:00
if ( buttonChanged !== 0 && buttonChanged !== 1 ) { //TODO Remove this IE8 compatibility and use the commented line above
2014-04-15 05:17:18 +04:00
return false ;
}
2014-03-30 04:02:24 +04:00
2014-04-15 05:17:18 +04:00
for ( i = 0 ; i < gPointCount ; i ++ ) {
curGPoint = gPoints [ i ] ;
updateGPoint = pointsList . getById ( curGPoint . id ) ;
if ( updateGPoint ) {
// Already tracking the pointer...update it
updateGPoint . captured = true ;
updateGPoint . insideElementPressed = true ;
updateGPoint . insideElement = true ;
updateGPoint . contactPos = curGPoint . currentPos ;
updateGPoint . contactTime = curGPoint . currentTime ;
updateGPoint . lastPos = updateGPoint . currentPos ;
updateGPoint . lastTime = updateGPoint . currentTime ;
updateGPoint . currentPos = curGPoint . currentPos ;
updateGPoint . currentTime = curGPoint . currentTime ;
curGPoint = updateGPoint ;
} else {
// Initialize for tracking and add to the tracking list (no pointerover or pointermove event occurred before this)
curGPoint . captured = true ;
curGPoint . insideElementPressed = true ;
curGPoint . insideElement = true ;
startTrackingPointer ( pointsList , curGPoint ) ;
2014-04-01 20:32:04 +04:00
}
2012-02-03 04:12:45 +04:00
2014-04-15 05:17:18 +04:00
pointsList . contacts ++ ;
2014-08-06 00:56:18 +04:00
//$.console.log('contacts++ ', pointsList.contacts);
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
if ( tracker . dragHandler || tracker . dragEndHandler || tracker . pinchHandler ) {
$ . MouseTracker . gesturePointVelocityTracker . addPoint ( tracker , curGPoint ) ;
2014-03-31 23:54:37 +04:00
}
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
if ( pointsList . contacts === 1 ) {
// Press
if ( tracker . pressHandler ) {
propagate = tracker . pressHandler (
2014-03-10 22:49:51 +04:00
{
eventSource : tracker ,
2014-04-15 05:17:18 +04:00
pointerType : curGPoint . type ,
position : getPointRelativeToAbsolute ( curGPoint . contactPos , tracker . element ) ,
buttons : pointsList . buttons ,
isTouchEvent : curGPoint . type === 'touch' ,
2014-03-10 22:49:51 +04:00
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
2014-04-15 05:17:18 +04:00
} else if ( pointsList . contacts === 2 ) {
if ( tracker . pinchHandler && curGPoint . type === 'touch' ) {
// Initialize for pinch
delegate . pinchGPoints = pointsList . asArray ( ) ;
delegate . lastPinchDist = delegate . currentPinchDist = delegate . pinchGPoints [ 0 ] . currentPos . distanceTo ( delegate . pinchGPoints [ 1 ] . currentPos ) ;
delegate . lastPinchCenter = delegate . currentPinchCenter = getCenterPoint ( delegate . pinchGPoints [ 0 ] . currentPos , delegate . pinchGPoints [ 1 ] . currentPos ) ;
2014-03-10 22:49:51 +04:00
}
}
}
2014-04-15 05:17:18 +04:00
return true ;
2013-01-29 21:32:58 +04:00
}
2011-12-06 07:50:25 +04:00
2014-03-10 22:49:51 +04:00
2012-02-01 06:01:37 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* @ function
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
2014-04-15 05:17:18 +04:00
* @ param { OpenSeadragon . MouseTracker } tracker
* A reference to the MouseTracker instance .
* @ param { Object } event
* A reference to the originating DOM event .
* @ param { Array . < OpenSeadragon . MouseTracker . GesturePoint > } gPoints
* Gesture points associated with the event .
* @ param { Number } buttonChanged
* The button involved in the event : - 1 : none , 0 : primary , 1 : aux , 2 : secondary , 3 : X1 , 4 : X2 , 5 : pen eraser .
* Note on chorded button presses ( a button pressed when another button is already pressed ) : In the W3C Pointer Events model ,
* only one pointerdown / pointerup event combo is fired . Chorded button state changes instead fire pointermove events .
*
* @ returns { Boolean } True if pointer capture should be released from the tracked element , otherwise false .
2013-09-06 21:43:39 +04:00
* /
2014-04-15 05:17:18 +04:00
function updatePointersUp ( tracker , event , gPoints , buttonChanged ) {
2014-03-10 22:49:51 +04:00
var delegate = THIS [ tracker . hash ] ,
2014-04-15 05:17:18 +04:00
pointsList = tracker . getActivePointersListByType ( gPoints [ 0 ] . type ) ,
2014-03-10 22:49:51 +04:00
propagate ,
insideElementReleased ,
releasePoint ,
2014-03-30 04:02:24 +04:00
releaseTime ,
2014-03-10 22:49:51 +04:00
i ,
2014-03-21 22:45:20 +04:00
gPointCount = gPoints . length ,
curGPoint ,
2014-03-30 04:02:24 +04:00
updateGPoint ,
2014-04-15 05:17:18 +04:00
releaseCapture = false ,
2014-04-22 20:23:56 +04:00
wasCaptured = false ,
quick ;
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
if ( typeof event . buttons !== 'undefined' ) {
pointsList . buttons = event . buttons ;
} else {
if ( buttonChanged === 0 ) {
// Primary
pointsList . buttons ^= ~ 1 ;
} else if ( buttonChanged === 1 ) {
// Aux
pointsList . buttons ^= ~ 4 ;
} else if ( buttonChanged === 2 ) {
// Secondary
pointsList . buttons ^= ~ 2 ;
} else if ( buttonChanged === 3 ) {
// X1 (Back)
pointsList . buttons ^= ~ 8 ;
} else if ( buttonChanged === 4 ) {
// X2 (Forward)
pointsList . buttons ^= ~ 16 ;
} else if ( buttonChanged === 5 ) {
// Pen Eraser
pointsList . buttons ^= ~ 32 ;
}
}
// Only capture and track primary button, pen, and touch contacts
//if ( buttonChanged !== 0 ) {
2014-04-16 06:19:47 +04:00
if ( buttonChanged !== 0 && buttonChanged !== 1 ) { //TODO Remove this IE8 compatibility and use the commented line above
2014-04-15 05:17:18 +04:00
return false ;
}
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
for ( i = 0 ; i < gPointCount ; i ++ ) {
curGPoint = gPoints [ i ] ;
updateGPoint = pointsList . getById ( curGPoint . id ) ;
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
if ( updateGPoint ) {
// Update the pointer, stop tracking it if not still in this element
if ( updateGPoint . captured ) {
updateGPoint . captured = false ;
releaseCapture = true ;
wasCaptured = true ;
}
updateGPoint . lastPos = updateGPoint . currentPos ;
updateGPoint . lastTime = updateGPoint . currentTime ;
updateGPoint . currentPos = curGPoint . currentPos ;
updateGPoint . currentTime = curGPoint . currentTime ;
if ( ! updateGPoint . insideElement ) {
stopTrackingPointer ( pointsList , updateGPoint ) ;
}
2014-03-30 04:02:24 +04:00
2014-04-15 05:17:18 +04:00
releasePoint = updateGPoint . currentPos ;
releaseTime = updateGPoint . currentTime ;
2014-03-30 04:02:24 +04:00
2014-04-15 05:17:18 +04:00
if ( wasCaptured ) {
// Pointer was activated in our element but could have been removed in any element since events are captured to our element
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
pointsList . contacts -- ;
2014-08-06 00:56:18 +04:00
//$.console.log('contacts-- ', pointsList.contacts);
2014-03-30 04:02:24 +04:00
2014-04-15 05:17:18 +04:00
if ( tracker . dragHandler || tracker . dragEndHandler || tracker . pinchHandler ) {
$ . MouseTracker . gesturePointVelocityTracker . removePoint ( tracker , updateGPoint ) ;
}
2014-03-30 04:02:24 +04:00
2014-04-15 05:17:18 +04:00
if ( pointsList . contacts === 0 ) {
2014-03-30 04:02:24 +04:00
2014-04-15 05:17:18 +04:00
// Release (pressed in our element)
2014-03-30 04:02:24 +04:00
if ( tracker . releaseHandler ) {
propagate = tracker . releaseHandler (
{
eventSource : tracker ,
2014-04-15 05:17:18 +04:00
pointerType : updateGPoint . type ,
2014-03-31 23:54:37 +04:00
position : getPointRelativeToAbsolute ( releasePoint , tracker . element ) ,
2014-04-15 05:17:18 +04:00
buttons : pointsList . buttons ,
insideElementPressed : updateGPoint . insideElementPressed ,
insideElementReleased : updateGPoint . insideElement ,
isTouchEvent : updateGPoint . type === 'touch' ,
2014-03-30 04:02:24 +04:00
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
2014-03-10 22:49:51 +04:00
2014-03-30 04:02:24 +04:00
// Drag End
2014-04-15 05:17:18 +04:00
if ( tracker . dragEndHandler && ! updateGPoint . currentPos . equals ( updateGPoint . contactPos ) ) {
2014-03-30 04:02:24 +04:00
propagate = tracker . dragEndHandler (
{
eventSource : tracker ,
2014-04-15 05:17:18 +04:00
pointerType : updateGPoint . type ,
position : getPointRelativeToAbsolute ( updateGPoint . currentPos , tracker . element ) ,
speed : updateGPoint . speed ,
direction : updateGPoint . direction ,
2014-03-30 04:02:24 +04:00
shift : event . shiftKey ,
2014-04-15 05:17:18 +04:00
isTouchEvent : updateGPoint . type === 'touch' ,
2014-03-30 04:02:24 +04:00
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
2014-04-22 20:23:56 +04:00
// Click / Double-Click
if ( ( tracker . clickHandler || tracker . dblClickHandler ) && updateGPoint . insideElement ) {
quick = releaseTime - updateGPoint . contactTime <= tracker . clickTimeThreshold &&
updateGPoint . contactPos . distanceTo ( releasePoint ) <= tracker . clickDistThreshold ;
// Click
if ( tracker . clickHandler ) {
propagate = tracker . clickHandler (
{
eventSource : tracker ,
pointerType : updateGPoint . type ,
position : getPointRelativeToAbsolute ( updateGPoint . currentPos , tracker . element ) ,
quick : quick ,
shift : event . shiftKey ,
isTouchEvent : updateGPoint . type === 'touch' ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
2014-03-30 04:02:24 +04:00
2014-04-22 20:23:56 +04:00
// Double-Click
if ( tracker . dblClickHandler && quick ) {
pointsList . clicks ++ ;
if ( pointsList . clicks === 1 ) {
delegate . lastClickPos = releasePoint ;
/*jshint loopfunc:true*/
delegate . dblClickTimeOut = setTimeout ( function ( ) {
pointsList . clicks = 0 ;
} , tracker . dblClickTimeThreshold ) ;
/*jshint loopfunc:false*/
} else if ( pointsList . clicks === 2 ) {
clearTimeout ( delegate . dblClickTimeOut ) ;
pointsList . clicks = 0 ;
if ( delegate . lastClickPos . distanceTo ( releasePoint ) <= tracker . dblClickDistThreshold ) {
propagate = tracker . dblClickHandler (
{
eventSource : tracker ,
pointerType : updateGPoint . type ,
position : getPointRelativeToAbsolute ( updateGPoint . currentPos , tracker . element ) ,
shift : event . shiftKey ,
isTouchEvent : updateGPoint . type === 'touch' ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
delegate . lastClickPos = null ;
2014-03-30 04:02:24 +04:00
}
}
}
2014-04-15 05:17:18 +04:00
} else if ( pointsList . contacts === 2 ) {
if ( tracker . pinchHandler && updateGPoint . type === 'touch' ) {
2014-03-30 04:02:24 +04:00
// Reset for pinch
delegate . pinchGPoints = pointsList . asArray ( ) ;
delegate . lastPinchDist = delegate . currentPinchDist = delegate . pinchGPoints [ 0 ] . currentPos . distanceTo ( delegate . pinchGPoints [ 1 ] . currentPos ) ;
delegate . lastPinchCenter = delegate . currentPinchCenter = getCenterPoint ( delegate . pinchGPoints [ 0 ] . currentPos , delegate . pinchGPoints [ 1 ] . currentPos ) ;
2014-03-10 22:49:51 +04:00
}
}
2014-04-15 05:17:18 +04:00
} else {
// Pointer was activated in another element but removed in our element
// Release (pressed in another element)
if ( tracker . releaseHandler ) {
propagate = tracker . releaseHandler (
{
eventSource : tracker ,
pointerType : updateGPoint . type ,
position : getPointRelativeToAbsolute ( releasePoint , tracker . element ) ,
buttons : pointsList . buttons ,
insideElementPressed : updateGPoint . insideElementPressed ,
insideElementReleased : updateGPoint . insideElement ,
isTouchEvent : updateGPoint . type === 'touch' ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
2014-03-10 22:49:51 +04:00
}
}
}
2014-04-15 05:17:18 +04:00
return releaseCapture ;
2013-01-29 21:32:58 +04:00
}
2011-12-06 07:50:25 +04:00
2014-03-10 22:49:51 +04:00
2012-02-01 06:01:37 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* Call when pointer ( s ) change coordinates , button state , pressure , tilt , or contact geometry ( e . g . width and height )
*
* @ function
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
2014-04-15 05:17:18 +04:00
* @ param { OpenSeadragon . MouseTracker } tracker
* A reference to the MouseTracker instance .
* @ param { Object } event
* A reference to the originating DOM event .
* @ param { Array . < OpenSeadragon . MouseTracker . GesturePoint > } gPoints
* Gesture points associated with the event .
2013-09-06 21:43:39 +04:00
* /
2014-04-15 05:17:18 +04:00
function updatePointersMove ( tracker , event , gPoints ) {
var delegate = THIS [ tracker . hash ] ,
pointsList = tracker . getActivePointersListByType ( gPoints [ 0 ] . type ) ,
i ,
gPointCount = gPoints . length ,
curGPoint ,
updateGPoint ,
gPointArray ,
delta ,
propagate ;
2011-12-06 07:50:25 +04:00
2014-04-15 05:17:18 +04:00
if ( typeof event . buttons !== 'undefined' ) {
pointsList . buttons = event . buttons ;
}
2014-03-10 22:49:51 +04:00
2014-04-15 05:17:18 +04:00
for ( i = 0 ; i < gPointCount ; i ++ ) {
curGPoint = gPoints [ i ] ;
updateGPoint = pointsList . getById ( curGPoint . id ) ;
if ( updateGPoint ) {
// Already tracking the pointer...update it
if ( curGPoint . hasOwnProperty ( 'isPrimary' ) ) {
updateGPoint . isPrimary = curGPoint . isPrimary ;
}
updateGPoint . lastPos = updateGPoint . currentPos ;
updateGPoint . lastTime = updateGPoint . currentTime ;
updateGPoint . currentPos = curGPoint . currentPos ;
updateGPoint . currentTime = curGPoint . currentTime ;
} else {
// Initialize for tracking and add to the tracking list (no pointerover or pointerdown event occurred before this)
curGPoint . captured = false ;
curGPoint . insideElementPressed = false ;
curGPoint . insideElement = true ;
startTrackingPointer ( pointsList , curGPoint ) ;
}
}
// Stop (mouse only)
if ( tracker . stopHandler && gPoints [ 0 ] . type === 'mouse' ) {
clearTimeout ( tracker . stopTimeOut ) ;
tracker . stopTimeOut = setTimeout ( function ( ) {
handlePointerStop ( tracker , event , gPoints [ 0 ] . type ) ;
} , tracker . stopDelay ) ;
}
if ( pointsList . contacts === 0 ) {
// Move (no contacts: hovering mouse or other hover-capable device)
if ( tracker . moveHandler ) {
propagate = tracker . moveHandler (
{
eventSource : tracker ,
pointerType : gPoints [ 0 ] . type ,
position : getPointRelativeToAbsolute ( gPoints [ 0 ] . currentPos , tracker . element ) ,
buttons : pointsList . buttons ,
isTouchEvent : gPoints [ 0 ] . type === 'touch' ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
} else if ( pointsList . contacts === 1 ) {
// Move (1 contact)
if ( tracker . moveHandler ) {
updateGPoint = pointsList . asArray ( ) [ 0 ] ;
propagate = tracker . moveHandler (
{
eventSource : tracker ,
pointerType : updateGPoint . type ,
position : getPointRelativeToAbsolute ( updateGPoint . currentPos , tracker . element ) ,
buttons : pointsList . buttons ,
isTouchEvent : updateGPoint . type === 'touch' ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
// Drag
if ( tracker . dragHandler ) {
updateGPoint = pointsList . asArray ( ) [ 0 ] ;
delta = updateGPoint . currentPos . minus ( updateGPoint . lastPos ) ;
propagate = tracker . dragHandler (
{
eventSource : tracker ,
pointerType : updateGPoint . type ,
position : getPointRelativeToAbsolute ( updateGPoint . currentPos , tracker . element ) ,
buttons : pointsList . buttons ,
delta : delta ,
speed : updateGPoint . speed ,
direction : updateGPoint . direction ,
shift : event . shiftKey ,
isTouchEvent : updateGPoint . type === 'touch' ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
} else if ( pointsList . contacts === 2 ) {
// Move (2 contacts, use center)
if ( tracker . moveHandler ) {
gPointArray = pointsList . asArray ( ) ;
propagate = tracker . moveHandler (
{
eventSource : tracker ,
pointerType : gPointArray [ 0 ] . type ,
position : getPointRelativeToAbsolute ( getCenterPoint ( gPointArray [ 0 ] . currentPos , gPointArray [ 1 ] . currentPos ) , tracker . element ) ,
buttons : pointsList . buttons ,
isTouchEvent : gPointArray [ 0 ] . type === 'touch' ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
// Pinch
if ( tracker . pinchHandler && gPoints [ 0 ] . type === 'touch' ) {
delta = delegate . pinchGPoints [ 0 ] . currentPos . distanceTo ( delegate . pinchGPoints [ 1 ] . currentPos ) ;
if ( delta != delegate . currentPinchDist ) {
delegate . lastPinchDist = delegate . currentPinchDist ;
delegate . currentPinchDist = delta ;
delegate . lastPinchCenter = delegate . currentPinchCenter ;
delegate . currentPinchCenter = getCenterPoint ( delegate . pinchGPoints [ 0 ] . currentPos , delegate . pinchGPoints [ 1 ] . currentPos ) ;
propagate = tracker . pinchHandler (
{
eventSource : tracker ,
pointerType : 'touch' ,
gesturePoints : delegate . pinchGPoints ,
lastCenter : getPointRelativeToAbsolute ( delegate . lastPinchCenter , tracker . element ) ,
center : getPointRelativeToAbsolute ( delegate . currentPinchCenter , tracker . element ) ,
lastDistance : delegate . lastPinchDist ,
distance : delegate . currentPinchDist ,
shift : event . shiftKey ,
originalEvent : event ,
preventDefaultAction : false ,
userData : tracker . userData
}
) ;
if ( propagate === false ) {
$ . cancelEvent ( event ) ;
}
}
}
}
}
2014-04-03 19:50:25 +04:00
2014-03-10 22:49:51 +04:00
2012-02-01 06:01:37 +04:00
/ * *
2014-04-15 05:17:18 +04:00
* @ function
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
2014-04-15 05:17:18 +04:00
* @ param { OpenSeadragon . MouseTracker } tracker
* A reference to the MouseTracker instance .
* @ param { Object } event
* A reference to the originating DOM event .
* @ param { Array . < OpenSeadragon . MouseTracker . GesturePoint > } gPoints
* Gesture points associated with the event .
2013-09-06 21:43:39 +04:00
* /
2014-04-15 05:17:18 +04:00
function updatePointersCancel ( tracker , event , gPoints ) {
2014-04-16 06:19:47 +04:00
updatePointersUp ( tracker , event , gPoints , 0 ) ;
updatePointersExit ( tracker , event , gPoints ) ;
2013-01-29 21:32:58 +04:00
}
2011-12-14 05:04:38 +04:00
2014-04-15 05:17:18 +04:00
2012-02-01 06:01:37 +04:00
/ * *
2013-09-06 21:43:39 +04:00
* @ private
* @ inner
* /
2014-04-15 05:17:18 +04:00
function handlePointerStop ( tracker , originalMoveEvent , pointerType ) {
if ( tracker . stopHandler ) {
tracker . stopHandler ( {
eventSource : tracker ,
pointerType : pointerType ,
position : getMouseRelative ( originalMoveEvent , tracker . element ) ,
buttons : tracker . getActivePointersListByType ( pointerType ) . buttons ,
isTouchEvent : pointerType === 'touch' ,
originalEvent : originalMoveEvent ,
preventDefaultAction : false ,
userData : tracker . userData
} ) ;
2011-12-14 05:04:38 +04:00
}
2014-04-15 05:17:18 +04:00
}
2013-06-19 21:33:25 +04:00
2013-09-06 04:20:17 +04:00
} ( OpenSeadragon ) ) ;