Mousetracker Over/Out Tracking Fixes

This commit is contained in:
Mark Salsbery 2014-08-04 21:41:07 -07:00
parent 975828c057
commit e11095968c
8 changed files with 251 additions and 37 deletions

View File

@ -137,6 +137,11 @@ $.Button = function( options ) {
this.tooltip; this.tooltip;
this.element.style.position = "relative"; this.element.style.position = "relative";
if ( this.element.style[ "touch-action" ] !== undefined ) {
this.element.style[ "touch-action" ] = "none";
} else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) {
this.element.style[ "-ms-touch-action" ] = "none";
}
this.imgGroup.style.position = this.imgGroup.style.position =
this.imgHover.style.position = this.imgHover.style.position =
@ -207,6 +212,7 @@ $.Button = function( options ) {
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
enterHandler: function( event ) { enterHandler: function( event ) {
$.console.log('Enter ');// + event.currentTarget.className);
if ( event.insideElementPressed ) { if ( event.insideElementPressed ) {
inTo( _this, $.ButtonState.DOWN ); inTo( _this, $.ButtonState.DOWN );
/** /**
@ -241,6 +247,7 @@ $.Button = function( options ) {
}, },
exitHandler: function( event ) { exitHandler: function( event ) {
$.console.log('Exit ');// + event.currentTarget.className);
outTo( _this, $.ButtonState.GROUP ); outTo( _this, $.ButtonState.GROUP );
if ( event.insideElementPressed ) { if ( event.insideElementPressed ) {
/** /**

View File

@ -80,6 +80,12 @@ $.ButtonGroup = function( options ) {
} }
} }
if ( this.element.style[ "touch-action" ] !== undefined ) {
this.element.style[ "touch-action" ] = "none";
} else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) {
this.element.style[ "-ms-touch-action" ] = "none";
}
/** /**
* Tracks mouse/touch/key events accross the group of buttons. * Tracks mouse/touch/key events accross the group of buttons.
* @member {OpenSeadragon.MouseTracker} tracker * @member {OpenSeadragon.MouseTracker} tracker

View File

@ -205,6 +205,10 @@
gesturestart: function ( event ) { onGestureStart( _this, event ); }, gesturestart: function ( event ) { onGestureStart( _this, event ); },
gesturechange: function ( event ) { onGestureChange( _this, event ); }, gesturechange: function ( event ) { onGestureChange( _this, event ); },
pointerover: function ( event ) { onPointerOver( _this, event ); },
MSPointerOver: function ( event ) { onPointerOver( _this, event ); },
pointerout: function ( event ) { onPointerOut( _this, event ); },
MSPointerOut: function ( event ) { onPointerOut( _this, event ); },
pointerenter: function ( event ) { onPointerEnter( _this, event ); }, pointerenter: function ( event ) { onPointerEnter( _this, event ); },
MSPointerEnter: function ( event ) { onPointerEnter( _this, event ); }, MSPointerEnter: function ( event ) { onPointerEnter( _this, event ); },
pointerleave: function ( event ) { onPointerLeave( _this, event ); }, pointerleave: function ( event ) { onPointerLeave( _this, event ); },
@ -217,6 +221,8 @@
MSPointerMove: function ( event ) { onPointerMove( _this, event ); }, MSPointerMove: function ( event ) { onPointerMove( _this, event ); },
pointercancel: function ( event ) { onPointerCancel( _this, event ); }, pointercancel: function ( event ) { onPointerCancel( _this, event ); },
MSPointerCancel: function ( event ) { onPointerCancel( _this, event ); }, MSPointerCancel: function ( event ) { onPointerCancel( _this, event ); },
pointerupcaptured: function ( event ) { onPointerUpCaptured( _this, event ); },
pointermovecaptured: function ( event ) { onPointerMoveCaptured( _this, event ); },
tracking: false, tracking: false,
@ -812,32 +818,41 @@
} }
if ( window.PointerEvent ) { if ( window.PointerEvent ) {
$.console.log('***** Pointer Event Model');
// IE11 and other W3C Pointer Event implementations (see http://www.w3.org/TR/pointerevents) // IE11 and other W3C Pointer Event implementations (see http://www.w3.org/TR/pointerevents)
$.MouseTracker.subscribeEvents.push( "pointerenter", "pointerleave", "pointerdown", "pointerup", "pointermove", "pointercancel" ); $.MouseTracker.subscribeEvents.push( "pointerover", "pointerout", "pointerdown", "pointerup", "pointermove", "pointercancel" );
$.MouseTracker.unprefixedPointerEvents = true; $.MouseTracker.unprefixedPointerEvents = true;
if( navigator.maxTouchPoints ) { if( navigator.maxTouchPoints ) {
$.MouseTracker.maxTouchPoints = navigator.maxTouchPoints; $.MouseTracker.maxTouchPoints = navigator.maxTouchPoints;
} else { } else {
$.MouseTracker.maxTouchPoints = 0; $.MouseTracker.maxTouchPoints = 0;
} }
$.MouseTracker.haveTouchEnter = true; $.MouseTracker.haveTouchEnter = false;
$.MouseTracker.haveMouseEnter = true; $.MouseTracker.haveMouseEnter = false;
} else if ( window.MSPointerEvent ) { } else if ( window.MSPointerEvent ) {
$.console.log('***** Pointer Event Model (Prefixed IE10)');
// IE10 // IE10
$.MouseTracker.subscribeEvents.push( "MSPointerEnter", "MSPointerLeave", "MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel" ); $.MouseTracker.subscribeEvents.push( "MSPointerOver", "MSPointerOut", "MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel" );
$.MouseTracker.unprefixedPointerEvents = false; $.MouseTracker.unprefixedPointerEvents = false;
if( navigator.msMaxTouchPoints ) { if( navigator.msMaxTouchPoints ) {
$.MouseTracker.maxTouchPoints = navigator.msMaxTouchPoints; $.MouseTracker.maxTouchPoints = navigator.msMaxTouchPoints;
} else { } else {
$.MouseTracker.maxTouchPoints = 0; $.MouseTracker.maxTouchPoints = 0;
} }
$.MouseTracker.haveTouchEnter = true; $.MouseTracker.haveTouchEnter = false;
$.MouseTracker.haveMouseEnter = true; $.MouseTracker.haveMouseEnter = false;
} else { } else {
$.console.log('***** Legacy Event Model');
// Legacy W3C mouse events // Legacy W3C mouse events
// TODO: Favor mouseenter/mouseleave over mouseover/mouseout when Webkit browser support is better // TODO: Favor mouseenter/mouseleave over mouseover/mouseout when Webkit browser support is better
$.MouseTracker.subscribeEvents.push( "mouseover", "mouseout", "mousedown", "mouseup", "mousemove" ); $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" );
$.MouseTracker.haveMouseEnter = false; //if ( $.Browser.vendor == $.BROWSERS.IE ) {
// $.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" );
// $.MouseTracker.haveMouseEnter = true;
//} else {
$.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" );
$.MouseTracker.haveMouseEnter = false;
//}
if ( 'ontouchstart' in window ) { if ( 'ontouchstart' in window ) {
// iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505) // iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505)
$.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" ); $.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" );
@ -1083,10 +1098,10 @@
var delegate = THIS[ tracker.hash ]; var delegate = THIS[ tracker.hash ];
if ( !delegate.capturing ) { if ( !delegate.capturing ) {
if ( $.MouseTracker.supportsMouseCapture ) { // if ( $.MouseTracker.supportsMouseCapture ) {
// IE<10, Firefox, other browsers with setCapture()/releaseCapture() // // IE<10, Firefox, other browsers with setCapture()/releaseCapture()
tracker.element.setCapture( true ); // tracker.element.setCapture( true );
} else { // } else {
// For browsers without setCapture()/releaseCapture(), we emulate mouse capture by hanging listeners on the window object. // For browsers without setCapture()/releaseCapture(), 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) // (Note we listen on the capture phase so the captured handlers will get called first)
$.addEvent( $.addEvent(
@ -1101,7 +1116,7 @@
delegate.mousemovecaptured, delegate.mousemovecaptured,
true true
); );
} // }
delegate.capturing = true; delegate.capturing = true;
} }
} }
@ -1116,10 +1131,10 @@
var delegate = THIS[ tracker.hash ]; var delegate = THIS[ tracker.hash ];
if ( delegate.capturing ) { if ( delegate.capturing ) {
if ( $.MouseTracker.supportsMouseCapture ) { // if ( $.MouseTracker.supportsMouseCapture ) {
// IE<10, Firefox, other browsers with setCapture()/releaseCapture() // // IE<10, Firefox, other browsers with setCapture()/releaseCapture()
tracker.element.releaseCapture(); // tracker.element.releaseCapture();
} else { // } else {
// For browsers without setCapture()/releaseCapture(), we emulate mouse capture by hanging listeners on the window object. // For browsers without setCapture()/releaseCapture(), 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) // (Note we listen on the capture phase so the captured handlers will get called first)
$.removeEvent( $.removeEvent(
@ -1134,7 +1149,7 @@
delegate.mouseupcaptured, delegate.mouseupcaptured,
true true
); );
} // }
delegate.capturing = false; delegate.capturing = false;
} }
} }
@ -1418,7 +1433,7 @@
event = $.getEvent( event ); event = $.getEvent( event );
if ( this === event.relatedTarget || isParentChild( this, event.relatedTarget ) ) { if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget ||
return; return;
} }
@ -1443,7 +1458,7 @@
event = $.getEvent( event ); event = $.getEvent( event );
if ( this === event.relatedTarget || isParentChild( this, event.relatedTarget ) ) { if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget ||
return; return;
} }
@ -1803,6 +1818,52 @@
} }
/**
* @private
* @inner
*/
function onPointerOver( tracker, event ) {
var gPoint;
if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget ||
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;
if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget ||
return;
}
gPoint = {
id: event.pointerId,
type: getPointerType( event ),
isPrimary: event.isPrimary,
currentPos: getMouseAbsolute( event ),
currentTime: $.now()
};
updatePointersExit( tracker, event, [ gPoint ] );
}
/** /**
* @private * @private
* @inner * @inner
@ -1841,6 +1902,72 @@
} }
/**
* Begin capturing pointer events to the tracked element (pointer event model only).
* @private
* @inner
*/
function capturePointer( tracker ) {
var delegate = THIS[ tracker.hash ];
if ( !delegate.capturing ) {
// if ( $.MouseTracker.supportsMouseCapture ) {
// // IE<10, Firefox, other browsers with setCapture()/releaseCapture()
// tracker.element.setCapture( true );
// } else {
// For browsers without setCapture()/releaseCapture(), 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(
window,
$.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp',
delegate.pointerupcaptured,
true
);
$.addEvent(
window,
$.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove',
delegate.pointermovecaptured,
true
);
// }
delegate.capturing = true;
}
}
/**
* Stop capturing pointer events to the tracked element (pointer event model only).
* @private
* @inner
*/
function releasePointer( tracker ) {
var delegate = THIS[ tracker.hash ];
if ( delegate.capturing ) {
// if ( $.MouseTracker.supportsMouseCapture ) {
// // IE<10, Firefox, other browsers with setCapture()/releaseCapture()
// tracker.element.releaseCapture();
// } else {
// For browsers without setCapture()/releaseCapture(), 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(
window,
$.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove',
delegate.pointermovecaptured,
true
);
$.removeEvent(
window,
$.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp',
delegate.pointerupcaptured,
true
);
// }
delegate.capturing = false;
}
}
/** /**
* @private * @private
* @inner * @inner
@ -1857,11 +1984,12 @@
}; };
if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) { if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) {
if ( $.MouseTracker.unprefixedPointerEvents ) { // if ( $.MouseTracker.unprefixedPointerEvents ) {
event.currentTarget.setPointerCapture( event.pointerId ); // event.currentTarget.setPointerCapture( event.pointerId );
} else { // } else {
event.currentTarget.msSetPointerCapture( event.pointerId ); // event.currentTarget.msSetPointerCapture( event.pointerId );
} // }
capturePointer( tracker );
$.stopEvent( event ); $.stopEvent( event );
} }
@ -1876,6 +2004,28 @@
* @inner * @inner
*/ */
function onPointerUp( tracker, event ) { function onPointerUp( tracker, event ) {
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 ) {
handlePointerUp( tracker, event );
$.stopEvent( event );
}
/**
* @private
* @inner
*/
function handlePointerUp( tracker, event ) {
var gPoint; var gPoint;
gPoint = { gPoint = {
@ -1887,11 +2037,13 @@
}; };
if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) { if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) {
if ( $.MouseTracker.unprefixedPointerEvents ) { // if ( $.MouseTracker.unprefixedPointerEvents ) {
event.currentTarget.releasePointerCapture( event.pointerId ); // event.currentTarget.releasePointerCapture( event.pointerId );
} else { // } else {
event.currentTarget.msReleasePointerCapture( event.pointerId ); // event.currentTarget.msReleasePointerCapture( event.pointerId );
} // }
releasePointer( tracker );
// $.stopEvent( event );
} }
} }
@ -1901,6 +2053,28 @@
* @inner * @inner
*/ */
function onPointerMove( tracker, event ) { function onPointerMove( tracker, event ) {
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 ) {
handlePointerMove( tracker, event );
$.stopEvent( event );
}
/**
* @private
* @inner
*/
function handlePointerMove( tracker, event ) {
// Pointer changed coordinates, button state, pressure, tilt, or contact geometry (e.g. width and height) // Pointer changed coordinates, button state, pressure, tilt, or contact geometry (e.g. width and height)
var gPoint; var gPoint;
@ -1964,6 +2138,7 @@
gPoint.lastPos = gPoint.currentPos; gPoint.lastPos = gPoint.currentPos;
gPoint.lastTime = gPoint.currentTime; gPoint.lastTime = gPoint.currentTime;
// $.console.log('startTrackingPointer() ', pointsList.getLength() + 1);
return pointsList.add( gPoint ); return pointsList.add( gPoint );
} }
@ -1999,6 +2174,7 @@
listLength = pointsList.getLength(); listLength = pointsList.getLength();
} }
// $.console.log('stopTrackingPointer() ', listLength);
return listLength; return listLength;
} }
@ -2213,6 +2389,7 @@
} }
pointsList.contacts++; pointsList.contacts++;
$.console.log('contacts++ ', pointsList.contacts);
if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {
$.MouseTracker.gesturePointVelocityTracker.addPoint( tracker, curGPoint ); $.MouseTracker.gesturePointVelocityTracker.addPoint( tracker, curGPoint );
@ -2339,6 +2516,7 @@
// Pointer was activated in our element but could have been removed in any element since events are captured to our element // Pointer was activated in our element but could have been removed in any element since events are captured to our element
pointsList.contacts--; pointsList.contacts--;
$.console.log('contacts-- ', pointsList.contacts);
if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {
$.MouseTracker.gesturePointVelocityTracker.removePoint( tracker, updateGPoint ); $.MouseTracker.gesturePointVelocityTracker.removePoint( tracker, updateGPoint );

View File

@ -112,6 +112,12 @@ $.Navigator = function( options ){
options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio; options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio;
if ( this.element.style[ "touch-action" ] !== undefined ) {
this.element.style[ "touch-action" ] = "none";
} else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) {
this.element.style[ "-ms-touch-action" ] = "none";
}
this.borderWidth = 2; this.borderWidth = 2;
//At some browser magnification levels the display regions lines up correctly, but at some there appears to //At some browser magnification levels the display regions lines up correctly, but at some there appears to
//be a one pixel gap. //be a one pixel gap.

View File

@ -2161,7 +2161,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
) )
); );
} else { } else {
regex = new RegExp( "Trident/.*rv:([0-9]{1,}[.0-9]{0,}) "); regex = new RegExp( "Trident/.*rv:([0-9]{1,}[.0-9]{0,})");
if ( regex.exec( ua ) !== null ) { if ( regex.exec( ua ) !== null ) {
$.Browser.vendor = $.BROWSERS.IE; $.Browser.vendor = $.BROWSERS.IE;
$.Browser.version = parseFloat( RegExp.$1 ); $.Browser.version = parseFloat( RegExp.$1 );

View File

@ -114,6 +114,12 @@ $.ReferenceStrip = function ( options ) {
style.background = '#000'; style.background = '#000';
style.position = 'relative'; style.position = 'relative';
if ( this.element.style[ "touch-action" ] !== undefined ) {
this.element.style[ "touch-action" ] = "none";
} else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) {
this.element.style[ "-ms-touch-action" ] = "none";
}
$.setElementOpacity( this.element, 0.8 ); $.setElementOpacity( this.element, 0.8 );
this.viewer = viewer; this.viewer = viewer;
@ -189,6 +195,11 @@ $.ReferenceStrip = function ( options ) {
element.style.cssFloat = 'left'; //Firefox element.style.cssFloat = 'left'; //Firefox
element.style.styleFloat = 'left'; //IE element.style.styleFloat = 'left'; //IE
element.style.padding = '2px'; element.style.padding = '2px';
if ( element.style[ "touch-action" ] !== undefined ) {
element.style[ "touch-action" ] = "none";
} else if ( element.style[ "-ms-touch-action" ] !== undefined ) {
element.style[ "-ms-touch-action" ] = "none";
}
element.innerTracker = new $.MouseTracker( { element.innerTracker = new $.MouseTracker( {
element: element, element: element,

View File

@ -276,10 +276,10 @@ $.Viewer = function( options ) {
style.top = "0px"; style.top = "0px";
style.left = "0px"; style.left = "0px";
// Disable browser default touch handling // Disable browser default touch handling
if (style["touch-action"] !== undefined) { if ( style[ "touch-action" ] !== undefined ) {
style["touch-action"] = "none"; style[ "touch-action" ] = "none";
} else if (style["-ms-touch-action"] !== undefined) { } else if ( style["-ms-touch-action"] !== undefined ) {
style["-ms-touch-action"] = "none"; style[ "-ms-touch-action" ] = "none";
} }
}(this.canvas.style)); }(this.canvas.style));

View File

@ -11,8 +11,14 @@
$.MouseTracker.subscribeEvents.push( "MozMousePixelScroll" ); $.MouseTracker.subscribeEvents.push( "MozMousePixelScroll" );
} }
$.MouseTracker.subscribeEvents.push( "mouseover", "mouseout", "mousedown", "mouseup", "mousemove" ); $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" );
$.MouseTracker.haveMouseEnter = false; if ( $.Browser.vendor == $.BROWSERS.IE ) {
$.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" );
$.MouseTracker.haveMouseEnter = true;
} else {
$.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" );
$.MouseTracker.haveMouseEnter = false;
}
if ( 'ontouchstart' in window ) { if ( 'ontouchstart' in window ) {
// iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505) // iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505)
$.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" ); $.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" );