From 56f5b9fb74c1c7c0b570851d54b83e1a5ae3d693 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Fri, 6 Sep 2013 10:43:39 -0700 Subject: [PATCH] MouseTracker Original Events in handlers Comment & Formatting fixes --- src/button.js | 10 +- src/mousetracker.js | 782 +++++++++++++++++------------------ src/openseadragon.js | 6 - src/referencestrip.js | 918 +++++++++++++++++++++--------------------- 4 files changed, 854 insertions(+), 862 deletions(-) diff --git a/src/button.js b/src/button.js index 4524234e..c1f711bd 100644 --- a/src/button.js +++ b/src/button.js @@ -184,9 +184,8 @@ $.Button = function( options ) { } }, - // TODO: This didn't match handler signature in MouseTracker. Investigate! - focusHandler: function ( tracker, eventData ) { //position, buttonDownElement, buttonDownAny - //this.enterHandler( tracker, eventData ); //position, buttonDownElement, buttonDownAny + focusHandler: function ( tracker, eventData ) { + this.enterHandler( tracker, eventData ); _this.raiseEvent( "onFocus", _this ); }, @@ -197,9 +196,8 @@ $.Button = function( options ) { } }, - // TODO: This didn't match handler signature in MouseTracker. Investigate! - blurHandler: function ( tracker, eventData ) { //position, buttonDownElement, buttonDownAny - //this.exitHandler( tracker, eventData ); //position, buttonDownElement, buttonDownAny + blurHandler: function ( tracker, eventData ) { + this.exitHandler( tracker, eventData ); _this.raiseEvent( "onBlur", _this ); }, diff --git a/src/mousetracker.js b/src/mousetracker.js index 36492d6a..c765b3d1 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -34,78 +34,78 @@ (function ( $ ) { - // is any button currently being pressed while mouse events occur + // is any button currently being pressed while mouse events occur var IS_BUTTON_DOWN = false, - // is any tracker currently capturing? - IS_CAPTURING = false, - // dictionary from hash to MouseTracker - ACTIVE = {}, - // list of trackers interested in capture - CAPTURING = [], - // dictionary from hash to private properties - THIS = {}; + // is any tracker currently capturing? + IS_CAPTURING = false, + // dictionary from hash to MouseTracker + ACTIVE = {}, + // list of trackers interested in capture + CAPTURING = [], + // dictionary from hash to private properties + THIS = {}; /** - * The MouseTracker allows other classes to set handlers for common mouse - * events on a specific element like, 'enter', 'exit', 'press', 'release', - * 'scroll', 'click', and 'drag'. - * @class - * @param {Object} options - * Allows configurable properties to be entirely specified by passing - * an options object to the constructor. The constructor also supports - * the original positional arguments 'elements', 'clickTimeThreshold', - * and 'clickDistThreshold' in that order. - * @param {Element|String} options.element - * A reference to an element or an element id for which the mouse - * events will be monitored. - * @param {Number} options.clickTimeThreshold - * The number of milliseconds within which mutliple mouse clicks - * will be treated as a single event. - * @param {Number} options.clickDistThreshold - * The distance between mouse click within multiple mouse clicks - * will be treated as a single event. - * @param {Function} options.enterHandler - * An optional handler for mouse enter. - * @param {Function} options.exitHandler - * An optional handler for mouse exit. - * @param {Function} options.pressHandler - * An optional handler for mouse press. - * @param {Function} options.releaseHandler - * An optional handler for mouse release. - * @param {Function} options.moveHandler - * An optional handler for mouse move. - * @param {Function} options.scrollHandler - * An optional handler for mouse scroll. - * @param {Function} options.clickHandler - * An optional handler for mouse click. - * @param {Function} options.dragHandler - * An optional handler for mouse drag. - * @param {Function} options.keyHandler - * An optional handler for keypress. - * @param {Function} options.focusHandler - * An optional handler for focus. - * @param {Function} options.blurHandler - * An optional handler for blur. - * @property {Number} hash - * An unique hash for this tracker. - * @property {Element} element - * The element for which mouse event are being monitored. - * @property {Number} clickTimeThreshold - * The number of milliseconds within which mutliple mouse clicks - * will be treated as a single event. - * @property {Number} clickDistThreshold - * The distance between mouse click within multiple mouse clicks - * will be treated as a single event. - * @property {Object} optional userData - * Arbitrary object to be passed unchanged to any attached handler methods. - */ + * The MouseTracker allows other classes to set handlers for common mouse + * events on a specific element like, 'enter', 'exit', 'press', 'release', + * 'scroll', 'click', and 'drag'. + * @class + * @param {Object} options + * Allows configurable properties to be entirely specified by passing + * an options object to the constructor. The constructor also supports + * the original positional arguments 'elements', 'clickTimeThreshold', + * and 'clickDistThreshold' in that order. + * @param {Element|String} options.element + * A reference to an element or an element id for which the mouse + * events will be monitored. + * @param {Number} options.clickTimeThreshold + * The number of milliseconds within which mutliple mouse clicks + * will be treated as a single event. + * @param {Number} options.clickDistThreshold + * The distance between mouse click within multiple mouse clicks + * will be treated as a single event. + * @param {Function} options.enterHandler + * An optional handler for mouse enter. + * @param {Function} options.exitHandler + * An optional handler for mouse exit. + * @param {Function} options.pressHandler + * An optional handler for mouse press. + * @param {Function} options.releaseHandler + * An optional handler for mouse release. + * @param {Function} options.moveHandler + * An optional handler for mouse move. + * @param {Function} options.scrollHandler + * An optional handler for mouse scroll. + * @param {Function} options.clickHandler + * An optional handler for mouse click. + * @param {Function} options.dragHandler + * An optional handler for mouse drag. + * @param {Function} options.keyHandler + * An optional handler for keypress. + * @param {Function} options.focusHandler + * An optional handler for focus. + * @param {Function} options.blurHandler + * An optional handler for blur. + * @property {Number} hash + * An unique hash for this tracker. + * @property {Element} element + * The element for which mouse event are being monitored. + * @property {Number} clickTimeThreshold + * The number of milliseconds within which mutliple mouse clicks + * will be treated as a single event. + * @property {Number} clickDistThreshold + * The distance between mouse click within multiple mouse clicks + * will be treated as a single event. + * @property {Object} optional userData + * Arbitrary object to be passed unchanged to any attached handler methods. + */ $.MouseTracker = function ( options ) { var args = arguments; if ( !$.isPlainObject( options ) ) { options = { - element: args[0], + element: args[0], clickTimeThreshold: args[1], clickDistThreshold: args[2] }; @@ -115,68 +115,68 @@ this.element = $.getElement( options.element ); this.clickTimeThreshold = options.clickTimeThreshold; this.clickDistThreshold = options.clickDistThreshold; - this.userData = options.userData || null; + this.userData = options.userData || null; - this.enterHandler = options.enterHandler || null; - this.exitHandler = options.exitHandler || null; - this.pressHandler = options.pressHandler || null; + this.enterHandler = options.enterHandler || null; + this.exitHandler = options.exitHandler || null; + this.pressHandler = options.pressHandler || null; this.releaseHandler = options.releaseHandler || null; - this.moveHandler = options.moveHandler || null; - this.scrollHandler = options.scrollHandler || null; - this.clickHandler = options.clickHandler || null; - this.dragHandler = options.dragHandler || null; - this.keyHandler = options.keyHandler || null; - this.focusHandler = options.focusHandler || null; - this.blurHandler = options.blurHandler || null; + this.moveHandler = options.moveHandler || null; + this.scrollHandler = options.scrollHandler || null; + this.clickHandler = options.clickHandler || null; + this.dragHandler = options.dragHandler || null; + this.keyHandler = options.keyHandler || null; + this.focusHandler = options.focusHandler || null; + this.blurHandler = options.blurHandler || null; //Store private properties in a scope sealed hash map var _this = this; /** - * @private - * @property {Boolean} tracking - * Are we currently tracking mouse events. - * @property {Boolean} capturing - * Are we curruently capturing mouse events. - * @property {Boolean} buttonDownElement - * True if the left mouse button is currently being pressed and was - * initiated inside the tracked element, otherwise false. - * @property {Boolean} insideElement - * Are we currently inside the screen area of the tracked element. - * @property {OpenSeadragon.Point} lastPoint - * Position of last mouse down/move - * @property {Number} lastMouseDownTime - * Time of last mouse down. - * @property {OpenSeadragon.Point} lastMouseDownPoint - * Position of last mouse down - */ + * @private + * @property {Boolean} tracking + * Are we currently tracking mouse events. + * @property {Boolean} capturing + * Are we curruently capturing mouse events. + * @property {Boolean} buttonDownElement + * True if the left mouse button is currently being pressed and was + * initiated inside the tracked element, otherwise false. + * @property {Boolean} insideElement + * Are we currently inside the screen area of the tracked element. + * @property {OpenSeadragon.Point} lastPoint + * Position of last mouse down/move + * @property {Number} lastMouseDownTime + * Time of last mouse down. + * @property {OpenSeadragon.Point} lastMouseDownPoint + * 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 ); }, - DOMMouseScroll: function ( event ) { onMouseWheelSpin( _this, event, false ); }, - mousewheel: function ( event ) { onMouseWheelSpin( _this, event, false ); }, - mouseupie: function ( event ) { onMouseUpIE( _this, event ); }, - mousemoveie: function ( event ) { onMouseMoveIE( _this, event ); }, - mouseupwindow: function ( event ) { onMouseUpWindow( _this, event ); }, - mousemovewindow: function ( event ) { onMouseMoveWindow( _this, event, false ); }, - 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, - buttonDownElement: false, - insideElement: false, - lastPoint: null, - lastMouseDownTime: null, + 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 ); }, + DOMMouseScroll: function ( event ) { onMouseWheelSpin( _this, event, false ); }, + mousewheel: function ( event ) { onMouseWheelSpin( _this, event, false ); }, + mouseupie: function ( event ) { onMouseUpIE( _this, event ); }, + mousemoveie: function ( event ) { onMouseMoveIE( _this, event ); }, + mouseupwindow: function ( event ) { onMouseUpWindow( _this, event ); }, + mousemovewindow: function ( event ) { onMouseMoveWindow( _this, event, false ); }, + 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, + buttonDownElement: false, + insideElement: false, + lastPoint: null, + lastMouseDownTime: null, lastMouseDownPoint: null, - lastPinchDelta: 0 + lastPinchDelta: 0 }; }; @@ -184,30 +184,30 @@ $.MouseTracker.prototype = { /** - * Clean up any events or objects created by the mouse tracker. - * @function - */ + * Clean up any events or objects created by the mouse tracker. + * @function + */ destroy: function () { stopTracking( this ); this.element = null; }, /** - * Are we currently tracking events on this element. - * @deprecated Just use this.tracking - * @function - * @returns {Boolean} Are we currently tracking events on this element. - */ + * Are we currently tracking events on this element. + * @deprecated Just use this.tracking + * @function + * @returns {Boolean} Are we currently tracking events on this element. + */ isTracking: function () { return THIS[this.hash].tracking; }, /** - * Enable or disable whether or not we are tracking events on this element. - * @function - * @param {Boolean} track True to start tracking, false to stop tracking. - * @returns {OpenSeadragon.MouseTracker} Chainable. - */ + * Enable or disable whether or not we are tracking events on this element. + * @function + * @param {Boolean} track True to start tracking, false to stop tracking. + * @returns {OpenSeadragon.MouseTracker} Chainable. + */ setTracking: function ( track ) { if ( track ) { startTracking( this ); @@ -219,198 +219,198 @@ }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * position: The position of the event relative to the tracked element. - * buttonDownElement: True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false. - * buttonDownAny: Was the button down anywhere in the screen during the event. - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * position: The position of the event relative to the tracked element. + * buttonDownElement: True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false. + * buttonDownAny: Was the button down anywhere in the screen during the event. + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ enterHandler: function () { }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * position: The position of the event relative to the tracked element. - * buttonDownElement: True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false. - * buttonDownAny: Was the button down anywhere in the screen during the event. - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * position: The position of the event relative to the tracked element. + * buttonDownElement: True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false. + * buttonDownAny: Was the button down anywhere in the screen during the event. + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ exitHandler: function () { }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * position: The position of the event relative to the tracked element. - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * position: The position of the event relative to the tracked element. + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ pressHandler: function () { }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * position: The position of the event relative to the tracked element. - * insideElementPress: True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false. - * insideElementRelease: Was the mouse still inside the tracked element when the button was released. - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * position: The position of the event relative to the tracked element. + * insideElementPress: True if the left mouse button is currently being pressed and was initiated inside the tracked element, otherwise false. + * insideElementRelease: Was the mouse still inside the tracked element when the button was released. + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ releaseHandler: function () { }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * position: The position of the event relative to the tracked element. - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * position: The position of the event relative to the tracked element. + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ moveHandler: function () { }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * position: The position of the event relative to the tracked element. - * scroll: The scroll delta for the event. - * shift: Was the shift key being pressed during this event? - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * position: The position of the event relative to the tracked element. + * scroll: The scroll delta for the event. + * shift: Was the shift key being pressed during this event? + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ scrollHandler: function () { }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * position: The position of the event relative to the tracked element. - * quick: True only if the clickDistThreshold and clickDeltaThreshold are both pased. Useful for ignoring events. - * shift: Was the shift key being pressed during this event? - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * position: The position of the event relative to the tracked element. + * quick: True only if the clickDistThreshold and clickDeltaThreshold are both pased. Useful for ignoring events. + * shift: Was the shift key being pressed during this event? + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ clickHandler: function () { }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * position: The position of the event relative to the tracked element. - * delta: The x,y components of the difference between start drag and end drag. Usefule for ignoring or weighting the events. - * shift: Was the shift key being pressed during this event? - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * position: The position of the event relative to the tracked element. + * delta: The x,y components of the difference between start drag and end drag. Usefule for ignoring or weighting the events. + * shift: Was the shift key being pressed during this event? + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ dragHandler: function () { }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * keyCode: The key code that was pressed. - * shift: Was the shift key being pressed during this event? - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * keyCode: The key code that was pressed. + * shift: Was the shift key being pressed during this event? + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ keyHandler: function () { }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ focusHandler: function () { }, /** - * Implement or assign implmentation to these handlers during or after - * calling the constructor. - * @function - * @param {OpenSeadragon.MouseTracker} tracker - * A reference to the tracker instance. - * @param {Object} eventData - * { - * isTouchEvent: True if the original event is a touch event, otherwise false. - * originalEvent: The original event object. - * userData: Arbitrary user-defined object. - * } - */ + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * { + * isTouchEvent: True if the original event is a touch event, otherwise false. + * originalEvent: The original event object. + * userData: Arbitrary user-defined object. + * } + */ blurHandler: function () { } }; /** - * Starts tracking mouse events on this element. - * @private - * @inner - */ + * Starts tracking mouse events on this element. + * @private + * @inner + */ function startTracking( tracker ) { var events = [ "mouseover", "mouseout", "mousedown", "mouseup", "mousemove", @@ -440,10 +440,10 @@ } /** - * Stops tracking mouse events on this element. - * @private - * @inner - */ + * Stops tracking mouse events on this element. + * @private + * @inner + */ function stopTracking( tracker ) { var events = [ "mouseover", "mouseout", "mousedown", "mouseup", "mousemove", @@ -475,18 +475,18 @@ } /** - * @private - * @inner - */ + * @private + * @inner + */ function hasMouse( tracker ) { return THIS[tracker.hash].insideElement; } /** - * Begin capturing mouse events on this element. - * @private - * @inner - */ + * Begin capturing mouse events on this element. + * @private + * @inner + */ function captureMouse( tracker ) { var delegate = THIS[tracker.hash]; if ( !delegate.capturing ) { @@ -530,10 +530,10 @@ /** - * Stop capturing mouse events on this element. - * @private - * @inner - */ + * Stop capturing mouse events on this element. + * @private + * @inner + */ function releaseMouse( tracker ) { var delegate = THIS[tracker.hash]; if ( delegate.capturing ) { @@ -577,9 +577,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function triggerOthers( tracker, handler, event, isTouch ) { var otherHash; for ( otherHash in ACTIVE ) { @@ -591,9 +591,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onFocus( tracker, event ) { //console.log( "focus %s", event ); var propagate; @@ -614,9 +614,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onBlur( tracker, event ) { //console.log( "blur %s", event ); var propagate; @@ -637,9 +637,9 @@ /** - * @private - * @inner - */ + * @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; @@ -663,9 +663,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onMouseOver( tracker, event, isTouch ) { var delegate = THIS[tracker.hash], @@ -717,9 +717,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onMouseOut( tracker, event, isTouch ) { var delegate = THIS[tracker.hash], propagate; @@ -772,9 +772,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onMouseDown( tracker, event, noCapture, isTouch ) { var delegate = THIS[tracker.hash], propagate; @@ -829,9 +829,9 @@ } /** - * @private - * @inner - */ + * @private + * @inner + */ function onTouchStart( tracker, event ) { var touchA, touchB; @@ -866,9 +866,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onMouseUp( tracker, event, isTouch ) { var delegate = THIS[tracker.hash], //were we inside the tracked element when we were pressed @@ -911,9 +911,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onTouchEnd( tracker, event ) { if ( event.touches.length === 0 && @@ -937,15 +937,15 @@ /** - * 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 - */ + * 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; @@ -975,14 +975,14 @@ /** - * 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 - */ + * 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 onMouseUpWindow( tracker, event, noRelease ) { if ( !THIS[tracker.hash].insideElement ) { onMouseUp( tracker, event, false ); @@ -997,9 +997,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onMouseMove( tracker, event ) { if ( tracker.moveHandler ) { event = $.getEvent( event ); @@ -1021,9 +1021,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onMouseClick( tracker, event ) { if ( tracker.clickHandler ) { $.cancelEvent( event ); @@ -1032,9 +1032,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onMouseWheelSpin( tracker, event, isTouch ) { var nDelta = 0, propagate; @@ -1078,9 +1078,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function handleMouseClick( tracker, event ) { var delegate = THIS[tracker.hash], propagate; @@ -1117,9 +1117,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onMouseMoveWindow( tracker, event, isTouch ) { var delegate = THIS[tracker.hash], delta, @@ -1154,9 +1154,9 @@ /** - * @private - * @inner - */ + * @private + * @inner + */ function onTouchMove( tracker, event ) { var touchA, touchB, @@ -1202,14 +1202,14 @@ } /** - * 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 - */ + * 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 onMouseMoveIE( tracker, event ) { var i; for ( i = 0; i < CAPTURING.length; i++ ) { @@ -1220,17 +1220,17 @@ } /** - * @private - * @inner - */ + * @private + * @inner + */ function getMouseAbsolute( event ) { return $.getMousePosition( event ); } /** - * @private - * @inner - */ + * @private + * @inner + */ function getMouseRelative( event, element ) { var mouse = $.getMousePosition( event ), offset = $.getElementOffset( element ); @@ -1239,10 +1239,10 @@ } /** - * @private - * @inner - * Returns true if elementB is a child node of elementA, or if they're equal. - */ + * @private + * @inner + * Returns true if elementB is a child node of elementA, or if they're equal. + */ function isChild( elementA, elementB ) { var body = document.body; while ( elementB && elementA != elementB && body != elementB ) { @@ -1256,17 +1256,17 @@ } /** - * @private - * @inner - */ + * @private + * @inner + */ function onGlobalMouseDown() { IS_BUTTON_DOWN = true; } /** - * @private - * @inner - */ + * @private + * @inner + */ function onGlobalMouseUp() { IS_BUTTON_DOWN = false; } diff --git a/src/openseadragon.js b/src/openseadragon.js index 6da43be9..b28cc507 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -705,7 +705,6 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ * @name OpenSeadragon.getElementOffset * @param {Element|String} element - the element we want the position for. * @returns {Point} - the position of the upper left corner of the element adjusted for current page and/or element scroll. - * Inspired by jQuery.fn.offset() (jquery 1.10.1) */ getElementOffset: function( element ) { var doc = element && element.ownerDocument, @@ -719,11 +718,6 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ docElement = doc.documentElement; - // Make sure it's not a disconnected DOM node - //if ( !jQuery.contains( docElement, element ) ) { - // return new $.Point(); - //} - if ( typeof element.getBoundingClientRect !== typeof undefined ) { boundingRect = element.getBoundingClientRect(); } diff --git a/src/referencestrip.js b/src/referencestrip.js index f822e98a..d6a2e7b0 100644 --- a/src/referencestrip.js +++ b/src/referencestrip.js @@ -34,508 +34,508 @@ (function ( $ ) { - // dictionary from id to private properties - var THIS = {}; +// dictionary from id to private properties +var THIS = {}; - /** - * The CollectionDrawer is a reimplementation if the Drawer API that - * focuses on allowing a viewport to be redefined as a collection - * of smaller viewports, defined by a clear number of rows and / or - * columns of which each item in the matrix of viewports has its own - * source. - * - * This idea is a reexpression of the idea of dzi collections - * which allows a clearer algorithm to reuse the tile sources already - * supported by OpenSeadragon, in heterogenious or homogenious - * sequences just like mixed groups already supported by the viewer - * for the purpose of image sequnces. - * - * TODO: The difficult part of this feature is figuring out how to express - * this functionality as a combination of the functionality already - * provided by Drawer, Viewport, TileSource, and Navigator. It may - * require better abstraction at those points in order to effeciently - * reuse those paradigms. - */ - $.ReferenceStrip = function ( options ) { +/** + * The CollectionDrawer is a reimplementation if the Drawer API that + * focuses on allowing a viewport to be redefined as a collection + * of smaller viewports, defined by a clear number of rows and / or + * columns of which each item in the matrix of viewports has its own + * source. + * + * This idea is a reexpression of the idea of dzi collections + * which allows a clearer algorithm to reuse the tile sources already + * supported by OpenSeadragon, in heterogenious or homogenious + * sequences just like mixed groups already supported by the viewer + * for the purpose of image sequnces. + * + * TODO: The difficult part of this feature is figuring out how to express + * this functionality as a combination of the functionality already + * provided by Drawer, Viewport, TileSource, and Navigator. It may + * require better abstraction at those points in order to effeciently + * reuse those paradigms. + */ +$.ReferenceStrip = function ( options ) { - var _this = this, - viewer = options.viewer, - viewerSize = $.getElementSize( viewer.element ), - element, - style, - i; + var _this = this, + viewer = options.viewer, + viewerSize = $.getElementSize( viewer.element ), + element, + style, + i; - //We may need to create a new element and id if they did not - //provide the id for the existing element - if ( !options.id ) { - options.id = 'referencestrip-' + $.now(); - this.element = $.makeNeutralElement( "div" ); - this.element.id = options.id; - this.element.className = 'referencestrip'; - } + //We may need to create a new element and id if they did not + //provide the id for the existing element + if ( !options.id ) { + options.id = 'referencestrip-' + $.now(); + this.element = $.makeNeutralElement( "div" ); + this.element.id = options.id; + this.element.className = 'referencestrip'; + } - options = $.extend( true, { - sizeRatio: $.DEFAULT_SETTINGS.referenceStripSizeRatio, - position: $.DEFAULT_SETTINGS.referenceStripPosition, - scroll: $.DEFAULT_SETTINGS.referenceStripScroll, - clickTimeThreshold: $.DEFAULT_SETTINGS.clickTimeThreshold - }, options, { - //required overrides - element: this.element, - //These need to be overridden to prevent recursion since - //the navigator is a viewer and a viewer has a navigator - showNavigator: false, - mouseNavEnabled: false, - showNavigationControl: false, - showSequenceControl: false - } ); + options = $.extend( true, { + sizeRatio: $.DEFAULT_SETTINGS.referenceStripSizeRatio, + position: $.DEFAULT_SETTINGS.referenceStripPosition, + scroll: $.DEFAULT_SETTINGS.referenceStripScroll, + clickTimeThreshold: $.DEFAULT_SETTINGS.clickTimeThreshold + }, options, { + //required overrides + element: this.element, + //These need to be overridden to prevent recursion since + //the navigator is a viewer and a viewer has a navigator + showNavigator: false, + mouseNavEnabled: false, + showNavigationControl: false, + showSequenceControl: false + } ); - $.extend( this, options ); - //Private state properties - THIS[this.id] = { - "animating": false - }; + $.extend( this, options ); + //Private state properties + THIS[this.id] = { + "animating": false + }; - this.minPixelRatio = this.viewer.minPixelRatio; + this.minPixelRatio = this.viewer.minPixelRatio; - style = this.element.style; - style.marginTop = '0px'; - style.marginRight = '0px'; - style.marginBottom = '0px'; - style.marginLeft = '0px'; - style.left = '0px'; - style.bottom = '0px'; - style.border = '0px'; - style.background = '#000'; - style.position = 'relative'; + style = this.element.style; + style.marginTop = '0px'; + style.marginRight = '0px'; + style.marginBottom = '0px'; + style.marginLeft = '0px'; + style.left = '0px'; + style.bottom = '0px'; + style.border = '0px'; + style.background = '#000'; + style.position = 'relative'; - $.setElementOpacity( this.element, 0.8 ); + $.setElementOpacity( this.element, 0.8 ); - this.viewer = viewer; - this.innerTracker = new $.MouseTracker( { - element: this.element, - dragHandler: $.delegate( this, onStripDrag ), - scrollHandler: $.delegate( this, onStripScroll ), - enterHandler: $.delegate( this, onStripEnter ), - exitHandler: $.delegate( this, onStripExit ), - keyHandler: $.delegate( this, onKeyPress ) - } ).setTracking( true ); + this.viewer = viewer; + this.innerTracker = new $.MouseTracker( { + element: this.element, + dragHandler: $.delegate( this, onStripDrag ), + scrollHandler: $.delegate( this, onStripScroll ), + enterHandler: $.delegate( this, onStripEnter ), + exitHandler: $.delegate( this, onStripExit ), + keyHandler: $.delegate( this, onKeyPress ) + } ).setTracking( true ); + + //Controls the position and orientation of the reference strip and sets the + //appropriate width and height + if ( options.width && options.height ) { + this.element.style.width = options.width + 'px'; + this.element.style.height = options.height + 'px'; + viewer.addControl( + this.element, + { anchor: $.ControlAnchor.BOTTOM_LEFT } + ); + } else { + if ( "horizontal" == options.scroll ) { + this.element.style.width = ( + viewerSize.x * + options.sizeRatio * + viewer.tileSources.length + ) + ( 12 * viewer.tileSources.length ) + 'px'; + + this.element.style.height = ( + viewerSize.y * + options.sizeRatio + ) + 'px'; - //Controls the position and orientation of the reference strip and sets the - //appropriate width and height - if ( options.width && options.height ) { - this.element.style.width = options.width + 'px'; - this.element.style.height = options.height + 'px'; viewer.addControl( this.element, { anchor: $.ControlAnchor.BOTTOM_LEFT } ); } else { - if ( "horizontal" == options.scroll ) { - this.element.style.width = ( - viewerSize.x * - options.sizeRatio * - viewer.tileSources.length - ) + ( 12 * viewer.tileSources.length ) + 'px'; + this.element.style.height = ( + viewerSize.y * + options.sizeRatio * + viewer.tileSources.length + ) + ( 12 * viewer.tileSources.length ) + 'px'; - this.element.style.height = ( - viewerSize.y * - options.sizeRatio - ) + 'px'; + this.element.style.width = ( + viewerSize.x * + options.sizeRatio + ) + 'px'; - viewer.addControl( - this.element, - { anchor: $.ControlAnchor.BOTTOM_LEFT } - ); + viewer.addControl( + this.element, + { anchor: $.ControlAnchor.TOP_LEFT } + ); + + } + } + + this.panelWidth = ( viewerSize.x * this.sizeRatio ) + 8; + this.panelHeight = ( viewerSize.y * this.sizeRatio ) + 8; + this.panels = []; + + /*jshint loopfunc:true*/ + for ( i = 0; i < viewer.tileSources.length; i++ ) { + + element = $.makeNeutralElement( 'div' ); + element.id = this.element.id + "-" + i; + + element.style.width = _this.panelWidth + 'px'; + element.style.height = _this.panelHeight + 'px'; + element.style.display = 'inline'; + element.style.float = 'left'; //Webkit + element.style.cssFloat = 'left'; //Firefox + element.style.styleFloat = 'left'; //IE + element.style.padding = '2px'; + + element.innerTracker = new $.MouseTracker( { + element: element, + clickTimeThreshold: this.clickTimeThreshold, + clickDistThreshold: this.clickDistThreshold, + pressHandler: function ( tracker, eventData ) { + tracker.dragging = $.now(); + }, + releaseHandler: function ( tracker, eventData ) { + var id = tracker.element.id, + page = Number( id.split( '-' )[2] ), + now = $.now(); + + if ( eventData.insideElementPress && + eventData.insideElementRelease && + tracker.dragging && + ( now - tracker.dragging ) < tracker.clickTimeThreshold ) { + tracker.dragging = null; + viewer.goToPage( page ); + } + } + } ).setTracking( true ); + + this.element.appendChild( element ); + + element.activePanel = false; + + this.panels.push( element ); + + } + loadPanels( this, this.scroll == 'vertical' ? viewerSize.y : viewerSize.y, 0 ); + this.setFocus( 0 ); + +}; + +$.extend( $.ReferenceStrip.prototype, $.EventHandler.prototype, $.Viewer.prototype, { + + setFocus: function ( page ) { + var element = $.getElement( this.element.id + '-' + page ), + viewerSize = $.getElementSize( this.viewer.canvas ), + scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ), + scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ), + offsetLeft = -Number( this.element.style.marginLeft.replace( 'px', '' ) ), + offsetTop = -Number( this.element.style.marginTop.replace( 'px', '' ) ), + offset; + + if ( this.currentSelected !== element ) { + if ( this.currentSelected ) { + this.currentSelected.style.background = '#000'; + } + this.currentSelected = element; + this.currentSelected.style.background = '#999'; + + if ( 'horizontal' == this.scroll ) { + //right left + offset = ( Number( page ) ) * ( this.panelWidth + 3 ); + if ( offset > offsetLeft + viewerSize.x - this.panelWidth ) { + offset = Math.min( offset, ( scrollWidth - viewerSize.x ) ); + this.element.style.marginLeft = -offset + 'px'; + loadPanels( this, viewerSize.x, -offset ); + } else if ( offset < offsetLeft ) { + offset = Math.max( 0, offset - viewerSize.x / 2 ); + this.element.style.marginLeft = -offset + 'px'; + loadPanels( this, viewerSize.x, -offset ); + } } else { - this.element.style.height = ( - viewerSize.y * - options.sizeRatio * - viewer.tileSources.length - ) + ( 12 * viewer.tileSources.length ) + 'px'; + offset = ( Number( page ) ) * ( this.panelHeight + 3 ); + if ( offset > offsetTop + viewerSize.y - this.panelHeight ) { + offset = Math.min( offset, ( scrollHeight - viewerSize.y ) ); + this.element.style.marginTop = -offset + 'px'; + loadPanels( this, viewerSize.y, -offset ); + } else if ( offset < offsetTop ) { + offset = Math.max( 0, offset - viewerSize.y / 2 ); + this.element.style.marginTop = -offset + 'px'; + loadPanels( this, viewerSize.y, -offset ); + } + } - this.element.style.width = ( - viewerSize.x * - options.sizeRatio - ) + 'px'; + this.currentPage = page; + $.getElement( element.id + '-displayregion' ).focus(); + onStripEnter.call( this, this.innerTracker, {} ); + } + }, + /** + * @function + * @name OpenSeadragon.ReferenceStrip.prototype.update + */ + update: function () { + if ( THIS[this.id].animating ) { + $.console.log( 'image reference strip update' ); + return true; + } + return false; + } - viewer.addControl( - this.element, - { anchor: $.ControlAnchor.TOP_LEFT } - ); +} ); + + + +/** + * @private + * @inner + * @function + */ +function onStripDrag( tracker, eventData ) { + + var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ), + offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ), + scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ), + scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ), + viewerSize = $.getElementSize( this.viewer.canvas ); + this.dragging = true; + if ( this.element ) { + if ( 'horizontal' == this.scroll ) { + if ( -eventData.delta.x > 0 ) { + //forward + if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) { + this.element.style.marginLeft = ( offsetLeft + ( eventData.delta.x * 2 ) ) + 'px'; + loadPanels( this, viewerSize.x, offsetLeft + ( eventData.delta.x * 2 ) ); + } + } else if ( -eventData.delta.x < 0 ) { + //reverse + if ( offsetLeft < 0 ) { + this.element.style.marginLeft = ( offsetLeft + ( eventData.delta.x * 2 ) ) + 'px'; + loadPanels( this, viewerSize.x, offsetLeft + ( eventData.delta.x * 2 ) ); + } + } + } else { + if ( -eventData.delta.y > 0 ) { + //forward + if ( offsetTop > -( scrollHeight - viewerSize.y ) ) { + this.element.style.marginTop = ( offsetTop + ( eventData.delta.y * 2 ) ) + 'px'; + loadPanels( this, viewerSize.y, offsetTop + ( eventData.delta.y * 2 ) ); + } + } else if ( -eventData.delta.y < 0 ) { + //reverse + if ( offsetTop < 0 ) { + this.element.style.marginTop = ( offsetTop + ( eventData.delta.y * 2 ) ) + 'px'; + loadPanels( this, viewerSize.y, offsetTop + ( eventData.delta.y * 2 ) ); + } } } + } + return false; - this.panelWidth = ( viewerSize.x * this.sizeRatio ) + 8; - this.panelHeight = ( viewerSize.y * this.sizeRatio ) + 8; - this.panels = []; +} - /*jshint loopfunc:true*/ - for ( i = 0; i < viewer.tileSources.length; i++ ) { - element = $.makeNeutralElement( 'div' ); - element.id = this.element.id + "-" + i; - element.style.width = _this.panelWidth + 'px'; - element.style.height = _this.panelHeight + 'px'; - element.style.display = 'inline'; - element.style.float = 'left'; //Webkit - element.style.cssFloat = 'left'; //Firefox - element.style.styleFloat = 'left'; //IE - element.style.padding = '2px'; +/** + * @private + * @inner + * @function + */ +function onStripScroll( tracker, eventData ) { + var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ), + offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ), + scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ), + scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ), + viewerSize = $.getElementSize( this.viewer.canvas ); + if ( this.element ) { + if ( 'horizontal' == this.scroll ) { + if ( eventData.scroll > 0 ) { + //forward + if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) { + this.element.style.marginLeft = ( offsetLeft - ( eventData.scroll * 60 ) ) + 'px'; + loadPanels( this, viewerSize.x, offsetLeft - ( eventData.scroll * 60 ) ); + } + } else if ( eventData.scroll < 0 ) { + //reverse + if ( offsetLeft < 0 ) { + this.element.style.marginLeft = ( offsetLeft - ( eventData.scroll * 60 ) ) + 'px'; + loadPanels( this, viewerSize.x, offsetLeft - ( eventData.scroll * 60 ) ); + } + } + } else { + if ( eventData.scroll < 0 ) { + //scroll up + if ( offsetTop > viewerSize.y - scrollHeight ) { + this.element.style.marginTop = ( offsetTop + ( eventData.scroll * 60 ) ) + 'px'; + loadPanels( this, viewerSize.y, offsetTop + ( eventData.scroll * 60 ) ); + } + } else if ( eventData.scroll > 0 ) { + //scroll dowm + if ( offsetTop < 0 ) { + this.element.style.marginTop = ( offsetTop + ( eventData.scroll * 60 ) ) + 'px'; + loadPanels( this, viewerSize.y, offsetTop + ( eventData.scroll * 60 ) ); + } + } + } + } + //cancels event + return false; +} - element.innerTracker = new $.MouseTracker( { + +function loadPanels( strip, viewerSize, scroll ) { + var panelSize, + activePanelsStart, + activePanelsEnd, + miniViewer, + style, + i, + element; + if ( 'horizontal' == strip.scroll ) { + panelSize = strip.panelWidth; + } else { + panelSize = strip.panelHeight; + } + activePanelsStart = Math.ceil( viewerSize / panelSize ) + 5; + activePanelsEnd = Math.ceil( ( Math.abs( scroll ) + viewerSize ) / panelSize ) + 1; + activePanelsStart = activePanelsEnd - activePanelsStart; + activePanelsStart = activePanelsStart < 0 ? 0 : activePanelsStart; + + for ( i = activePanelsStart; i < activePanelsEnd && i < strip.panels.length; i++ ) { + element = strip.panels[i]; + if ( !element.activePanel ) { + miniViewer = new $.Viewer( { + id: element.id, + tileSources: [strip.viewer.tileSources[i]], element: element, - clickTimeThreshold: this.clickTimeThreshold, - clickDistThreshold: this.clickDistThreshold, - pressHandler: function ( tracker, eventData ) { - tracker.dragging = $.now(); - }, - releaseHandler: function ( tracker, eventData ) { - var id = tracker.element.id, - page = Number( id.split( '-' )[2] ), - now = $.now(); + navigatorSizeRatio: strip.sizeRatio, + showNavigator: false, + mouseNavEnabled: false, + showNavigationControl: false, + showSequenceControl: false, + immediateRender: true, + blendTime: 0, + animationTime: 0 + } ); - if ( eventData.insideElementPress && - eventData.insideElementRelease && - tracker.dragging && - ( now - tracker.dragging ) < tracker.clickTimeThreshold ) { - tracker.dragging = null; - viewer.goToPage( page ); - } - } - } ).setTracking( true ); + miniViewer.displayRegion = $.makeNeutralElement( "textarea" ); + miniViewer.displayRegion.id = element.id + '-displayregion'; + miniViewer.displayRegion.className = 'displayregion'; - this.element.appendChild( element ); + style = miniViewer.displayRegion.style; + style.position = 'relative'; + style.top = '0px'; + style.left = '0px'; + style.fontSize = '0px'; + style.overflow = 'hidden'; + style.float = 'left'; //Webkit + style.cssFloat = 'left'; //Firefox + style.styleFloat = 'left'; //IE + style.zIndex = 999999999; + style.cursor = 'default'; + style.width = ( strip.panelWidth - 4 ) + 'px'; + style.height = ( strip.panelHeight - 4 ) + 'px'; - element.activePanel = false; + miniViewer.displayRegion.innerTracker = new $.MouseTracker( { + element: miniViewer.displayRegion + } ); - this.panels.push( element ); + element.getElementsByTagName( 'form' )[0].appendChild( + miniViewer.displayRegion + ); + element.activePanel = true; } - loadPanels( this, this.scroll == 'vertical' ? viewerSize.y : viewerSize.y, 0 ); - this.setFocus( 0 ); + } +} - }; - $.extend( $.ReferenceStrip.prototype, $.EventHandler.prototype, $.Viewer.prototype, { +/** + * @private + * @inner + * @function + */ +function onStripEnter( tracker, eventData ) { - setFocus: function ( page ) { - var element = $.getElement( this.element.id + '-' + page ), - viewerSize = $.getElementSize( this.viewer.canvas ), - scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ), - scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ), - offsetLeft = -Number( this.element.style.marginLeft.replace( 'px', '' ) ), - offsetTop = -Number( this.element.style.marginTop.replace( 'px', '' ) ), - offset; + //$.setElementOpacity(tracker.element, 0.8); - if ( this.currentSelected !== element ) { - if ( this.currentSelected ) { - this.currentSelected.style.background = '#000'; - } - this.currentSelected = element; - this.currentSelected.style.background = '#999'; + //tracker.element.style.border = '1px solid #555'; + //tracker.element.style.background = '#000'; - if ( 'horizontal' == this.scroll ) { - //right left - offset = ( Number( page ) ) * ( this.panelWidth + 3 ); - if ( offset > offsetLeft + viewerSize.x - this.panelWidth ) { - offset = Math.min( offset, ( scrollWidth - viewerSize.x ) ); - this.element.style.marginLeft = -offset + 'px'; - loadPanels( this, viewerSize.x, -offset ); - } else if ( offset < offsetLeft ) { - offset = Math.max( 0, offset - viewerSize.x / 2 ); - this.element.style.marginLeft = -offset + 'px'; - loadPanels( this, viewerSize.x, -offset ); - } - } else { - offset = ( Number( page ) ) * ( this.panelHeight + 3 ); - if ( offset > offsetTop + viewerSize.y - this.panelHeight ) { - offset = Math.min( offset, ( scrollHeight - viewerSize.y ) ); - this.element.style.marginTop = -offset + 'px'; - loadPanels( this, viewerSize.y, -offset ); - } else if ( offset < offsetTop ) { - offset = Math.max( 0, offset - viewerSize.y / 2 ); - this.element.style.marginTop = -offset + 'px'; - loadPanels( this, viewerSize.y, -offset ); - } - } + if ( 'horizontal' == this.scroll ) { - this.currentPage = page; - $.getElement( element.id + '-displayregion' ).focus(); - onStripEnter.call( this, this.innerTracker, {} ); - } - }, - /** - * @function - * @name OpenSeadragon.ReferenceStrip.prototype.update - */ - update: function () { - if ( THIS[this.id].animating ) { - $.console.log( 'image reference strip update' ); - return true; - } + //tracker.element.style.paddingTop = "0px"; + tracker.element.style.marginBottom = "0px"; + + } else { + + //tracker.element.style.paddingRight = "0px"; + tracker.element.style.marginLeft = "0px"; + + } + return false; +} + + +/** + * @private + * @inner + * @function + */ +function onStripExit( tracker, eventData ) { + if ( 'horizontal' == this.scroll ) { + + //tracker.element.style.paddingTop = "10px"; + tracker.element.style.marginBottom = "-" + ( $.getElementSize( tracker.element ).y / 2 ) + "px"; + + } else { + + //tracker.element.style.paddingRight = "10px"; + tracker.element.style.marginLeft = "-" + ( $.getElementSize( tracker.element ).x / 2 ) + "px"; + + } + return false; +} + + + +/** + * @private + * @inner + * @function + */ +function onKeyPress( tracker, eventData ) { + //console.log( eventData.keyCode ); + + switch ( eventData.keyCode ) { + case 61: //=|+ + onStripScroll.call( this, this.tracker, { position: null, scroll: 1, shift: null } ); return false; - } - - } ); - - - - - /** - * @private - * @inner - * @function - */ - function onStripDrag( tracker, eventData ) { - - var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ), - offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ), - scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ), - scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ), - viewerSize = $.getElementSize( this.viewer.canvas ); - this.dragging = true; - if ( this.element ) { - if ( 'horizontal' == this.scroll ) { - if ( -eventData.delta.x > 0 ) { - //forward - if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) { - this.element.style.marginLeft = ( offsetLeft + ( eventData.delta.x * 2 ) ) + 'px'; - loadPanels( this, viewerSize.x, offsetLeft + ( eventData.delta.x * 2 ) ); - } - } else if ( -eventData.delta.x < 0 ) { - //reverse - if ( offsetLeft < 0 ) { - this.element.style.marginLeft = ( offsetLeft + ( eventData.delta.x * 2 ) ) + 'px'; - loadPanels( this, viewerSize.x, offsetLeft + ( eventData.delta.x * 2 ) ); - } - } - } else { - if ( -eventData.delta.y > 0 ) { - //forward - if ( offsetTop > -( scrollHeight - viewerSize.y ) ) { - this.element.style.marginTop = ( offsetTop + ( eventData.delta.y * 2 ) ) + 'px'; - loadPanels( this, viewerSize.y, offsetTop + ( eventData.delta.y * 2 ) ); - } - } else if ( -eventData.delta.y < 0 ) { - //reverse - if ( offsetTop < 0 ) { - this.element.style.marginTop = ( offsetTop + ( eventData.delta.y * 2 ) ) + 'px'; - loadPanels( this, viewerSize.y, offsetTop + ( eventData.delta.y * 2 ) ); - } - } - } - } - return false; - - } - - - - /** - * @private - * @inner - * @function - */ - function onStripScroll( tracker, eventData ) { - var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ), - offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ), - scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ), - scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ), - viewerSize = $.getElementSize( this.viewer.canvas ); - if ( this.element ) { - if ( 'horizontal' == this.scroll ) { - if ( eventData.scroll > 0 ) { - //forward - if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) { - this.element.style.marginLeft = ( offsetLeft - ( eventData.scroll * 60 ) ) + 'px'; - loadPanels( this, viewerSize.x, offsetLeft - ( eventData.scroll * 60 ) ); - } - } else if ( eventData.scroll < 0 ) { - //reverse - if ( offsetLeft < 0 ) { - this.element.style.marginLeft = ( offsetLeft - ( eventData.scroll * 60 ) ) + 'px'; - loadPanels( this, viewerSize.x, offsetLeft - ( eventData.scroll * 60 ) ); - } - } - } else { - if ( eventData.scroll < 0 ) { - //scroll up - if ( offsetTop > viewerSize.y - scrollHeight ) { - this.element.style.marginTop = ( offsetTop + ( eventData.scroll * 60 ) ) + 'px'; - loadPanels( this, viewerSize.y, offsetTop + ( eventData.scroll * 60 ) ); - } - } else if ( eventData.scroll > 0 ) { - //scroll dowm - if ( offsetTop < 0 ) { - this.element.style.marginTop = ( offsetTop + ( eventData.scroll * 60 ) ) + 'px'; - loadPanels( this, viewerSize.y, offsetTop + ( eventData.scroll * 60 ) ); - } - } - } - } - //cancels event - return false; - } - - - function loadPanels( strip, viewerSize, scroll ) { - var panelSize, - activePanelsStart, - activePanelsEnd, - miniViewer, - style, - i, - element; - if ( 'horizontal' == strip.scroll ) { - panelSize = strip.panelWidth; - } else { - panelSize = strip.panelHeight; - } - activePanelsStart = Math.ceil( viewerSize / panelSize ) + 5; - activePanelsEnd = Math.ceil( ( Math.abs( scroll ) + viewerSize ) / panelSize ) + 1; - activePanelsStart = activePanelsEnd - activePanelsStart; - activePanelsStart = activePanelsStart < 0 ? 0 : activePanelsStart; - - for ( i = activePanelsStart; i < activePanelsEnd && i < strip.panels.length; i++ ) { - element = strip.panels[i]; - if ( !element.activePanel ) { - miniViewer = new $.Viewer( { - id: element.id, - tileSources: [strip.viewer.tileSources[i]], - element: element, - navigatorSizeRatio: strip.sizeRatio, - showNavigator: false, - mouseNavEnabled: false, - showNavigationControl: false, - showSequenceControl: false, - immediateRender: true, - blendTime: 0, - animationTime: 0 - } ); - - miniViewer.displayRegion = $.makeNeutralElement( "textarea" ); - miniViewer.displayRegion.id = element.id + '-displayregion'; - miniViewer.displayRegion.className = 'displayregion'; - - style = miniViewer.displayRegion.style; - style.position = 'relative'; - style.top = '0px'; - style.left = '0px'; - style.fontSize = '0px'; - style.overflow = 'hidden'; - style.float = 'left'; //Webkit - style.cssFloat = 'left'; //Firefox - style.styleFloat = 'left'; //IE - style.zIndex = 999999999; - style.cursor = 'default'; - style.width = ( strip.panelWidth - 4 ) + 'px'; - style.height = ( strip.panelHeight - 4 ) + 'px'; - - miniViewer.displayRegion.innerTracker = new $.MouseTracker( { - element: miniViewer.displayRegion - } ); - - element.getElementsByTagName( 'form' )[0].appendChild( - miniViewer.displayRegion - ); - - element.activePanel = true; - } - } - } - - - /** - * @private - * @inner - * @function - */ - function onStripEnter( tracker, eventData ) { - - //$.setElementOpacity(tracker.element, 0.8); - - //tracker.element.style.border = '1px solid #555'; - //tracker.element.style.background = '#000'; - - if ( 'horizontal' == this.scroll ) { - - //tracker.element.style.paddingTop = "0px"; - tracker.element.style.marginBottom = "0px"; - - } else { - - //tracker.element.style.paddingRight = "0px"; - tracker.element.style.marginLeft = "0px"; - - } - return false; - } - - - /** - * @private - * @inner - * @function - */ - function onStripExit( tracker, eventData ) { - if ( 'horizontal' == this.scroll ) { - - //tracker.element.style.paddingTop = "10px"; - tracker.element.style.marginBottom = "-" + ( $.getElementSize( tracker.element ).y / 2 ) + "px"; - - } else { - - //tracker.element.style.paddingRight = "10px"; - tracker.element.style.marginLeft = "-" + ( $.getElementSize( tracker.element ).x / 2 ) + "px"; - - } - return false; - } - - - - /** - * @private - * @inner - * @function - */ - function onKeyPress( tracker, eventData ) { - //console.log( eventData.keyCode ); - - switch ( eventData.keyCode ) { - case 61: //=|+ - onStripScroll.call( this, this.tracker, { position: null, scroll: 1, shift: null } ); - return false; - case 45: //-|_ - onStripScroll.call( this, this.tracker, { position: null, scroll: -1, shift: null } ); - return false; - case 48: //0|) - case 119: //w - case 87: //W - case 38: //up arrow - onStripScroll.call( this, this.tracker, { position: null, scroll: 1, shift: null } ); - return false; - case 115: //s - case 83: //S - case 40: //down arrow - onStripScroll.call( this, this.tracker, { position: null, scroll: -1, shift: null } ); - return false; - case 97: //a - case 37: //left arrow - onStripScroll.call( this, this.tracker, { position: null, scroll: -1, shift: null } ); - return false; - case 100: //d - case 39: //right arrow - onStripScroll.call( this, this.tracker, { position: null, scroll: 1, shift: null } ); - return false; - default: - //console.log( 'navigator keycode %s', eventData.keyCode ); - return true; - } + case 45: //-|_ + onStripScroll.call( this, this.tracker, { position: null, scroll: -1, shift: null } ); + return false; + case 48: //0|) + case 119: //w + case 87: //W + case 38: //up arrow + onStripScroll.call( this, this.tracker, { position: null, scroll: 1, shift: null } ); + return false; + case 115: //s + case 83: //S + case 40: //down arrow + onStripScroll.call( this, this.tracker, { position: null, scroll: -1, shift: null } ); + return false; + case 97: //a + case 37: //left arrow + onStripScroll.call( this, this.tracker, { position: null, scroll: -1, shift: null } ); + return false; + case 100: //d + case 39: //right arrow + onStripScroll.call( this, this.tracker, { position: null, scroll: 1, shift: null } ); + return false; + default: + //console.log( 'navigator keycode %s', eventData.keyCode ); + return true; } +}