diff --git a/src/openseadragon.js b/src/openseadragon.js index 6b36327b..c0111b2b 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -255,6 +255,11 @@ * @property {Boolean} [preserveImageSizeOnResize=false] * Set to true to have the image size preserved when the viewer is resized. This requires autoResize=true (default). * + * @property {Number} [minScrollDeltaTime=50] + * Number of milliseconds between canvas-scroll events. This value helps normalize the rate of canvas-scroll + * events between different devices, causing the faster devices to slow down enough to make the zoom control + * more manageable. + * * @property {Number} [pixelsPerWheelLine=40] * For pixel-resolution scrolling devices, the number of pixels equal to one scroll line. * @@ -1003,6 +1008,7 @@ if (typeof define === 'function' && define.amd) { pixelsPerWheelLine: 40, autoResize: true, preserveImageSizeOnResize: false, // requires autoResize=true + minScrollDeltaTime: 50, //DEFAULT CONTROL SETTINGS showSequenceControl: true, //SEQUENCE diff --git a/src/viewer.js b/src/viewer.js index 923bfd6b..0890a55d 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -203,6 +203,8 @@ $.Viewer = function( options ) { this._loadQueue = []; this.currentOverlays = []; + this._lastScrollTime = $.now(); // variable used to help normalize the scroll event speed of different devices + //Inherit some behaviors and properties $.EventSource.call( this ); @@ -604,7 +606,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, var originalSuccess = options.success; options.success = function(event) { successes++; - + // TODO: now that options has other things besides tileSource, the overlays // should probably be at the options level, not the tileSource level. if (options.tileSource.overlays) { @@ -2738,44 +2740,57 @@ function onCanvasPinch( event ) { function onCanvasScroll( event ) { var gestureSettings, - factor; + factor, + thisScrollTime, + deltaScrollTime; - if ( !event.preventDefaultAction && this.viewport ) { - gestureSettings = this.gestureSettingsByDeviceType( event.pointerType ); - if ( gestureSettings.scrollToZoom ) { - factor = Math.pow( this.zoomPerScroll, event.scroll ); - this.viewport.zoomBy( - factor, - this.viewport.pointFromPixel( event.position, true ) - ); - this.viewport.applyConstraints(); + /* Certain scroll devices fire the scroll event way too fast so we are injecting a simple adjustment to keep things + * partially normalized. If we have already fired an event within the last 'minScrollDelta' milliseconds we skip + * this one and wait for the next event. */ + thisScrollTime = $.now(); + deltaScrollTime = thisScrollTime - this._lastScrollTime; + if (deltaScrollTime > this.minScrollDeltaTime) { + this._lastScrollTime = thisScrollTime; + + if ( !event.preventDefaultAction && this.viewport ) { + gestureSettings = this.gestureSettingsByDeviceType( event.pointerType ); + if ( gestureSettings.scrollToZoom ) { + factor = Math.pow( this.zoomPerScroll, event.scroll ); + this.viewport.zoomBy( + factor, + this.viewport.pointFromPixel( event.position, true ) + ); + this.viewport.applyConstraints(); + } + } + /** + * Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#canvas} element (mouse wheel). + * + * @event canvas-scroll + * @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} scroll - The scroll 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-scroll', { + tracker: event.eventSource, + position: event.position, + scroll: event.scroll, + shift: event.shift, + originalEvent: event.originalEvent + }); + if (gestureSettings && gestureSettings.scrollToZoom) { + //cancels event + return false; } } - /** - * Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#canvas} element (mouse wheel). - * - * @event canvas-scroll - * @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} scroll - The scroll 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-scroll', { - tracker: event.eventSource, - position: event.position, - scroll: event.scroll, - shift: event.shift, - originalEvent: event.originalEvent - }); - - if (gestureSettings && gestureSettings.scrollToZoom) { - //cancels event - return false; + else { + return false; // We are swallowing this event } }