diff --git a/src/mousetracker.js b/src/mousetracker.js
index 86238d8c..f70bef3f 100644
--- a/src/mousetracker.js
+++ b/src/mousetracker.js
@@ -84,7 +84,11 @@
* @param {OpenSeadragon.EventHandler} [options.clickHandler=null]
* An optional handler for mouse click.
* @param {OpenSeadragon.EventHandler} [options.dragHandler=null]
- * An optional handler for mouse drag.
+ * An optional handler for the drag gesture.
+ * @param {OpenSeadragon.EventHandler} [options.pinchHandler=null]
+ * An optional handler for the pinch gesture.
+ * @param {OpenSeadragon.EventHandler} [options.swipeHandler=null]
+ * An optional handler for the swipe gesture.
* @param {OpenSeadragon.EventHandler} [options.keyHandler=null]
* An optional handler for keypress.
* @param {OpenSeadragon.EventHandler} [options.focusHandler=null]
@@ -136,6 +140,8 @@
this.scrollHandler = options.scrollHandler || null;
this.clickHandler = options.clickHandler || null;
this.dragHandler = options.dragHandler || null;
+ this.pinchHandler = options.pinchHandler || null;
+ this.swipeHandler = options.swipeHandler || null;
this.stopHandler = options.stopHandler || null;
this.keyHandler = options.keyHandler || null;
this.focusHandler = options.focusHandler || null;
@@ -163,34 +169,57 @@
* Position of last mouse down
*/
THIS[ this.hash ] = {
- mouseover: function ( event ) { onMouseOver( _this, event, false ); },
- mouseout: function ( event ) { onMouseOut( _this, event, false ); },
- mousedown: function ( event ) { onMouseDown( _this, event ); },
- mouseup: function ( event ) { onMouseUp( _this, event, false ); },
- mousemove: function ( event ) { onMouseMove( _this, event ); },
- click: function ( event ) { onMouseClick( _this, event ); },
+ click: function ( event ) { onClick( _this, event ); },
+ keypress: function ( event ) { onKeyPress( _this, event ); },
+ focus: function ( event ) { onFocus( _this, event ); },
+ blur: function ( event ) { onBlur( _this, event ); },
wheel: function ( event ) { onWheel( _this, event ); },
mousewheel: function ( event ) { onMouseWheel( _this, event ); },
DOMMouseScroll: function ( event ) { onMouseWheel( _this, event ); },
MozMousePixelScroll: function ( event ) { onMouseWheel( _this, event ); },
- mouseupie: function ( event ) { onMouseUpIE( _this, event ); },
+ pointerover: function ( event ) { onPointerOver( _this, event ); },
+ MSPointerOver: function ( event ) { onPointerOver( _this, event ); },
+ mouseover: function ( event ) { onMouseOver( _this, event ); },
+ pointerout: function ( event ) { onPointerOut( _this, event ); },
+ MSPointerOut: function ( event ) { onPointerOut( _this, event ); },
+ mouseout: function ( event ) { onMouseOut( _this, event ); },
+ pointerdown: function ( event ) { onPointerDown( _this, event ); },
+ MSPointerDown: function ( event ) { onPointerDown( _this, event ); },
+ mousedown: function ( event ) { onMouseDown( _this, event ); },
+ pointerup: function ( event ) { onPointerUp( _this, event ); },
+ MSPointerUp: function ( event ) { onPointerUp( _this, event ); },
+ mouseup: function ( event ) { onMouseUp( _this, event ); },
+ pointermove: function ( event ) { onPointerMove( _this, event ); },
+ MSPointerMove: function ( event ) { onPointerMove( _this, event ); },
+ mousemove: function ( event ) { onMouseMove( _this, event ); },
+ pointercancel: function ( event ) { onPointerCancel( _this, event ); },
+ MSPointerCancel: function ( event ) { onPointerCancel( _this, event ); },
+ mouseupcapturedie: function ( event ) { onMouseUpCapturedIE( _this, event ); },
mousemovecapturedie: function ( event ) { onMouseMoveCapturedIE( _this, event ); },
mouseupcaptured: function ( event ) { onMouseUpCaptured( _this, event ); },
- mousemovecaptured: function ( event ) { onMouseMoveCaptured( _this, event, false ); },
+ mousemovecaptured: function ( event ) { onMouseMoveCaptured( _this, event ); },
touchstart: function ( event ) { onTouchStart( _this, event ); },
touchmove: function ( event ) { onTouchMove( _this, event ); },
touchend: function ( event ) { onTouchEnd( _this, event ); },
- keypress: function ( event ) { onKeyPress( _this, event ); },
- focus: function ( event ) { onFocus( _this, event ); },
- blur: function ( event ) { onBlur( _this, event ); },
tracking: false,
capturing: false,
- insideElementPressed: false,
- insideElement: false,
- lastPoint: null,
- lastMouseDownTime: null,
- lastMouseDownPoint: null,
- lastPinchDelta: 0
+ // Contact Points
+ mousePoints: {},
+ mousePointCount: 0,
+ touchPoints: {},
+ touchPointCount: 0,
+ penPoints: {},
+ penPointCount: 0,
+ // Tracking for pinch gesture
+ lastPinchDist: 0,
+ currentPinchDist: 0,
+
+ //insideElementPressed: false,
+ //insideElement: false,
+ //lastPoint: null,
+ //lastMouseDownTime: null,
+ //lastMouseDownPoint: null,
+ //lastPinchDelta: 0,
};
};
@@ -247,7 +276,7 @@
* @param {Boolean} event.buttonDownAny
* Was the button down anywhere in the screen during the event.
* @param {Boolean} event.isTouchEvent
- * True if the original event is a touch event, otherwise false.
+ * True if the original event is a touch event, otherwise false. Deprecated. Examine originalEvent instead.
* @param {Object} event.originalEvent
* The original event object.
* @param {Boolean} event.preventDefaultAction
@@ -272,7 +301,7 @@
* @param {Boolean} event.buttonDownAny
* Was the button down anywhere in the screen during the event.
* @param {Boolean} event.isTouchEvent
- * True if the original event is a touch event, otherwise false.
+ * True if the original event is a touch event, otherwise false. Deprecated. Examine originalEvent instead.
* @param {Object} event.originalEvent
* The original event object.
* @param {Boolean} event.preventDefaultAction
@@ -292,7 +321,7 @@
* @param {OpenSeadragon.Point} event.position
* The position of the event relative to the tracked element.
* @param {Boolean} event.isTouchEvent
- * True if the original event is a touch event, otherwise false.
+ * True if the original event is a touch event, otherwise false. Deprecated. Examine originalEvent instead.
* @param {Object} event.originalEvent
* The original event object.
* @param {Boolean} event.preventDefaultAction
@@ -317,7 +346,7 @@
* @param {Boolean} event.insideElementReleased
* True if the cursor still inside the tracked element when the button was released.
* @param {Boolean} event.isTouchEvent
- * True if the original event is a touch event, otherwise false.
+ * True if the original event is a touch event, otherwise false. Deprecated. Examine originalEvent instead.
* @param {Object} event.originalEvent
* The original event object.
* @param {Boolean} event.preventDefaultAction
@@ -337,7 +366,7 @@
* @param {OpenSeadragon.Point} event.position
* The position of the event relative to the tracked element.
* @param {Boolean} event.isTouchEvent
- * True if the original event is a touch event, otherwise false.
+ * True if the original event is a touch event, otherwise false. Deprecated. Examine originalEvent instead.
* @param {Object} event.originalEvent
* The original event object.
* @param {Boolean} event.preventDefaultAction
@@ -361,7 +390,7 @@
* @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.
+ * True if the original event is a touch event, otherwise false. Deprecated. Examine originalEvent instead.
* @param {Object} event.originalEvent
* The original event object.
* @param {Boolean} event.preventDefaultAction
@@ -385,7 +414,7 @@
* @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.
+ * True if the original event is a touch event, otherwise false. Deprecated. Examine originalEvent instead.
* @param {Object} event.originalEvent
* The original event object.
* @param {Boolean} event.preventDefaultAction
@@ -409,7 +438,7 @@
* @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.
+ * True if the original event is a touch event, otherwise false. Deprecated. Examine originalEvent instead.
* @param {Object} event.originalEvent
* The original event object.
* @param {Boolean} event.preventDefaultAction
@@ -428,8 +457,56 @@
* A reference to the tracker instance.
* @param {OpenSeadragon.Point} event.position
* The position of the event relative to the tracked element.
+ * @param {OpenSeadragon.Point} event.delta
+ * The x,y components of the difference between start drag and end drag. Usefule for ignoring or weighting the events.
+ * @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.
+ * True if the original event is a touch event, otherwise false. Deprecated. Examine originalEvent instead.
+ * @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.
+ */
+ pinchHandler: function () { },
+
+ /**
+ * 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 {OpenSeadragon.Point} event.position
+ * The position of the event relative to the tracked element.
+ * @param {OpenSeadragon.Point} event.delta
+ * The x,y components of the difference between start drag and end drag. Usefule for ignoring or weighting the events.
+ * @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. Deprecated. Examine originalEvent instead.
+ * @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.
+ */
+ swipeHandler: function () { },
+
+ /**
+ * 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 {OpenSeadragon.Point} event.position
+ * The position of the event relative to the tracked element.
+ * @param {Boolean} event.isTouchEvent
+ * True if the original event is a touch event, otherwise false. Deprecated. Examine originalEvent instead.
* @param {Object} event.originalEvent
* The original event object.
* @param {Boolean} event.preventDefaultAction
@@ -492,40 +569,75 @@
blurHandler: function () { }
};
+
/**
- * Detect available mouse wheel event.
+ * Detect available mouse wheel event name.
*/
$.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
+ /**
+ * Detect browser pointer/touch event model and build appropriate list of events to subscribe to.
+ */
+ $.MouseTracker.subscribeEvents = [ "click", "keypress", "focus", "blur", $.MouseTracker.wheelEventName ];
+
+ 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)
+ $.MouseTracker.subscribeEvents.push( "pointerover", "pointerout", "pointerdown", "pointerup", "pointermove", "pointercancel" );
+ $.MouseTracker.unprefixedPointerEvents = true;
+ if( navigator.maxTouchPoints ) {
+ $.MouseTracker.maxTouchPoints = navigator.maxTouchPoints;
+ }
+ else {
+ $.MouseTracker.maxTouchPoints = 0;
+ }
+ }
+ else if ( window.MSPointerEvent ) {
+ // IE10
+ $.MouseTracker.subscribeEvents.push( "MSPointerOver", "MSPointerOut", "MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel" );
+ $.MouseTracker.unprefixedPointerEvents = false;
+ if( navigator.msMaxTouchPoints ) {
+ $.MouseTracker.maxTouchPoints = navigator.msMaxTouchPoints;
+ }
+ else {
+ $.MouseTracker.maxTouchPoints = 0;
+ }
+ }
+ else {
+ $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout", "mousedown", "mouseup", "mousemove" );
+ if ( 'ontouchstart' in window ) {
+ // iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505)
+ $.MouseTracker.subscribeEvents.push( "touchstart", "touchmove", "touchend" );
+ }
+ $.MouseTracker.mousePointerId = "legacy-mouse";
+ $.MouseTracker.maxTouchPoints = 10;
+ }
+
+
+//*******************************************************************************************************************************************
+//** Utility Functions
+
+
/**
* Starts tracking mouse events on this element.
* @private
* @inner
*/
function startTracking( tracker ) {
- var events = [
- "mouseover", "mouseout", "mousedown", "mouseup", "mousemove",
- "click",
- $.MouseTracker.wheelEventName,
- "touchstart", "touchmove", "touchend",
- "keypress",
- "focus", "blur"
- ],
- delegate = THIS[ tracker.hash ],
+ var delegate = THIS[ tracker.hash ],
event,
i;
- // Add 'MozMousePixelScroll' event handler for older Firefox
- if( $.MouseTracker.wheelEventName == "DOMMouseScroll" ) {
- events.push( "MozMousePixelScroll" );
- }
-
if ( !delegate.tracking ) {
- for ( i = 0; i < events.length; i++ ) {
- event = events[ i ];
+ for ( i = 0; i < $.MouseTracker.subscribeEvents.length; i++ ) {
+ event = $.MouseTracker.subscribeEvents[ i ];
$.addEvent(
tracker.element,
event,
@@ -544,26 +656,13 @@
* @inner
*/
function stopTracking( tracker ) {
- var events = [
- "mouseover", "mouseout", "mousedown", "mouseup", "mousemove",
- "click",
- $.MouseTracker.wheelEventName,
- "touchstart", "touchmove", "touchend",
- "keypress",
- "focus", "blur"
- ],
- delegate = THIS[ tracker.hash ],
+ var delegate = THIS[ tracker.hash ],
event,
i;
- // Remove 'MozMousePixelScroll' event handler for older Firefox
- if( $.MouseTracker.wheelEventName == "DOMMouseScroll" ) {
- events.push( "MozMousePixelScroll" );
- }
-
if ( delegate.tracking ) {
- for ( i = 0; i < events.length; i++ ) {
- event = events[ i ];
+ for ( i = 0; i < $.MouseTracker.subscribeEvents.length; i++ ) {
+ event = $.MouseTracker.subscribeEvents[ i ];
$.removeEvent(
tracker.element,
event,
@@ -605,7 +704,7 @@
$.addEvent(
tracker.element,
"mouseup",
- delegate.mouseupie,
+ delegate.mouseupcapturedie,
true
);
$.addEvent(
@@ -652,7 +751,7 @@
$.removeEvent(
tracker.element,
"mouseup",
- delegate.mouseupie,
+ delegate.mouseupcapturedie,
true
);
$.addEvent(
@@ -684,11 +783,112 @@
* @private
* @inner
*/
- function triggerOthers( tracker, handler, event, isTouch ) {
- var otherHash;
- for ( otherHash in ACTIVE ) {
- if ( ACTIVE.hasOwnProperty( otherHash ) && tracker.hash != otherHash ) {
- handler( ACTIVE[ otherHash ], event, isTouch );
+ //function triggerOthers( tracker, handler, event, isTouch ) {
+ // var otherHash;
+ // for ( otherHash in ACTIVE ) {
+ // if ( ACTIVE.hasOwnProperty( otherHash ) && tracker.hash != otherHash ) {
+ // handler( ACTIVE[ otherHash ], event, isTouch );
+ // }
+ // }
+ //}
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function getPointerType( event ) {
+ var pointerTypeStr;
+ if ( $.MouseTracker.unprefixedPointerEvents ) {
+ pointerTypeStr = event.pointerType;
+ }
+ else {
+ // 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 = '';
+ }
+ }
+ return pointerTypeStr;
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function getMouseAbsolute( event ) {
+ return $.getMousePosition( event );
+ }
+
+ /**
+ * @private
+ * @inner
+ */
+ function getMouseRelative( event, element ) {
+ return getPointRelative( getMouseAbsolute( event ), element );
+ }
+
+ /**
+ * @private
+ * @inner
+ */
+ function getPointRelative( point, element ) {
+ var offset = $.getElementOffset( element );
+ return point.minus( offset );
+ }
+
+
+//*******************************************************************************************************************************************
+//** DOM EVent Handlers
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onClick( tracker, event ) {
+ if ( tracker.clickHandler ) {
+ $.cancelEvent( event );
+ }
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onKeyPress( tracker, event ) {
+ //console.log( "keypress %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey );
+ var propagate;
+ if ( tracker.keyHandler ) {
+ event = $.getEvent( event );
+ propagate = tracker.keyHandler(
+ {
+ eventSource: tracker,
+ position: getMouseRelative( event, tracker.element ),
+ keyCode: event.keyCode ? event.keyCode : event.charCode,
+ shift: event.shiftKey,
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+ if ( !propagate ) {
+ $.cancelEvent( event );
}
}
}
@@ -702,6 +902,7 @@
//console.log( "focus %s", event );
var propagate;
if ( tracker.focusHandler ) {
+ event = $.getEvent( event );
propagate = tracker.focusHandler(
{
eventSource: tracker,
@@ -725,6 +926,7 @@
//console.log( "blur %s", event );
var propagate;
if ( tracker.blurHandler ) {
+ event = $.getEvent( event );
propagate = tracker.blurHandler(
{
eventSource: tracker,
@@ -740,437 +942,6 @@
}
- /**
- * @private
- * @inner
- */
- function onKeyPress( tracker, event ) {
- //console.log( "keypress %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey );
- var propagate;
- if ( tracker.keyHandler ) {
- propagate = tracker.keyHandler(
- {
- eventSource: tracker,
- position: getMouseRelative( event, tracker.element ),
- keyCode: event.keyCode ? event.keyCode : event.charCode,
- shift: event.shiftKey,
- originalEvent: event,
- preventDefaultAction: false,
- userData: tracker.userData
- }
- );
- if ( !propagate ) {
- $.cancelEvent( event );
- }
- }
- }
-
-
- /**
- * @private
- * @inner
- */
- function onMouseOver( tracker, event, isTouch ) {
-
- var delegate = THIS[ tracker.hash ],
- propagate;
-
- isTouch = isTouch || false;
-
- event = $.getEvent( event );
-
- if ( !isTouch ) {
- if ( $.Browser.vendor == $.BROWSERS.IE &&
- $.Browser.version < 9 &&
- delegate.capturing &&
- !isChild( event.srcElement, tracker.element ) ) {
-
- triggerOthers( tracker, onMouseOver, event, isTouch );
- }
-
- var to = event.target ?
- event.target :
- event.srcElement,
- from = event.relatedTarget ?
- event.relatedTarget :
- event.fromElement;
-
- if ( !isChild( tracker.element, to ) ||
- isChild( tracker.element, from ) ) {
- return;
- }
- }
-
- delegate.insideElement = true;
-
- if ( tracker.enterHandler ) {
- propagate = tracker.enterHandler(
- {
- eventSource: tracker,
- position: getMouseRelative( isTouch ? event.changedTouches[ 0 ] : event, tracker.element ),
- insideElementPressed: delegate.insideElementPressed,
- buttonDownAny: IS_BUTTON_DOWN,
- isTouchEvent: isTouch,
- originalEvent: event,
- preventDefaultAction: false,
- userData: tracker.userData
- }
- );
- if ( propagate === false ) {
- $.cancelEvent( event );
- }
- }
- }
-
-
- /**
- * @private
- * @inner
- */
- function onMouseOut( tracker, event, isTouch ) {
- var delegate = THIS[ tracker.hash ],
- propagate;
-
- isTouch = isTouch || false;
-
- event = $.getEvent( event );
-
- if ( !isTouch ) {
- if ( $.Browser.vendor == $.BROWSERS.IE &&
- $.Browser.version < 9 &&
- delegate.capturing &&
- !isChild( event.srcElement, tracker.element ) ) {
-
- triggerOthers( tracker, onMouseOut, event, isTouch );
-
- }
-
- var from = event.target ?
- event.target :
- event.srcElement,
- to = event.relatedTarget ?
- event.relatedTarget :
- event.toElement;
-
- if ( !isChild( tracker.element, from ) ||
- isChild( tracker.element, to ) ) {
- return;
- }
- }
-
- delegate.insideElement = false;
-
- if ( tracker.exitHandler ) {
- propagate = tracker.exitHandler(
- {
- eventSource: tracker,
- position: getMouseRelative( isTouch ? event.changedTouches[ 0 ] : event, tracker.element ),
- insideElementPressed: delegate.insideElementPressed,
- buttonDownAny: IS_BUTTON_DOWN,
- isTouchEvent: isTouch,
- originalEvent: event,
- preventDefaultAction: false,
- userData: tracker.userData
- }
- );
-
- if ( propagate === false ) {
- $.cancelEvent( event );
- }
- }
- }
-
-
- /**
- * @private
- * @inner
- */
- function onMouseDown( tracker, event, noCapture, isTouch ) {
- var delegate = THIS[ tracker.hash ],
- propagate;
-
- isTouch = isTouch || false;
-
- event = $.getEvent(event);
-
- var eventOrTouchPoint = isTouch ? event.touches[ 0 ] : event;
-
- if ( event.button == 2 ) {
- return;
- }
-
- delegate.insideElementPressed = true;
-
- delegate.lastPoint = getMouseAbsolute( eventOrTouchPoint );
- delegate.lastMouseDownPoint = delegate.lastPoint;
- delegate.lastMouseDownTime = $.now();
-
- if ( tracker.pressHandler ) {
- propagate = tracker.pressHandler(
- {
- eventSource: tracker,
- position: getMouseRelative( eventOrTouchPoint, tracker.element ),
- isTouchEvent: isTouch,
- originalEvent: event,
- preventDefaultAction: false,
- userData: tracker.userData
- }
- );
- if ( propagate === false ) {
- $.cancelEvent( event );
- }
- }
-
- if ( tracker.pressHandler || tracker.dragHandler ) {
- $.cancelEvent( event );
- }
-
- if ( noCapture ) {
- return;
- }
-
- if ( isTouch ||
- !( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) ||
- !IS_CAPTURING ) {
- captureMouse( tracker );
- IS_CAPTURING = true;
- // reset to empty & add us
- CAPTURING = [ tracker ];
- } else if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) {
- // add us to the list
- CAPTURING.push( tracker );
- }
- }
-
- /**
- * @private
- * @inner
- */
- function onTouchStart( tracker, event ) {
- var touchA,
- touchB;
-
- if ( event.touches.length == 1 &&
- event.targetTouches.length == 1 &&
- event.changedTouches.length == 1 ) {
-
- THIS[ tracker.hash ].lastTouch = event.touches[ 0 ];
- onMouseOver( tracker, event, true );
- // call with no capture as the onMouseMoveCaptured will
- // be triggered by onTouchMove
- onMouseDown( tracker, event, true, true );
- }
-
- if ( event.touches.length == 2 ) {
-
- touchA = getMouseAbsolute( event.touches[ 0 ] );
- touchB = getMouseAbsolute( event.touches[ 1 ] );
- THIS[ tracker.hash ].lastPinchDelta =
- Math.abs( touchA.x - touchB.x ) +
- Math.abs( touchA.y - touchB.y );
- THIS[ tracker.hash ].pinchMidpoint = new $.Point(
- ( touchA.x + touchB.x ) / 2,
- ( touchA.y + touchB.y ) / 2
- );
- //$.console.debug("pinch start : "+THIS[ tracker.hash ].lastPinchDelta);
- }
-
- event.preventDefault();
- }
-
-
- /**
- * @private
- * @inner
- */
- function onMouseUp( tracker, event, isTouch ) {
- var delegate = THIS[ tracker.hash ],
- //were we inside the tracked element when we were pressed
- insideElementPressed = delegate.insideElementPressed,
- //are we still inside the tracked element when we released
- insideElementReleased = delegate.insideElement,
- propagate;
-
- isTouch = isTouch || false;
-
- event = $.getEvent(event);
-
- if ( event.button == 2 ) {
- return;
- }
-
- delegate.insideElementPressed = false;
-
- if ( tracker.releaseHandler ) {
- propagate = tracker.releaseHandler(
- {
- eventSource: tracker,
- position: getMouseRelative( isTouch ? event.changedTouches[ 0 ] : event, tracker.element ),
- insideElementPressed: insideElementPressed,
- insideElementReleased: insideElementReleased,
- isTouchEvent: isTouch,
- originalEvent: event,
- preventDefaultAction: false,
- userData: tracker.userData
- }
- );
- if ( propagate === false ) {
- $.cancelEvent( event );
- }
- }
-
- if ( insideElementPressed && insideElementReleased ) {
- handleMouseClick( tracker, event, isTouch );
- }
- }
-
-
- /**
- * @private
- * @inner
- */
- function onTouchEnd( tracker, event ) {
-
- if ( event.touches.length === 0 &&
- event.targetTouches.length === 0 &&
- event.changedTouches.length == 1 ) {
-
- THIS[ tracker.hash ].lastTouch = null;
-
- // call with no release, as the mouse events are
- // not registered in onTouchStart
- onMouseUpCaptured( tracker, event, true, true );
- onMouseOut( tracker, event, true );
- }
- if ( event.touches.length + event.changedTouches.length == 2 ) {
- THIS[ tracker.hash ].lastPinchDelta = null;
- THIS[ tracker.hash ].pinchMidpoint = null;
- //$.console.debug("pinch end");
- }
- event.preventDefault();
- }
-
-
- /**
- * Only triggered once by the deepest element that initially received
- * the mouse down event. We want to make sure THIS event doesn't bubble.
- * Instead, we want to trigger the elements that initially received the
- * mouse down event (including this one) only if the mouse is no longer
- * inside them. Then, we want to release capture, and emulate a regular
- * mouseup on the event that this event was meant for.
- * @private
- * @inner
- */
- function onMouseUpIE( tracker, event ) {
- var othertracker,
- i;
-
- event = $.getEvent( event );
-
- if ( event.button == 2 ) {
- return;
- }
-
- for ( i = 0; i < CAPTURING.length; i++ ) {
- othertracker = CAPTURING[ i ];
- if ( !hasMouse( othertracker ) ) {
- onMouseUp( othertracker, event, false );
- }
- }
-
- releaseMouse( tracker );
- IS_CAPTURING = false;
- event.srcElement.fireEvent(
- "on" + event.type,
- document.createEventObject( event )
- );
-
- $.stopEvent( event );
- }
-
-
- /**
- * Only triggered in W3C browsers by elements within which the mouse was
- * initially pressed, since they are now listening to the window for
- * mouseup during the capture phase. We shouldn't handle the mouseup
- * here if the mouse is still inside this element, since the regular
- * mouseup handler will still fire.
- * @private
- * @inner
- */
- function onMouseUpCaptured( tracker, event, noRelease, isTouch ) {
- isTouch = isTouch || false;
-
- if ( !THIS[ tracker.hash ].insideElement || isTouch ) {
- onMouseUp( tracker, event, isTouch );
- }
-
- if ( noRelease ) {
- return;
- }
-
- releaseMouse( tracker );
- }
-
-
- /**
- * @private
- * @inner
- */
- function onMouseMove( tracker, event ) {
- if ( tracker.moveHandler ) {
- event = $.getEvent( event );
-
- var propagate = tracker.moveHandler(
- {
- eventSource: tracker,
- position: getMouseRelative( event, tracker.element ),
- isTouchEvent: false,
- originalEvent: event,
- preventDefaultAction: false,
- userData: tracker.userData
- }
- );
- if ( propagate === false ) {
- $.cancelEvent( event );
- }
- }
- if ( tracker.stopHandler ) {
- clearTimeout( tracker.stopTimeOut );
- tracker.stopTimeOut = setTimeout( function() {
- onMouseStop( tracker, event );
- }, tracker.stopDelay );
- }
- }
-
- /**
- * @private
- * @inner
- */
- function onMouseStop( tracker, originalMoveEvent ) {
- if ( tracker.stopHandler ) {
- tracker.stopHandler( {
- eventSource: tracker,
- position: getMouseRelative( originalMoveEvent, tracker.element ),
- isTouchEvent: false,
- originalEvent: originalMoveEvent,
- preventDefaultAction: false,
- userData: tracker.userData
- } );
- }
- }
-
- /**
- * @private
- * @inner
- */
- function onMouseClick( tracker, event ) {
- if ( tracker.clickHandler ) {
- $.cancelEvent( event );
- }
- }
-
-
/**
* Handler for 'wheel' events
*
@@ -1178,7 +949,7 @@
* @inner
*/
function onWheel( tracker, event ) {
- handleWheelEvent( tracker, event, event, false );
+ handleWheelEvent( tracker, event, event );
}
@@ -1189,8 +960,7 @@
* @inner
*/
function onMouseWheel( tracker, event ) {
- // For legacy IE, access the global (window) event object
- event = event || window.event;
+ event = $.getEvent( event );
// Simulate a 'wheel' event
var simulatedEvent = {
@@ -1213,23 +983,743 @@
simulatedEvent.deltaY = event.detail;
}
- handleWheelEvent( tracker, simulatedEvent, event, false );
+ handleWheelEvent( tracker, simulatedEvent, event );
}
+ /**
+ * @private
+ * @inner
+ */
+ function onPointerOver( tracker, event ) {
+ var time,
+ point,
+ pointer;
+
+ time = $.now();
+ point = getMouseAbsolute( event );
+
+ pointer = {
+ id: event.pointerId,
+ type: getPointerType( event ),
+ //isCaptured: false,
+ //insideElementPressed: true,
+ insideElement: true,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: point,
+ currentTime: time
+ };
+
+ updatePointersOver( tracker, event, [pointer] );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onMouseOver( tracker, event ) {
+ var time,
+ point,
+ pointer;
+
+ event = $.getEvent(event);
+
+ time = $.now();
+ point = getMouseAbsolute( event );
+
+ pointer = {
+ id: $.MouseTracker.mousePointerId,
+ type: 'mouse',
+ //isCaptured: true,
+ //insideElementPressed: true,
+ insideElement: true,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: point,
+ currentTime: time
+ };
+
+ updatePointersOver( tracker, event, [pointer] );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onPointerOut( tracker, event ) {
+ var time,
+ point,
+ pointer;
+
+ time = $.now();
+ point = getMouseAbsolute( event );
+
+ pointer = {
+ id: event.pointerId,
+ type: getPointerType( event ),
+ //isCaptured: false,
+ //insideElementPressed: true,
+ insideElement: false,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: point,
+ currentTime: time
+ };
+
+ updatePointersOut( tracker, event, [pointer] );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onMouseOut( tracker, event ) {
+ var time,
+ point,
+ pointer;
+
+ event = $.getEvent(event);
+
+ var eventOrTouchPoint = event;//isTouch ? event.touches[ 0 ] : event;
+
+ time = $.now();
+ point = getMouseAbsolute( event );
+
+ pointer = {
+ id: $.MouseTracker.mousePointerId,
+ type: 'mouse',
+ //isCaptured: true,
+ //insideElementPressed: true,
+ insideElement: false,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: point,
+ currentTime: time
+ };
+
+ updatePointersOut( tracker, event, [pointer] );
+ }
+
+
+//$.MouseTracker.mousePointerId = "legacy-mouse";
+//$.MouseTracker.unprefixedPointerEvents = false;
+//$.MouseTracker.maxTouchPoints = 10;
+// function addPointers( tracker, event, pointers ) {
+// }
+// function updatePointersOver( tracker, event, pointers ) {
+// }
+// function updatePointersOut( tracker, event, pointers ) {
+// }
+// function updatePointers( tracker, event, pointers ) {
+// }
+// function removePointers( tracker, event, pointers ) {
+// }
+// function cancelPointers( tracker, event, pointers ) {
+// }
+//pointer = {
+// id: x, // getPointerType( event )
+// type: '', // 'mouse', 'touch', 'pen', ''
+// isCaptured: false,
+// insideElementPressed: true,
+// insideElement: true,
+// startPos: null, // $.Point getMouseAbsolute( eventOrTouchPoint ); getPointRelative( point, tracker.element )
+// startTime: 0xFFFFFFFF,
+// lastPos: null, // $.Point getMouseAbsolute( eventOrTouchPoint ); getPointRelative( point, tracker.element )
+// lastTime: 0xFFFFFFFF,
+// currentPos: null, // $.Point getMouseAbsolute( eventOrTouchPoint ); getPointRelative( point, tracker.element )
+// currentTime: 0xFFFFFFFF,
+//}
+//var delegate = THIS[ tracker.hash ]
+//delegate.mousePoints: {},
+//delegate.mousePointCount: 0,
+//delegate.touchPoints: {},
+//delegate.touchPointCount: 0,
+//delegate.penPoints: {},
+//delegate.penPointCount: 0
+//
+//var touchPoints = {};
+//touchPoints[event.pointerId] = "test";
+//touchPoints[12345] = "test12345";
+//delete touchPoints[event.pointerId];
+ /**
+ * @private
+ * @inner
+ */
+ function onPointerDown( tracker, event ) {
+ var delegate = THIS[ tracker.hash ],
+ time,
+ point,
+ pointer;
+
+ if ( event.button == 2 ) {
+ return;
+ }
+
+ if ( $.MouseTracker.unprefixedPointerEvents ) {
+ event.target.setPointerCapture(event.pointerId);
+ }
+ else {
+ event.target.msSetPointerCapture(event.pointerId);
+ }
+
+ time = $.now();
+ point = getMouseAbsolute( event );
+
+ pointer = {
+ id: event.pointerId,
+ type: getPointerType( event ),
+ isCaptured: true,
+ insideElementPressed: true,
+ insideElement: true,
+ startPos: point,
+ startTime: time,
+ lastPos: point,
+ lastTime: time,
+ currentPos: point,
+ currentTime: time
+ };
+
+ addPointers( tracker, event, [pointer] );
+
+ if ( tracker.pressHandler || tracker.dragHandler || tracker.pinchHandler || tracker.swipeHandler ) {
+ $.cancelEvent( event );
+ }
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onMouseDown( tracker, event ) {
+ var delegate = THIS[ tracker.hash ],
+ time,
+ point,
+ pointer;
+
+ event = $.getEvent(event);
+
+ if ( event.button == 2 ) {
+ return;
+ }
+
+ time = $.now();
+ point = getMouseAbsolute( event );
+
+ pointer = {
+ id: $.MouseTracker.mousePointerId,
+ type: 'mouse',
+ isCaptured: true,
+ insideElementPressed: true,
+ insideElement: true,
+ startPos: point,
+ startTime: time,
+ lastPos: point,
+ lastTime: time,
+ currentPos: point,
+ currentTime: time
+ };
+
+ addPointers( tracker, event, [pointer] );
+
+ if ( tracker.pressHandler || tracker.dragHandler || tracker.pinchHandler || tracker.swipeHandler ) {
+ $.cancelEvent( event );
+ }
+
+ if ( !( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) ||
+ !IS_CAPTURING ) {
+ captureMouse( tracker );
+ IS_CAPTURING = true;
+ // reset to empty & add us
+ CAPTURING = [ tracker ];
+ } else if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) {
+ // add us to the list
+ CAPTURING.push( tracker );
+ }
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onPointerUp( tracker, event ) {
+ var delegate = THIS[ tracker.hash ],
+ time,
+ point,
+ pointer;
+
+ if ( event.button == 2 ) {
+ return;
+ }
+
+ if ( $.MouseTracker.unprefixedPointerEvents ) {
+ event.target.releasePointerCapture(event.pointerId);
+ }
+ else {
+ event.target.msReleasePointerCapture(event.pointerId);
+ }
+
+ time = $.now();
+ point = getMouseAbsolute( event );
+
+ pointer = {
+ id: event.pointerId,
+ type: getPointerType( event ),
+ isCaptured: false,
+ //insideElementPressed: true,
+ //insideElement: true,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: point,
+ currentTime: time
+ };
+
+ removePointers( tracker, event, [pointer] );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onMouseUp( tracker, event ) {
+ handleMouseUp( tracker, event );
+ }
+
+
+ /**
+ * Only triggered in W3C browsers by elements within which the mouse was
+ * initially pressed, since they are now listening to the window for
+ * mouseup during the capture phase. We shouldn't handle the mouseup
+ * here if the mouse is still inside this element, since the regular
+ * mouseup handler will still fire.
+ * @private
+ * @inner
+ */
+ function onMouseUpCaptured( tracker, event ) {
+ var delegate = THIS[ tracker.hash ],
+ pointer = delegate.mousePoints[ $.MouseTracker.mousePointerId ] || null;
+
+ if ( !pointer.insideElement ) {
+ handleMouseUp( tracker, event );
+ }
+
+ releaseMouse( tracker );
+ }
+
+
+ /**
+ * Only triggered once by the deepest element that initially received
+ * the mouse down event. We want to make sure THIS event doesn't bubble.
+ * Instead, we want to trigger the elements that initially received the
+ * mouse down event (including this one) only if the mouse is no longer
+ * inside them. Then, we want to release capture, and emulate a regular
+ * mouseup on the event that this event was meant for.
+ * @private
+ * @inner
+ */
+ function onMouseUpCapturedIE( tracker, event ) {
+ var othertracker,
+ i;
+
+ event = $.getEvent( event );
+
+ if ( event.button == 2 ) {
+ return;
+ }
+
+ for ( i = 0; i < CAPTURING.length; i++ ) {
+ othertracker = CAPTURING[ i ];
+ if ( !hasMouse( othertracker ) ) {
+ handleMouseUp( othertracker, event );
+ }
+ }
+
+ releaseMouse( tracker );
+ IS_CAPTURING = false;
+ event.srcElement.fireEvent(
+ "on" + event.type,
+ document.createEventObject( event )
+ );
+
+ $.stopEvent( event );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onPointerMove( tracker, event ) {
+ // Pointer changed coordinates, button state, pressure, tilt, or contact geometry (e.g. width and height)
+ var time,
+ point,
+ pointer;
+
+ time = $.now();
+ point = getMouseAbsolute( event );
+
+ pointer = {
+ id: event.pointerId,
+ type: getPointerType( event ),
+ //isCaptured: false,
+ //insideElementPressed: true,
+ //insideElement: true,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: point,
+ currentTime: time
+ };
+
+ updatePointers( tracker, event, [pointer] );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onMouseMove( tracker, event ) {
+ handleMouseMove( tracker, event );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onMouseMoveCaptured( tracker, event ) {
+ handleMouseMove( tracker, event );
+ }
+
+
+ /**
+ * Only triggered once by the deepest element that initially received
+ * the mouse down event. Since no other element has captured the mouse,
+ * we want to trigger the elements that initially received the mouse
+ * down event (including this one). The the param tracker isn't used
+ * but for consistency with the other event handlers we include it.
+ * @private
+ * @inner
+ */
+ function onMouseMoveCapturedIE( tracker, event ) {
+ var i;
+ for ( i = 0; i < CAPTURING.length; i++ ) {
+ handleMouseMove( CAPTURING[ i ], event );
+ }
+
+ $.stopEvent( event );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onPointerCancel( tracker, event ) {
+ var //time,
+ //point,
+ pointer;
+
+ //time = $.now();
+ //point = getMouseAbsolute( event );
+
+ pointer = {
+ id: event.pointerId,
+ type: getPointerType( event ),
+ //isCaptured: false,
+ //insideElementPressed: true,
+ //insideElement: true,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ //currentPos: point,
+ //currentTime: time
+ };
+
+ cancelPointers( tracker, event, [pointer] );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onTouchStart( tracker, event ) {
+ var delegate = THIS[ tracker.hash ],
+ time,
+ point,
+ pointer,
+ i,
+ touchCount = event.changedTouches.length,
+ pointers = [];
+
+ time = $.now();
+
+ if ( touchCount > 0 && delegate.touchPointCount === 0 ) {
+ pointer = {
+ id: event.changedTouches[ 0 ].identifier,
+ type: 'touch',
+ //isCaptured: false,
+ //insideElementPressed: true,
+ insideElement: true,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: getMouseAbsolute( event.changedTouches[ 0 ] ),
+ currentTime: time
+ };
+ updatePointersOver( tracker, event, [pointer] );
+ }
+
+ for ( i = 0; i < touchCount; i++ ) {
+ point = getMouseAbsolute( event.changedTouches[ i ] );
+
+ pointers.push( {
+ id: event.changedTouches[ i ].identifier,
+ type: 'touch',
+ isCaptured: false,
+ insideElementPressed: true,
+ insideElement: true,
+ startPos: point,
+ startTime: time,
+ lastPos: point,
+ lastTime: time,
+ currentPos: point,
+ currentTime: time
+ } );
+ }
+
+ addPointers( tracker, event, pointers );
+
+ event.preventDefault();
+////****************************************************************
+// var touchA,
+// touchB;
+
+// if ( event.touches.length == 1 &&
+// event.targetTouches.length == 1 &&
+// event.changedTouches.length == 1 ) {
+
+// THIS[ tracker.hash ].lastTouch = event.touches[ 0 ];
+// handlePointerOver( tracker, event, getMouseRelative( event.changedTouches[ 0 ], tracker.element ) );
+// // call with no capture as the onMouseMoveCaptured will
+// // be triggered by onTouchMove
+// onMouseDown( tracker, event, true, true );
+// }
+
+// if ( event.touches.length == 2 ) {
+
+// touchA = getMouseAbsolute( event.touches[ 0 ] );
+// touchB = getMouseAbsolute( event.touches[ 1 ] );
+// THIS[ tracker.hash ].lastPinchDelta =
+// Math.abs( touchA.x - touchB.x ) +
+// Math.abs( touchA.y - touchB.y );
+// THIS[ tracker.hash ].pinchMidpoint = new $.Point(
+// ( touchA.x + touchB.x ) / 2,
+// ( touchA.y + touchB.y ) / 2
+// );
+// //$.console.debug("pinch start : "+THIS[ tracker.hash ].lastPinchDelta);
+// }
+
+// event.preventDefault();
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onTouchEnd( tracker, event ) {
+ var delegate = THIS[ tracker.hash ],
+ time,
+ point,
+ pointer,
+ i,
+ touchCount = event.changedTouches.length,
+ pointers = [];
+
+ time = $.now();
+
+ for ( i = 0; i < touchCount; i++ ) {
+ point = getMouseAbsolute( event.changedTouches[ i ] );
+
+ pointers.push( {
+ id: event.changedTouches[ i ].identifier,
+ type: 'touch',
+ isCaptured: false,
+ //insideElementPressed: true,
+ //insideElement: true,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: point,
+ currentTime: time
+ } );
+ }
+
+ removePointers( tracker, event, pointers );
+
+ if ( touchCount > 0 && delegate.touchPointCount === 0 ) {
+ pointer = {
+ id: event.changedTouches[ 0 ].identifier,
+ type: 'touch',
+ //isCaptured: false,
+ //insideElementPressed: true,
+ insideElement: false,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: getMouseAbsolute( event.changedTouches[ 0 ] ),
+ currentTime: time
+ };
+ updatePointersOut( tracker, event, [pointer] );
+ }
+
+ event.preventDefault();
+//****************************************************************************************
+// if ( event.touches.length === 0 &&
+// event.targetTouches.length === 0 &&
+// event.changedTouches.length == 1 ) {
+
+// THIS[ tracker.hash ].lastTouch = null;
+
+// // call with no release, as the mouse events are
+// // not registered in onTouchStart
+// onMouseUpCaptured( tracker, event, true, true );
+// handlePointerOut( tracker, event, getMouseRelative( event.changedTouches[ 0 ], tracker.element ) );
+// }
+// if ( event.touches.length + event.changedTouches.length == 2 ) {
+// THIS[ tracker.hash ].lastPinchDelta = null;
+// THIS[ tracker.hash ].pinchMidpoint = null;
+// //$.console.debug("pinch end");
+// }
+// event.preventDefault();
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function onTouchMove( tracker, event ) {
+ var time,
+ point,
+ i,
+ touchCount = event.changedTouches.length,
+ pointers = [];
+
+ time = $.now();
+
+ for ( i = 0; i < touchCount; i++ ) {
+ point = getMouseAbsolute( event.changedTouches[ i ] );
+
+ pointers.push( {
+ id: event.changedTouches[ i ].identifier,
+ type: 'touch',
+ //isCaptured: false,
+ //insideElementPressed: true,
+ //insideElement: true,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: point,
+ currentTime: time
+ } );
+ }
+
+ updatePointers( tracker, event, pointers );
+
+ event.preventDefault();
+//*******************************************************************************
+// var touchA,
+// touchB,
+// pinchDelta;
+
+// if ( !THIS[ tracker.hash ].lastTouch ) {
+// return;
+// }
+
+// if ( event.touches.length === 1 &&
+// event.targetTouches.length === 1 &&
+// event.changedTouches.length === 1 &&
+// THIS[ tracker.hash ].lastTouch.identifier === event.touches[ 0 ].identifier ) {
+
+// onMouseMoveCaptured( tracker, event, true );
+
+// } else if ( event.touches.length === 2 ) {
+
+// touchA = getMouseAbsolute( event.touches[ 0 ] );
+// touchB = getMouseAbsolute( event.touches[ 1 ] );
+// pinchDelta =
+// Math.abs( touchA.x - touchB.x ) +
+// Math.abs( touchA.y - touchB.y );
+
+// ////TODO: make the 75px pinch threshold configurable
+// //if ( Math.abs( THIS[ tracker.hash ].lastPinchDelta - pinchDelta ) > 75 ) {
+// // //$.console.debug( "pinch delta : " + pinchDelta + " | previous : " + THIS[ tracker.hash ].lastPinchDelta);
+
+// // // Simulate a 'wheel' event
+// // var simulatedEvent = {
+// // target: event.target || event.srcElement,
+// // type: "wheel",
+// // shiftKey: event.shiftKey || false,
+// // clientX: THIS[ tracker.hash ].pinchMidpoint.x,
+// // clientY: THIS[ tracker.hash ].pinchMidpoint.y,
+// // pageX: THIS[ tracker.hash ].pinchMidpoint.x,
+// // pageY: THIS[ tracker.hash ].pinchMidpoint.y,
+// // deltaMode: 1, // 0=pixel, 1=line, 2=page
+// // deltaX: 0,
+// // deltaY: ( THIS[ tracker.hash ].lastPinchDelta > pinchDelta ) ? 1 : -1,
+// // deltaZ: 0
+// // };
+
+// // handleWheelEvent( tracker, simulatedEvent, event, true );
+
+// // THIS[ tracker.hash ].lastPinchDelta = pinchDelta;
+// //}
+// }
+// event.preventDefault();
+ }
+
+
+//*******************************************************************************************************************************************
+//** Event Processing Functions
+
+
/**
* Handles 'wheel' events.
- * The event may be simulated by the legacy mouse wheel event handler (onMouseWheel()) or onTouchMove().
+ * The event may be simulated by the legacy mouse wheel event handler (onMouseWheel()).
*
* @private
* @inner
*/
- function handleWheelEvent( tracker, event, originalEvent, isTouch ) {
+ function handleWheelEvent( tracker, event, originalEvent ) {
var nDelta = 0,
propagate;
- isTouch = isTouch || false;
-
// 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.
@@ -1244,7 +1734,7 @@
position: getMouseRelative( event, tracker.element ),
scroll: nDelta,
shift: event.shiftKey,
- isTouchEvent: isTouch,
+ isTouchEvent: false,
originalEvent: originalEvent,
preventDefaultAction: false,
userData: tracker.userData
@@ -1261,41 +1751,190 @@
* @private
* @inner
*/
- function handleMouseClick( tracker, event, isTouch ) {
- var delegate = THIS[ tracker.hash ],
- propagate;
+ function handleMouseMove( tracker, event ) {
+ var time,
+ point,
+ pointer;
- isTouch = isTouch || false;
+ event = $.getEvent(event);
- event = $.getEvent( event );
+ time = $.now();
+ point = getMouseAbsolute( event );
- var eventOrTouchPoint = isTouch ? event.changedTouches[ 0 ] : event;
+ pointer = {
+ id: $.MouseTracker.mousePointerId,
+ type: 'mouse',
+ //isCaptured: false,
+ //insideElementPressed: true,
+ //insideElement: true,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: point,
+ currentTime: time
+ };
+
+ updatePointers( tracker, event, [pointer] );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function handleMouseUp( tracker, event ) {
+ var time,
+ point,
+ pointer;
+
+ event = $.getEvent(event);
if ( event.button == 2 ) {
return;
}
- var time = $.now() - delegate.lastMouseDownTime,
- point = getMouseAbsolute( eventOrTouchPoint ),
- distance = delegate.lastMouseDownPoint.distanceTo( point ),
- quick = time <= tracker.clickTimeThreshold &&
- distance <= tracker.clickDistThreshold;
+ time = $.now();
+ point = getMouseAbsolute( event );
- if ( tracker.clickHandler ) {
- propagate = tracker.clickHandler(
- {
- eventSource: tracker,
- position: getMouseRelative( eventOrTouchPoint, tracker.element ),
- quick: quick,
- shift: event.shiftKey,
- isTouchEvent: isTouch,
- originalEvent: event,
- preventDefaultAction: false,
- userData: tracker.userData
+ pointer = {
+ id: $.MouseTracker.mousePointerId,
+ type: 'mouse',
+ isCaptured: false,
+ //insideElementPressed: true,
+ //insideElement: true,
+ //startPos: point,
+ //startTime: time,
+ //lastPos: point,
+ //lastTime: time,
+ currentPos: point,
+ currentTime: time
+ };
+
+ removePointers( tracker, event, [pointer] );
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function handlePointerStop( tracker, originalMoveEvent ) {
+ if ( tracker.stopHandler ) {
+ tracker.stopHandler( {
+ eventSource: tracker,
+ position: getMouseRelative( originalMoveEvent, tracker.element ),
+ isTouchEvent: false,
+ originalEvent: originalMoveEvent,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ } );
+ }
+ }
+
+
+//$.MouseTracker.mousePointerId = "legacy-mouse";
+//$.MouseTracker.unprefixedPointerEvents = false;
+//$.MouseTracker.maxTouchPoints = 10;
+// function addPointers( tracker, event, pointers ) {
+// }
+// function updatePointersOver( tracker, event, pointers ) {
+// }
+// function updatePointersOut( tracker, event, pointers ) {
+// }
+// function updatePointers( tracker, event, pointers ) {
+// }
+// function removePointers( tracker, event, pointers ) {
+// }
+// function cancelPointers( tracker, event, pointers ) {
+// }
+//pointer = {
+// id: x, // getPointerType( event )
+// type: '', // 'mouse', 'touch', 'pen', ''
+// isCaptured: false,
+// insideElementPressed: true,
+// insideElement: true,
+// startPos: null, // $.Point getMouseAbsolute( eventOrTouchPoint ); getPointRelative( point, tracker.element )
+// startTime: 0xFFFFFFFF,
+// lastPos: null, // $.Point getMouseAbsolute( eventOrTouchPoint ); getPointRelative( point, tracker.element )
+// lastTime: 0xFFFFFFFF,
+// currentPos: null, // $.Point getMouseAbsolute( eventOrTouchPoint ); getPointRelative( point, tracker.element )
+// currentTime: 0xFFFFFFFF,
+//}
+//var delegate = THIS[ tracker.hash ]
+//delegate.mousePoints: {},
+//delegate.mousePointCount: 0,
+//delegate.touchPoints: {},
+//delegate.touchPointCount: 0,
+//delegate.penPoints: {},
+//delegate.penPointCount: 0
+//
+//var touchPoints = {};
+//touchPoints[event.pointerId] = "test";
+//touchPoints[12345] = "test12345";
+//delete touchPoints[event.pointerId];
+
+ /**
+ * @private
+ * @inner
+ */
+ function addPointers( tracker, event, pointers ) {
+ var delegate = THIS[ tracker.hash ],
+ propagate,
+ dispatchPress = false,
+ i,
+ pointerCount = pointers.length,
+ curPointer,
+ gesturePoints;
+
+ for ( i = 0; i < pointerCount; i++ ) {
+ curPointer = pointers[ i ];
+ if ( curPointer.type === 'mouse' ) {
+ if ( !delegate.mousePointCount ) {
+ delegate.mousePoints[ curPointer.id ] = curPointer;
+ delegate.mousePointCount++;
+ dispatchPress = true;
+ }
+ }
+ else if ( curPointer.type === 'touch' ) {
+ if ( !delegate.touchPointCount ) {
+ dispatchPress = true;
+ }
+ if ( !delegate.touchPoints[ curPointer.id ] ) {
+ delegate.touchPoints[ curPointer.id ] = curPointer;
+ delegate.touchPointCount++;
+ if ( delegate.touchPointCount == 2 && tracker.pinchHandler ) {
+ // Initialize for pinch gesture tracking
+ gesturePoints = [];
+ for ( var p in delegate.touchPoints ) {
+ gesturePoints.push( delegate.touchPoints[ p ] );
+ }
+ delegate.lastPinchDist = delegate.currentPinchDist = gesturePoints[0].currentPos.distanceTo(gesturePoints[1].currentPos);
+ }
+ }
+ }
+ else if ( curPointer.type === 'pen' ) {
+ if ( !delegate.penPointCount ) {
+ delegate.penPoints[ curPointer.id ] = curPointer;
+ delegate.penPointCount++;
+ dispatchPress = true;
+ }
+ }
+
+ if ( dispatchPress && tracker.pressHandler ) {
+ propagate = tracker.pressHandler(
+ {
+ eventSource: tracker,
+ position: getPointRelative( curPointer.startPos, tracker.element ),
+ isTouchEvent: curPointer.type === 'touch',
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+ if ( propagate === false ) {
+ $.cancelEvent( event );
}
- );
- if ( propagate === false ) {
- $.cancelEvent( event );
}
}
}
@@ -1305,36 +1944,239 @@
* @private
* @inner
*/
- function onMouseMoveCaptured( tracker, event, isTouch ) {
+ function updatePointersOver( tracker, event, pointers ) {
var delegate = THIS[ tracker.hash ],
+ i,
+ pointerCount = pointers.length,
+ curPointer,
+ updatePointer,
+ insideElementPressed,
+ propagate;
+
+ for ( i = 0; i < pointerCount; i++ ) {
+ curPointer = pointers[ i ];
+ if ( curPointer.type === 'mouse' ) {
+ updatePointer = delegate.mousePoints[ curPointer.id ] || null;
+ }
+ else if ( curPointer.type === 'touch' ) {
+ updatePointer = delegate.touchPoints[ curPointer.id ] || null;
+ }
+ else if ( curPointer.type === 'pen' ) {
+ updatePointer = delegate.penPoints[ curPointer.id ] || null;
+ }
+ else {
+ updatePointer = null;
+ }
+
+ if ( updatePointer ) {
+ updatePointer.insideElement = true;
+ updatePointer.lastPos = updatePointer.currentPos;
+ updatePointer.lastTime = updatePointer.currentTime;
+ updatePointer.currentPos = curPointer.currentPos;
+ updatePointer.currentTime = curPointer.currentTime;
+ insideElementPressed = updatePointer.insideElementPressed;
+ }
+ else {
+ insideElementPressed = false;
+ }
+
+ if ( tracker.enterHandler ) {
+ propagate = tracker.enterHandler(
+ {
+ eventSource: tracker,
+ position: getPointRelative( curPointer.currentPos, tracker.element ),
+ insideElementPressed: insideElementPressed,
+ buttonDownAny: IS_BUTTON_DOWN,
+ isTouchEvent: curPointer.type === 'touch',
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+ if ( propagate === false ) {
+ $.cancelEvent( event );
+ }
+ }
+ }
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function updatePointersOut( tracker, event, pointers ) {
+ var delegate = THIS[ tracker.hash ],
+ i,
+ pointerCount = pointers.length,
+ curPointer,
+ updatePointer,
+ insideElementPressed,
+ propagate;
+
+ for ( i = 0; i < pointerCount; i++ ) {
+ curPointer = pointers[ i ];
+ if ( curPointer.type === 'mouse' ) {
+ updatePointer = delegate.mousePoints[ curPointer.id ] || null;
+ }
+ else if ( curPointer.type === 'touch' ) {
+ updatePointer = delegate.touchPoints[ curPointer.id ] || null;
+ }
+ else if ( curPointer.type === 'pen' ) {
+ updatePointer = delegate.penPoints[ curPointer.id ] || null;
+ }
+ else {
+ updatePointer = null;
+ }
+
+ if ( updatePointer ) {
+ updatePointer.insideElement = false;
+ updatePointer.lastPos = updatePointer.currentPos;
+ updatePointer.lastTime = updatePointer.currentTime;
+ updatePointer.currentPos = curPointer.currentPos;
+ updatePointer.currentTime = curPointer.currentTime;
+ insideElementPressed = updatePointer.insideElementPressed;
+ }
+ else {
+ insideElementPressed = false;
+ }
+
+ if ( tracker.exitHandler ) {
+ propagate = tracker.exitHandler(
+ {
+ eventSource: tracker,
+ position: getPointRelative( curPointer.currentPos, tracker.element ),
+ insideElementPressed: insideElementPressed,
+ buttonDownAny: IS_BUTTON_DOWN,
+ isTouchEvent: curPointer.type === 'touch',
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+
+ if ( propagate === false ) {
+ $.cancelEvent( event );
+ }
+ }
+ }
+ }
+
+
+ /**
+ * @private
+ * @inner
+ */
+ function updatePointers( tracker, event, pointers ) {
+ // Pointer(s) changed coordinates, button state, pressure, tilt, or contact geometry (e.g. width and height)
+ var delegate = THIS[ tracker.hash ],
+ i,
+ pointerCount = pointers.length,
+ curPointer,
+ updatePointer,
+ points,
+ pointCount,
delta,
propagate,
- point;
+ gesturePoints;
- isTouch = isTouch || false;
+ if ( pointers[ 0 ].type === 'mouse' ) {
+ points = delegate.mousePoints;
+ pointCount = delegate.mousePointCount;
+ }
+ else if ( pointers[ 0 ].type === 'touch' ) {
+ points = delegate.touchPoints;
+ pointCount = delegate.touchPointCount;
+ }
+ else if ( pointers[ 0 ].type === 'pen' ) {
+ points = delegate.penPoints;
+ pointCount = delegate.penPointCount;
+ }
+ else {
+ points = null;
+ }
- event = $.getEvent(event);
- var eventOrTouchPoint = isTouch ? event.touches[ 0 ] : event;
- point = getMouseAbsolute( eventOrTouchPoint );
- delta = point.minus( delegate.lastPoint );
+ for ( i = 0; i < pointerCount; i++ ) {
+ curPointer = pointers[ i ];
+ updatePointer = points ? ( points[ curPointer.id ] || null ) : null;
- delegate.lastPoint = point;
+ if ( updatePointer ) {
+ updatePointer.lastPos = updatePointer.currentPos;
+ updatePointer.lastTime = updatePointer.currentTime;
+ updatePointer.currentPos = curPointer.currentPos;
+ updatePointer.currentTime = curPointer.currentTime;
- if ( tracker.dragHandler ) {
- propagate = tracker.dragHandler(
- {
- eventSource: tracker,
- position: getMouseRelative( eventOrTouchPoint, tracker.element ),
- delta: delta,
- shift: event.shiftKey,
- isTouchEvent: isTouch,
- originalEvent: event,
- preventDefaultAction: false,
- userData: tracker.userData
+ // Drag Gesture
+ if ( pointCount == 1 && tracker.dragHandler && !updatePointer.currentPos.equals( updatePointer.lastPos ) ) {
+ delta = updatePointer.currentPos.minus( updatePointer.lastPos );
+ propagate = tracker.dragHandler(
+ {
+ eventSource: tracker,
+ position: getPointRelative( updatePointer.currentPos, tracker.element ),
+ delta: delta,
+ shift: event.shiftKey,
+ isTouchEvent: curPointer.type === 'touch',
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+ if ( propagate === false ) {
+ $.cancelEvent( event );
+ }
+ }
+ }
+
+ if ( pointCount == 1 && tracker.moveHandler ) {
+ propagate = tracker.moveHandler(
+ {
+ eventSource: tracker,
+ position: getPointRelative( curPointer.currentPos, tracker.element ),
+ isTouchEvent: curPointer.type === 'touch',
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+ if ( propagate === false ) {
+ $.cancelEvent( event );
+ }
+ }
+ //if ( tracker.stopHandler ) {
+ // clearTimeout( tracker.stopTimeOut );
+ // tracker.stopTimeOut = setTimeout( function() {
+ // handlePointerStop( tracker, event );
+ // }, tracker.stopDelay );
+ //}
+ }
+
+ // Pinch Gesture
+ if ( pointers[ 0 ].type === 'touch' && delegate.touchPointCount == 2 && tracker.pinchHandler ) {
+ gesturePoints = [];
+ for ( var p in delegate.touchPoints ) {
+ gesturePoints.push( delegate.touchPoints[ p ] );
+ }
+ delta = gesturePoints[0].currentPos.distanceTo( gesturePoints[1].currentPos );
+ //if ( delta != delegate.currentPinchDist ) {
+ if (delta != delegate.currentPinchDist && Math.abs(delta - delegate.lastPinchDist) > 75) {
+ delegate.lastPinchDist = delegate.currentPinchDist;
+ delegate.currentPinchDist = delta;
+
+ propagate = tracker.pinchHandler(
+ {
+ eventSource: tracker,
+ position: getPointRelative( updatePointer.currentPos, tracker.element ),
+ delta: delegate.currentPinchDist - delegate.lastPinchDist,
+ shift: event.shiftKey,
+ isTouchEvent: curPointer.type === 'touch',
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+ if ( propagate === false ) {
+ $.cancelEvent( event );
}
- );
- if ( propagate === false ) {
- $.cancelEvent( event );
}
}
}
@@ -1344,93 +2186,333 @@
* @private
* @inner
*/
- function onTouchMove( tracker, event ) {
- var touchA,
- touchB,
- pinchDelta;
+ function removePointers( tracker, event, pointers ) {
+ var delegate = THIS[ tracker.hash ],
+ propagate,
+ //were we inside the tracked element when we were pressed
+ insideElementPressed,
+ //are we still inside the tracked element when we released
+ insideElementReleased,
+ dispatchRelease,
+ pressPoint,
+ pressTime,
+ releasePoint,
+ i,
+ pointerCount = pointers.length,
+ curPointer,
+ updatePointer;
- if ( !THIS[ tracker.hash ].lastTouch ) {
- return;
- }
+ for ( i = 0; i < pointerCount; i++ ) {
+ curPointer = pointers[ i ];
+ dispatchRelease = false;
+ if ( curPointer.type === 'mouse' ) {
+ updatePointer = delegate.mousePoints[ curPointer.id ] || null;
+ if ( updatePointer ) {
+ pressPoint = updatePointer.startPos;
+ pressTime = updatePointer.startTime;
+ delete delegate.mousePoints[ curPointer.id ];
+ delegate.mousePointCount--;
+ if ( !delegate.mousePointCount ) {
+ dispatchRelease = true;
+ releasePoint = curPointer.currentPos;
+ }
+ }
+ }
+ else if ( curPointer.type === 'touch' ) {
+ updatePointer = delegate.touchPoints[ curPointer.id ] || null;
+ if ( updatePointer ) {
+ pressPoint = updatePointer.startPos;
+ pressTime = updatePointer.startTime;
+ delete delegate.touchPoints[ curPointer.id ];
+ delegate.touchPointCount--;
+ if ( !delegate.touchPointCount ) {
+ dispatchRelease = true;
+ releasePoint = curPointer.currentPos;
+ }
+ }
+ }
+ else if ( curPointer.type === 'pen' ) {
+ updatePointer = delegate.penPoints[ curPointer.id ] || null;
+ if ( updatePointer ) {
+ pressPoint = updatePointer.startPos;
+ pressTime = updatePointer.startTime;
+ delete delegate.penPoints[ curPointer.id ];
+ delegate.penPointCount--;
+ if ( !delegate.penPointCount ) {
+ dispatchRelease = true;
+ releasePoint = curPointer.currentPos;
+ }
+ }
+ }
+ else {
+ updatePointer = null;
+ }
- if ( event.touches.length === 1 &&
- event.targetTouches.length === 1 &&
- event.changedTouches.length === 1 &&
- THIS[ tracker.hash ].lastTouch.identifier === event.touches[ 0 ].identifier ) {
+ if ( dispatchRelease ) {
+ if ( updatePointer ) {
+ insideElementPressed = updatePointer.insideElementPressed;
+ insideElementReleased = $.pointInElement( tracker.element, releasePoint );
+ }
+ else {
+ insideElementPressed = false;
+ insideElementReleased = false;
+ }
- onMouseMoveCaptured( tracker, event, true );
+ if ( tracker.releaseHandler ) {
+ propagate = tracker.releaseHandler(
+ {
+ eventSource: tracker,
+ position: getPointRelative( releasePoint, tracker.element ),
+ insideElementPressed: insideElementPressed,
+ insideElementReleased: insideElementReleased,
+ isTouchEvent: curPointer.type === 'touch',
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+ if ( propagate === false ) {
+ $.cancelEvent( event );
+ }
+ }
- } else if ( event.touches.length === 2 ) {
+ // Click Gesture
+ if ( insideElementPressed && insideElementReleased && tracker.clickHandler ) {
+ var time = curPointer.currentTime - pressTime,
+ distance = pressPoint.distanceTo( curPointer.currentPos ),
+ quick = time <= tracker.clickTimeThreshold &&
+ distance <= tracker.clickDistThreshold;
- touchA = getMouseAbsolute( event.touches[ 0 ] );
- touchB = getMouseAbsolute( event.touches[ 1 ] );
- pinchDelta =
- Math.abs( touchA.x - touchB.x ) +
- Math.abs( touchA.y - touchB.y );
-
- //TODO: make the 75px pinch threshold configurable
- if ( Math.abs( THIS[ tracker.hash ].lastPinchDelta - pinchDelta ) > 75 ) {
- //$.console.debug( "pinch delta : " + pinchDelta + " | previous : " + THIS[ tracker.hash ].lastPinchDelta);
-
- // Simulate a 'wheel' event
- var simulatedEvent = {
- target: event.target || event.srcElement,
- type: "wheel",
- shiftKey: event.shiftKey || false,
- clientX: THIS[ tracker.hash ].pinchMidpoint.x,
- clientY: THIS[ tracker.hash ].pinchMidpoint.y,
- pageX: THIS[ tracker.hash ].pinchMidpoint.x,
- pageY: THIS[ tracker.hash ].pinchMidpoint.y,
- deltaMode: 1, // 0=pixel, 1=line, 2=page
- deltaX: 0,
- deltaY: ( THIS[ tracker.hash ].lastPinchDelta > pinchDelta ) ? 1 : -1,
- deltaZ: 0
- };
-
- handleWheelEvent( tracker, simulatedEvent, event, true );
-
- THIS[ tracker.hash ].lastPinchDelta = pinchDelta;
+ propagate = tracker.clickHandler(
+ {
+ eventSource: tracker,
+ position: getPointRelative( curPointer.currentPos, tracker.element ),
+ quick: quick,
+ shift: event.shiftKey,
+ isTouchEvent: curPointer.type === 'touch',
+ originalEvent: event,
+ preventDefaultAction: false,
+ userData: tracker.userData
+ }
+ );
+ if ( propagate === false ) {
+ $.cancelEvent( event );
+ }
+ }
}
}
- event.preventDefault();
}
+
/**
- * Only triggered once by the deepest element that initially received
- * the mouse down event. Since no other element has captured the mouse,
- * we want to trigger the elements that initially received the mouse
- * down event (including this one). The the param tracker isn't used
- * but for consistency with the other event handlers we include it.
* @private
* @inner
*/
- function onMouseMoveCapturedIE( tracker, event ) {
- var i;
- for ( i = 0; i < CAPTURING.length; i++ ) {
- onMouseMoveCaptured( CAPTURING[ i ], event, false );
+ function cancelPointers( tracker, event, pointers ) {
+ var delegate = THIS[ tracker.hash ],
+ i,
+ pointerCount = pointers.length,
+ curPointer;
+
+ for ( i = 0; i < pointerCount; i++ ) {
+ curPointer = pointers[ i ];
+ if ( curPointer.type === 'mouse' ) {
+ if ( delegate.mousePoints[ curPointer.id ] ) {
+ delete delegate.mousePoints[ curPointer.id ];
+ delegate.mousePointCount--;
+ }
+ }
+ else if ( curPointer.type === 'touch' ) {
+ if ( delegate.touchPoints[ curPointer.id ] ) {
+ delete delegate.touchPoints[ curPointer.id ];
+ delegate.touchPointCount--;
+ }
+ }
+ else if ( curPointer.type === 'pen' ) {
+ if ( delegate.penPoints[ curPointer.id ] ) {
+ delete delegate.penPoints[ curPointer.id ];
+ delegate.penPointCount--;
+ }
+ }
}
-
- $.stopEvent( event );
}
- /**
- * @private
- * @inner
- */
- function getMouseAbsolute( event ) {
- return $.getMousePosition( event );
- }
- /**
- * @private
- * @inner
- */
- function getMouseRelative( event, element ) {
- var mouse = $.getMousePosition( event ),
- offset = $.getElementOffset( element );
+//*******************************************************************************************************************************************
+//*******************************************************************************************************************************************
+
+
+ //function handlePointerOver( tracker, event, position ) {
+ // var delegate = THIS[ tracker.hash ],
+ // propagate;
+
+ // //if ( !isTouch ) {
+ // // if ( $.Browser.vendor == $.BROWSERS.IE &&
+ // // $.Browser.version < 9 &&
+ // // delegate.capturing &&
+ // // !isChild( event.srcElement, tracker.element ) ) {
+
+ // // triggerOthers( tracker, onMouseOver, event, isTouch );
+ // // }
+
+ // // var to = event.target ?
+ // // event.target :
+ // // event.srcElement,
+ // // from = event.relatedTarget ?
+ // // event.relatedTarget :
+ // // event.fromElement;
+
+ // // if ( !isChild( tracker.element, to ) ||
+ // // isChild( tracker.element, from ) ) {
+ // // return;
+ // // }
+ // //}
+
+ // //delegate.insideElement = true;
+
+ // if ( tracker.enterHandler ) {
+ // propagate = tracker.enterHandler(
+ // {
+ // eventSource: tracker,
+ // position: position,
+ // insideElementPressed: delegate.insideElementPressed,
+ // buttonDownAny: IS_BUTTON_DOWN,
+ // isTouchEvent: false,//isTouch,
+ // originalEvent: event,
+ // preventDefaultAction: false,
+ // userData: tracker.userData
+ // }
+ // );
+ // if ( propagate === false ) {
+ // $.cancelEvent( event );
+ // }
+ // }
+ //}
+
+
+ //function handlePointerOut( tracker, event, position ) {
+ // var delegate = THIS[ tracker.hash ],
+ // propagate;
+
+ // //if ( !isTouch ) {
+ // // if ( $.Browser.vendor == $.BROWSERS.IE &&
+ // // $.Browser.version < 9 &&
+ // // delegate.capturing &&
+ // // !isChild( event.srcElement, tracker.element ) ) {
+
+ // // triggerOthers( tracker, onMouseOut, event, isTouch );
+
+ // // }
+
+ // // var from = event.target ?
+ // // event.target :
+ // // event.srcElement,
+ // // to = event.relatedTarget ?
+ // // event.relatedTarget :
+ // // event.toElement;
+
+ // // if ( !isChild( tracker.element, from ) ||
+ // // isChild( tracker.element, to ) ) {
+ // // return;
+ // // }
+ // //}
+
+ // //delegate.insideElement = false;
+
+ // if ( tracker.exitHandler ) {
+ // propagate = tracker.exitHandler(
+ // {
+ // eventSource: tracker,
+ // position: position,
+ // insideElementPressed: delegate.insideElementPressed,
+ // buttonDownAny: IS_BUTTON_DOWN,
+ // isTouchEvent: false,//isTouch,
+ // originalEvent: event,
+ // preventDefaultAction: false,
+ // userData: tracker.userData
+ // }
+ // );
+
+ // if ( propagate === false ) {
+ // $.cancelEvent( event );
+ // }
+ // }
+ //}
+
+
+ ///**
+ // * @private
+ // * @inner
+ // */
+ //function handlePointerMove( tracker, event ) {
+ // var propagate;
+ // if ( tracker.moveHandler ) {
+ // propagate = tracker.moveHandler(
+ // {
+ // eventSource: tracker,
+ // position: getMouseRelative( event, tracker.element ),
+ // isTouchEvent: false,
+ // originalEvent: event,
+ // preventDefaultAction: false,
+ // userData: tracker.userData
+ // }
+ // );
+ // if ( propagate === false ) {
+ // $.cancelEvent( event );
+ // }
+ // }
+ // if ( tracker.stopHandler ) {
+ // clearTimeout( tracker.stopTimeOut );
+ // tracker.stopTimeOut = setTimeout( function() {
+ // handlePointerStop( tracker, event );
+ // }, tracker.stopDelay );
+ // }
+ //}
+
+ //
+ ///**
+ // * @private
+ // * @inner
+ // */
+ //function handleMouseClick( tracker, event, isTouch ) {
+ // var delegate = THIS[ tracker.hash ],
+ // propagate;
+
+ // isTouch = isTouch || false;
+
+ // event = $.getEvent( event );
+
+ // var eventOrTouchPoint = isTouch ? event.changedTouches[ 0 ] : event;
+
+ // if ( event.button == 2 ) {
+ // return;
+ // }
+
+ // var time = $.now() - delegate.lastMouseDownTime,
+ // point = getMouseAbsolute( eventOrTouchPoint ),
+ // distance = delegate.lastMouseDownPoint.distanceTo( point ),
+ // quick = time <= tracker.clickTimeThreshold &&
+ // distance <= tracker.clickDistThreshold;
+
+ // if ( tracker.clickHandler ) {
+ // propagate = tracker.clickHandler(
+ // {
+ // eventSource: tracker,
+ // position: getMouseRelative( eventOrTouchPoint, tracker.element ),
+ // quick: quick,
+ // shift: event.shiftKey,
+ // isTouchEvent: isTouch,
+ // originalEvent: event,
+ // preventDefaultAction: false,
+ // userData: tracker.userData
+ // }
+ // );
+ // if ( propagate === false ) {
+ // $.cancelEvent( event );
+ // }
+ // }
+ //}
- return mouse.minus( offset );
- }
/**
* @private
diff --git a/src/openseadragon.js b/src/openseadragon.js
index 611d1cd4..b56af941 100644
--- a/src/openseadragon.js
+++ b/src/openseadragon.js
@@ -998,6 +998,21 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
},
+ /**
+ * Determines if a point is within the bounding rectangle of the given element (hit-test).
+ * @function
+ * @param {Element|String} element
+ * @param {OpenSeadragon.Point} point
+ * @returns {Boolean}
+ */
+ pointInElement: function( element, point ) {
+ element = $.getElement( element );
+ var offset = $.getElementOffset( element ),
+ size = $.getElementSize( element );
+ return point.x >= offset.x && point.x < offset.x + size.x && point.y < offset.y + size.y && point.y >= offset.y;
+ },
+
+
/**
* Gets the latest event, really only useful internally since its
* specific to IE behavior.
diff --git a/src/viewer.js b/src/viewer.js
index cd4b5614..1d53fa2c 100644
--- a/src/viewer.js
+++ b/src/viewer.js
@@ -270,7 +270,14 @@ $.Viewer = function( options ) {
style.position = "absolute";
style.top = "0px";
style.left = "0px";
- }( this.canvas.style ));
+ // Disable browser default touch handling
+ if (style["touch-action"] !== undefined) {
+ style["touch-action"] = "none";
+ }
+ else if (style["-ms-touch-action"] !== undefined) {
+ style["-ms-touch-action"] = "none";
+ }
+ }(this.canvas.style));
//the container is created through applying the ControlDock constructor above
this.container.className = "openseadragon-container";
@@ -378,7 +385,8 @@ $.Viewer = function( options ) {
clickHandler: $.delegate( this, onCanvasClick ),
dragHandler: $.delegate( this, onCanvasDrag ),
releaseHandler: $.delegate( this, onCanvasRelease ),
- scrollHandler: $.delegate( this, onCanvasScroll )
+ scrollHandler: $.delegate( this, onCanvasScroll ),
+ pinchHandler: $.delegate( this, onCanvasPinch )
}).setTracking( this.mouseNavEnabled ? true : false ); // default state
this.outerTracker = new $.MouseTracker({
@@ -1817,7 +1825,7 @@ function onCanvasScroll( event ) {
this.viewport.applyConstraints();
}
/**
- * Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#canvas} element (mouse wheel, touch pinch, etc.).
+ * Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#canvas} element (mouse wheel).
*
* @event canvas-scroll
* @memberof OpenSeadragon.Viewer
@@ -1841,7 +1849,41 @@ function onCanvasScroll( event ) {
return false;
}
-function onContainerExit( event ) {
+function onCanvasPinch(event) {
+ if (!event.preventDefaultAction && this.viewport) {
+ //TODO This is temporary for testing. Zoom should track pinch gesture one-to-one, around center point!
+ this.viewport.zoomBy(
+ ( event.delta > 0 ) ? 1.2 : 0.8,
+ this.viewport.pointFromPixel(event.position, true)
+ );
+ this.viewport.applyConstraints();
+ }
+ /**
+ * Raised when a pinch event occurs on the {@link OpenSeadragon.Viewer#canvas} element.
+ *
+ * @event canvas-pinch
+ * @memberof OpenSeadragon.Viewer
+ * @type {object}
+ * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
+ * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.
+ * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.
+ * @property {Number} delta - The pinch delta for the event.
+ * @property {Boolean} shift - True if the shift key was pressed during this event.
+ * @property {Object} originalEvent - The original DOM event.
+ * @property {?Object} userData - Arbitrary subscriber-defined object.
+ */
+ this.raiseEvent('canvas-pinch', {
+ tracker: event.eventSource,
+ position: event.position,
+ delta: event.delta,
+ shift: event.shift,
+ originalEvent: event.originalEvent
+ });
+ //cancels event
+ return false;
+}
+
+function onContainerExit(event) {
if ( !event.insideElementPressed ) {
THIS[ this.hash ].mouseInside = false;
if ( !THIS[ this.hash ].animating ) {