From 0d29c98df219fe030aa4c5a4ee7698d705d6aa90 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Fri, 13 Dec 2013 09:23:56 -0800 Subject: [PATCH 01/11] Enhanced Navigator Resizability (#280, #296) New navigator options: * @property {Boolean} [showNavigator=false] * Set to true to make the navigator minimap appear. * * @property {Boolean} [navigatorId=navigator-GENERATED DATE] * The ID of a div to hold the navigator minimap. * If an ID is specified, the navigatorPosition, navigatorSizeRatio, navigatorMaintainSizeRatio, and navigatorTop|Left|Height|Width options will be ignored. * If an ID is not specified, a div element will be generated and placed on top of the main image. * * @property {String} [navigatorPosition='TOP_RIGHT'] * Valid values are 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', 'BOTTOM_RIGHT', or 'ABSOLUTE'.
* If 'ABSOLUTE' is specified, then navigatorTop|Left|Height|Width determines the size and position of the navigator minimap in the viewer, and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.
* For 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', and 'BOTTOM_RIGHT', the navigatorSizeRatio or navigatorHeight|Width values determine the size of the navigator minimap. * * @property {Number} [navigatorSizeRatio=0.2] * Ratio of navigator size to viewer size. Ignored if navigatorHeight|Width are specified. * * @property {Boolean} [navigatorMaintainSizeRatio=false] * If true, the navigator minimap is resized (using navigatorSizeRatio) when the viewer size changes. * * @property {Number|String} [navigatorTop=null] * Specifies the location of the navigator minimap (see navigatorPosition). * * @property {Number|String} [navigatorLeft=null] * Specifies the location of the navigator minimap (see navigatorPosition). * * @property {Number|String} [navigatorHeight=null] * Specifies the size of the navigator minimap (see navigatorPosition). * If specified, navigatorSizeRatio and navigatorMaintainSizeRatio are ignored. * * @property {Number|String} [navigatorWidth=null] * Specifies the size of the navigator minimap (see navigatorPosition). * If specified, navigatorSizeRatio and navigatorMaintainSizeRatio are ignored. Fixes #280 and #296 --- src/control.js | 45 ++++++++++++------- src/controldock.js | 6 +++ src/navigator.js | 103 +++++++++++++++++++++++++------------------ src/openseadragon.js | 51 ++++++++++++++------- src/viewer.js | 23 +++++----- 5 files changed, 144 insertions(+), 84 deletions(-) diff --git a/src/control.js b/src/control.js index d35776b9..3c7efe0c 100644 --- a/src/control.js +++ b/src/control.js @@ -46,13 +46,15 @@ * @property {Number} TOP_RIGHT * @property {Number} BOTTOM_LEFT * @property {Number} BOTTOM_RIGHT + * @property {Number} ABSOLUTE */ $.ControlAnchor = { NONE: 0, TOP_LEFT: 1, TOP_RIGHT: 2, BOTTOM_RIGHT: 3, - BOTTOM_LEFT: 4 + BOTTOM_LEFT: 4, + ABSOLUTE: 5 }; /** @@ -110,13 +112,15 @@ $.Control = function ( element, options, container ) { * @member {Element} wrapper * @memberof OpenSeadragon.Control# */ - this.wrapper = $.makeNeutralElement( "span" ); - this.wrapper.style.display = "inline-block"; - this.wrapper.appendChild( this.element ); + if ( this.anchor != $.ControlAnchor.ABSOLUTE ) { + this.wrapper = $.makeNeutralElement( "span" ); + this.wrapper.style.display = "inline-block"; + this.wrapper.appendChild( this.element ); - if ( this.anchor == $.ControlAnchor.NONE ) { - // IE6 fix - this.wrapper.style.width = this.wrapper.style.height = "100%"; + if ( this.anchor == $.ControlAnchor.NONE ) { + // IE6 fix + this.wrapper.style.width = this.wrapper.style.height = "100%"; + } } if (options.attachToViewer ) { @@ -126,11 +130,13 @@ $.Control = function ( element, options, container ) { this.wrapper, this.container.firstChild ); + } else if ( this.anchor == $.ControlAnchor.ABSOLUTE ) { + this.container.appendChild( this.element ); } else { this.container.appendChild( this.wrapper ); } } else { - parent.appendChild( this.wrapper ); + parent.appendChild( this.anchor == $.ControlAnchor.ABSOLUTE ? this.element : this.wrapper ); } }; @@ -141,8 +147,10 @@ $.Control.prototype = /** @lends OpenSeadragon.Control.prototype */{ * @function */ destroy: function() { - this.wrapper.removeChild( this.element ); - this.container.removeChild( this.wrapper ); + if ( this.anchor != $.ControlAnchor.ABSOLUTE ) { + this.wrapper.removeChild( this.element ); + } + this.container.removeChild( this.anchor == $.ControlAnchor.ABSOLUTE ? this.element : this.wrapper ); }, /** @@ -151,7 +159,8 @@ $.Control.prototype = /** @lends OpenSeadragon.Control.prototype */{ * @return {Boolean} true if currenly visible, false otherwise. */ isVisible: function() { - return this.wrapper.style.display != "none"; + var controlElement = this.anchor == $.ControlAnchor.ABSOLUTE ? this.element : this.wrapper; + return controlElement.style.display != "none"; }, /** @@ -160,9 +169,15 @@ $.Control.prototype = /** @lends OpenSeadragon.Control.prototype */{ * @param {Boolean} visible - true to make visible, false to hide. */ setVisible: function( visible ) { - this.wrapper.style.display = visible ? - "inline-block" : - "none"; + if ( this.anchor == $.ControlAnchor.ABSOLUTE ) { + this.element.style.display = visible ? + "block" : + "none"; + } else { + this.wrapper.style.display = visible ? + "inline-block" : + "none"; + } }, /** @@ -171,7 +186,7 @@ $.Control.prototype = /** @lends OpenSeadragon.Control.prototype */{ * @param {Number} opactiy - a value between 1 and 0 inclusively. */ setOpacity: function( opacity ) { - if ( this.element[ $.SIGNAL ] && $.Browser.vendor == $.BROWSERS.IE ) { + if ( this.anchor == $.ControlAnchor.ABSOLUTE || ( this.element[ $.SIGNAL ] && $.Browser.vendor == $.BROWSERS.IE ) ) { $.setElementOpacity( this.element, opacity, true ); } else { $.setElementOpacity( this.wrapper, opacity, true ); diff --git a/src/controldock.js b/src/controldock.js index 685418d4..34a29967 100644 --- a/src/controldock.js +++ b/src/controldock.js @@ -126,6 +126,12 @@ element.style.paddingLeft = "0px"; element.style.paddingTop = "0px"; break; + case $.ControlAnchor.ABSOLUTE: + div = this.container; + element.style.position = "absolute"; + element.style.margin = "0px"; + element.style.padding = "0px"; + break; default: case $.ControlAnchor.NONE: div = this.container; diff --git a/src/navigator.js b/src/navigator.js index f06944f9..2ce878e8 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -50,7 +50,7 @@ $.Navigator = function( options ){ var viewer = options.viewer, - viewerSize = $.getElementSize( viewer.element), + viewerSize, unneededElement; //We may need to create a new element and id if they did not @@ -73,6 +73,12 @@ $.Navigator = function( options ){ options.controlOptions.anchor = $.ControlAnchor.TOP_RIGHT; } else if( 'TOP_LEFT' == options.position ){ options.controlOptions.anchor = $.ControlAnchor.TOP_LEFT; + } else if( 'ABSOLUTE' == options.position ){ + options.controlOptions.anchor = $.ControlAnchor.ABSOLUTE; + options.controlOptions.top = options.top; + options.controlOptions.left = options.left; + options.controlOptions.height = options.height; + options.controlOptions.width = options.width; } } @@ -104,7 +110,6 @@ $.Navigator = function( options ){ options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio; - this.viewerSizeInPoints = viewer.viewport.deltaPointsFromPixels(viewerSize); this.borderWidth = 2; //At some browser magnification levels the display regions lines up correctly, but at some there appears to //be a one pixel gap. @@ -147,20 +152,16 @@ $.Navigator = function( options ){ style.cssFloat = 'left'; //Firefox style.styleFloat = 'left'; //IE style.zIndex = 999999999; - style.cursor = 'default'; + style.cursor = 'pointer'; }( this.displayRegion.style, this.borderWidth )); this.element.innerTracker = new $.MouseTracker({ - element: this.element, - dragHandler: $.delegate( this, onCanvasDrag ), - clickHandler: $.delegate( this, onCanvasClick ), - releaseHandler: $.delegate( this, onCanvasRelease ), - scrollHandler: function(){ - //dont scroll the page up and down if the user is scrolling - //in the navigator - return false; - } + element: this.element, + dragHandler: $.delegate( this, onCanvasDrag ), + clickHandler: $.delegate( this, onCanvasClick ), + releaseHandler: $.delegate( this, onCanvasRelease ), + scrollHandler: $.delegate( this, onCanvasScroll ) }).setTracking( true ); /*this.displayRegion.outerTracker = new $.MouseTracker({ @@ -178,12 +179,20 @@ $.Navigator = function( options ){ options.controlOptions ); - if( options.width && options.height ){ - this.element.style.width = options.width + 'px'; - this.element.style.height = options.height + 'px'; + if ( options.controlOptions.anchor === $.ControlAnchor.ABSOLUTE ) { + this.element.style.top = typeof ( options.top ) == "number" ? ( options.top + 'px' ) : options.top; + this.element.style.left = typeof ( options.left ) == "number" ? (options.left + 'px' ) : options.left; + } + if ( options.width && options.height ) { + this.element.style.height = typeof ( options.height ) == "number" ? ( options.height + 'px' ) : options.height; + this.element.style.width = typeof ( options.width ) == "number" ? ( options.width + 'px' ) : options.width; } else { - this.element.style.width = ( viewerSize.x * options.sizeRatio ) + 'px'; + viewerSize = $.getElementSize( viewer.element ); this.element.style.height = ( viewerSize.y * options.sizeRatio ) + 'px'; + this.element.style.width = ( viewerSize.x * options.sizeRatio ) + 'px'; + if ( options.maintainSizeRatio ) { + this.oldViewerSize = viewerSize; + } } $.Viewer.apply( this, [ options ] ); @@ -203,10 +212,20 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /* */ update: function( viewport ){ - var bounds, + var viewerSize, + bounds, topleft, bottomright; + if ( this.maintainSizeRatio ) { + viewerSize = $.getElementSize( this.viewer.element ); + if ( !viewerSize.equals ( this.oldViewerSize ) ) { + this.element.style.height = ( viewerSize.y * this.sizeRatio ) + 'px'; + this.element.style.width = ( viewerSize.x * this.sizeRatio ) + 'px'; + this.oldViewerSize = viewerSize; + } + } + if( viewport && this.viewport ){ bounds = viewport.getBounds( true ); topleft = this.viewport.pixelFromPoint( bounds.getTopLeft()); @@ -256,21 +275,7 @@ function onCanvasClick( event ) { dimensions; if (! this.drag) { if ( this.viewer.viewport ) { - viewerPosition = this.viewport.deltaPointsFromPixels( event.position ); - dimensions = this.viewer.viewport.getBounds().getSize(); - newBounds = new $.Rect( - viewerPosition.x - dimensions.x/2, - viewerPosition.y - dimensions.y/2, - dimensions.x, - dimensions.y - ); - if (this.viewer.source.aspectRatio > this.viewer.viewport.getAspectRatio()) { - newBounds.y = newBounds.y - ((this.viewerSizeInPoints.y - (1/this.viewer.source.aspectRatio)) /2 ); - } - else { - newBounds.x = newBounds.x - ((this.viewerSizeInPoints.x -1) /2 ); - } - this.viewer.viewport.fitBounds(newBounds); + this.viewer.viewport.panTo( this.viewport.pointFromPixel( event.position ) ); this.viewer.viewport.applyConstraints(); } } @@ -320,16 +325,30 @@ function onCanvasRelease( event ) { * @function */ function onCanvasScroll( event ) { - var factor; - if ( this.viewer.viewport ) { - factor = Math.pow( this.zoomPerScroll, event.scroll ); - this.viewer.viewport.zoomBy( - factor, - this.viewport.getCenter() - ); - this.viewer.viewport.applyConstraints(); - } - //cancels event + /** + * Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#navigator} element (mouse wheel, touch pinch, etc.). + * + * @event navigator-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.viewer.raiseEvent( 'navigator-scroll', { + tracker: event.eventSource, + position: event.position, + scroll: event.scroll, + shift: event.shift, + originalEvent: event.originalEvent + }); + + //dont scroll the page up and down if the user is scrolling + //in the navigator return false; } diff --git a/src/openseadragon.js b/src/openseadragon.js index 40af70aa..43ad51a9 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -271,20 +271,34 @@ * Set to true to make the navigator minimap appear. * * @property {Boolean} [navigatorId=navigator-GENERATED DATE] - * Set the ID of a div to hold the navigator minimap. If one is not specified, - * one will be generated and placed on top of the main image + * The ID of a div to hold the navigator minimap. + * If an ID is specified, the navigatorPosition, navigatorSizeRatio, navigatorMaintainSizeRatio, and navigatorTop|Left|Height|Width options will be ignored. + * If an ID is not specified, a div element will be generated and placed on top of the main image. * - * @property {Number} [navigatorHeight=null] - * TODO: Implement this. Currently not used. - * - * @property {Number} [navigatorWidth=null] - * TODO: Implement this. Currently not used. - * - * @property {Number} [navigatorPosition=null] - * TODO: Implement this. Currently not used. + * @property {String} [navigatorPosition='TOP_RIGHT'] + * Valid values are 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', 'BOTTOM_RIGHT', or 'ABSOLUTE'.
+ * If 'ABSOLUTE' is specified, then navigatorTop|Left|Height|Width determines the size and position of the navigator minimap in the viewer, and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.
+ * For 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', and 'BOTTOM_RIGHT', the navigatorSizeRatio or navigatorHeight|Width values determine the size of the navigator minimap. * * @property {Number} [navigatorSizeRatio=0.2] - * Ratio of navigator size to viewer size. + * Ratio of navigator size to viewer size. Ignored if navigatorHeight|Width are specified. + * + * @property {Boolean} [navigatorMaintainSizeRatio=false] + * If true, the navigator minimap is resized (using navigatorSizeRatio) when the viewer size changes. + * + * @property {Number|String} [navigatorTop=null] + * Specifies the location of the navigator minimap (see navigatorPosition). + * + * @property {Number|String} [navigatorLeft=null] + * Specifies the location of the navigator minimap (see navigatorPosition). + * + * @property {Number|String} [navigatorHeight=null] + * Specifies the size of the navigator minimap (see navigatorPosition). + * If specified, navigatorSizeRatio and navigatorMaintainSizeRatio are ignored. + * + * @property {Number|String} [navigatorWidth=null] + * Specifies the size of the navigator minimap (see navigatorPosition). + * If specified, navigatorSizeRatio and navigatorMaintainSizeRatio are ignored. * * @property {Number} [controlsFadeDelay=2000] * The number of milliseconds to wait once the user has stopped interacting @@ -713,12 +727,15 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ mouseNavEnabled: true, //GENERAL MOUSE INTERACTIVITY //VIEWPORT NAVIGATOR SETTINGS - showNavigator: false, - navigatorId: null, - navigatorHeight: null, - navigatorWidth: null, - navigatorPosition: null, - navigatorSizeRatio: 0.2, + showNavigator: false, + navigatorId: null, + navigatorPosition: null, + navigatorSizeRatio: 0.2, + navigatorMaintainSizeRatio: false, + navigatorTop: null, + navigatorLeft: null, + navigatorHeight: null, + navigatorWidth: null, // INITIAL ROTATION degrees: 0, diff --git a/src/viewer.js b/src/viewer.js index 8894a8a4..84406008 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1469,16 +1469,19 @@ function openTileSource( viewer, source ) { _this.navigator.open( source ); } else { _this.navigator = new $.Navigator({ - id: _this.navigatorId, - position: _this.navigatorPosition, - sizeRatio: _this.navigatorSizeRatio, - height: _this.navigatorHeight, - width: _this.navigatorWidth, - tileSources: source, - tileHost: _this.tileHost, - prefixUrl: _this.prefixUrl, - overlays: _this.overlays, - viewer: _this + id: _this.navigatorId, + position: _this.navigatorPosition, + sizeRatio: _this.navigatorSizeRatio, + maintainSizeRatio: _this.navigatorMaintainSizeRatio, + top: _this.navigatorTop, + left: _this.navigatorLeft, + width: _this.navigatorWidth, + height: _this.navigatorHeight, + tileSources: source, + tileHost: _this.tileHost, + prefixUrl: _this.prefixUrl, + overlays: _this.overlays, + viewer: _this }); } } From 71fb3a5e33149c5827adeea0b1c3425399de1048 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Fri, 13 Dec 2013 09:44:21 -0800 Subject: [PATCH 02/11] changelog update --- changelog.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.txt b/changelog.txt index abb9fed9..95ebec39 100644 --- a/changelog.txt +++ b/changelog.txt @@ -6,6 +6,10 @@ OPENSEADRAGON CHANGELOG * Fixed: Nav button highlight states aren't quite aligned on Firefox (#303) * Added ControlAnchor options for default controls (#304) * Enabled basic cross-domain tile loading without tainting canvas (works in Chrome and Firefox) (#308) +* Added a ControlAnchor.ABSOLUTE enumeration. Enables absolute positioning of control elements in the viewer (#310) +* Added a navigatorMaintainSizeRatio option. If set to true, the navigator minimap resizes when the viewer element is resized (#310) +* Added 'ABSOLUTE' as a navigatorPosition option, along with corresponding navigatorTop, navigatorLeft options. Allows the navigator minimap to be placed anywhere in the viewer (#310) +* Enhanced the navigatorTop, navigatorLeft, navigatorHeight, and navigatorWidth options to allow a number for pixel units or a string for other element units (%, em, etc.) (#310) 1.0.0: From 14acb5d5810a8b484e266856fa593bd9128430ef Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Fri, 13 Dec 2013 11:55:36 -0800 Subject: [PATCH 03/11] ABSOLUTE Control bug fix Wrapped ABSOLUTE positioned controls in a div so fade opacity would work correctly. Added 'navigator-scroll' event addition to changelog. --- changelog.txt | 1 + src/control.js | 47 ++++++++++++++++++++++++---------------------- src/controldock.js | 1 - src/navigator.js | 24 +++++++++++------------ 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/changelog.txt b/changelog.txt index 95ebec39..ffa4e708 100644 --- a/changelog.txt +++ b/changelog.txt @@ -7,6 +7,7 @@ OPENSEADRAGON CHANGELOG * Added ControlAnchor options for default controls (#304) * Enabled basic cross-domain tile loading without tainting canvas (works in Chrome and Firefox) (#308) * Added a ControlAnchor.ABSOLUTE enumeration. Enables absolute positioning of control elements in the viewer (#310) +* Added a 'navigator-scroll' event to Navigator. Fired when mousewheel/pinch events occur in the navigator (#310) * Added a navigatorMaintainSizeRatio option. If set to true, the navigator minimap resizes when the viewer element is resized (#310) * Added 'ABSOLUTE' as a navigatorPosition option, along with corresponding navigatorTop, navigatorLeft options. Allows the navigator minimap to be placed anywhere in the viewer (#310) * Enhanced the navigatorTop, navigatorLeft, navigatorHeight, and navigatorWidth options to allow a number for pixel units or a string for other element units (%, em, etc.) (#310) diff --git a/src/control.js b/src/control.js index 3c7efe0c..c6010399 100644 --- a/src/control.js +++ b/src/control.js @@ -112,16 +112,30 @@ $.Control = function ( element, options, container ) { * @member {Element} wrapper * @memberof OpenSeadragon.Control# */ - if ( this.anchor != $.ControlAnchor.ABSOLUTE ) { + if ( this.anchor == $.ControlAnchor.ABSOLUTE ) { + this.wrapper = $.makeNeutralElement( "div" ); + this.wrapper.style.position = "absolute"; + this.wrapper.style.top = typeof ( options.top ) == "number" ? ( options.top + 'px' ) : options.top; + this.wrapper.style.left = typeof ( options.left ) == "number" ? (options.left + 'px' ) : options.left; + this.wrapper.style.height = typeof ( options.height ) == "number" ? ( options.height + 'px' ) : options.height; + this.wrapper.style.width = typeof ( options.width ) == "number" ? ( options.width + 'px' ) : options.width; + this.wrapper.style.margin = "0px"; + this.wrapper.style.padding = "0px"; + + this.element.style.position = "relative"; + this.element.style.top = "0px"; + this.element.style.left = "0px"; + this.element.style.height = "100%"; + this.element.style.width = "100%"; + } else { this.wrapper = $.makeNeutralElement( "span" ); this.wrapper.style.display = "inline-block"; - this.wrapper.appendChild( this.element ); - if ( this.anchor == $.ControlAnchor.NONE ) { // IE6 fix this.wrapper.style.width = this.wrapper.style.height = "100%"; } } + this.wrapper.appendChild( this.element ); if (options.attachToViewer ) { if ( this.anchor == $.ControlAnchor.TOP_RIGHT || @@ -130,13 +144,11 @@ $.Control = function ( element, options, container ) { this.wrapper, this.container.firstChild ); - } else if ( this.anchor == $.ControlAnchor.ABSOLUTE ) { - this.container.appendChild( this.element ); } else { this.container.appendChild( this.wrapper ); } } else { - parent.appendChild( this.anchor == $.ControlAnchor.ABSOLUTE ? this.element : this.wrapper ); + parent.appendChild( this.wrapper ); } }; @@ -147,10 +159,8 @@ $.Control.prototype = /** @lends OpenSeadragon.Control.prototype */{ * @function */ destroy: function() { - if ( this.anchor != $.ControlAnchor.ABSOLUTE ) { - this.wrapper.removeChild( this.element ); - } - this.container.removeChild( this.anchor == $.ControlAnchor.ABSOLUTE ? this.element : this.wrapper ); + this.wrapper.removeChild( this.element ); + this.container.removeChild( this.wrapper ); }, /** @@ -159,8 +169,7 @@ $.Control.prototype = /** @lends OpenSeadragon.Control.prototype */{ * @return {Boolean} true if currenly visible, false otherwise. */ isVisible: function() { - var controlElement = this.anchor == $.ControlAnchor.ABSOLUTE ? this.element : this.wrapper; - return controlElement.style.display != "none"; + return this.wrapper.style.display != "none"; }, /** @@ -169,15 +178,9 @@ $.Control.prototype = /** @lends OpenSeadragon.Control.prototype */{ * @param {Boolean} visible - true to make visible, false to hide. */ setVisible: function( visible ) { - if ( this.anchor == $.ControlAnchor.ABSOLUTE ) { - this.element.style.display = visible ? - "block" : - "none"; - } else { - this.wrapper.style.display = visible ? - "inline-block" : - "none"; - } + this.wrapper.style.display = visible ? + ( this.anchor == $.ControlAnchor.ABSOLUTE ? 'block' : 'inline-block' ) : + "none"; }, /** @@ -186,7 +189,7 @@ $.Control.prototype = /** @lends OpenSeadragon.Control.prototype */{ * @param {Number} opactiy - a value between 1 and 0 inclusively. */ setOpacity: function( opacity ) { - if ( this.anchor == $.ControlAnchor.ABSOLUTE || ( this.element[ $.SIGNAL ] && $.Browser.vendor == $.BROWSERS.IE ) ) { + if ( this.element[ $.SIGNAL ] && $.Browser.vendor == $.BROWSERS.IE ) { $.setElementOpacity( this.element, opacity, true ); } else { $.setElementOpacity( this.wrapper, opacity, true ); diff --git a/src/controldock.js b/src/controldock.js index 34a29967..183890c7 100644 --- a/src/controldock.js +++ b/src/controldock.js @@ -128,7 +128,6 @@ break; case $.ControlAnchor.ABSOLUTE: div = this.container; - element.style.position = "absolute"; element.style.margin = "0px"; element.style.padding = "0px"; break; diff --git a/src/navigator.js b/src/navigator.js index 2ce878e8..bfd51980 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -179,19 +179,17 @@ $.Navigator = function( options ){ options.controlOptions ); - if ( options.controlOptions.anchor === $.ControlAnchor.ABSOLUTE ) { - this.element.style.top = typeof ( options.top ) == "number" ? ( options.top + 'px' ) : options.top; - this.element.style.left = typeof ( options.left ) == "number" ? (options.left + 'px' ) : options.left; - } - if ( options.width && options.height ) { - this.element.style.height = typeof ( options.height ) == "number" ? ( options.height + 'px' ) : options.height; - this.element.style.width = typeof ( options.width ) == "number" ? ( options.width + 'px' ) : options.width; - } else { - viewerSize = $.getElementSize( viewer.element ); - this.element.style.height = ( viewerSize.y * options.sizeRatio ) + 'px'; - this.element.style.width = ( viewerSize.x * options.sizeRatio ) + 'px'; - if ( options.maintainSizeRatio ) { - this.oldViewerSize = viewerSize; + if ( options.controlOptions.anchor != $.ControlAnchor.ABSOLUTE ) { + if ( options.width && options.height ) { + this.element.style.height = typeof ( options.height ) == "number" ? ( options.height + 'px' ) : options.height; + this.element.style.width = typeof ( options.width ) == "number" ? ( options.width + 'px' ) : options.width; + } else { + viewerSize = $.getElementSize( viewer.element ); + this.element.style.height = ( viewerSize.y * options.sizeRatio ) + 'px'; + this.element.style.width = ( viewerSize.x * options.sizeRatio ) + 'px'; + if ( options.maintainSizeRatio ) { + this.oldViewerSize = viewerSize; + } } } From a189ba97d7244f5e002e909e182e5ff85458f615 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Sat, 14 Dec 2013 09:11:14 -0800 Subject: [PATCH 04/11] Update navigator on full-page/full-screen bug fix --- src/viewer.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/viewer.js b/src/viewer.js index 84406008..06a8858f 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -910,6 +910,10 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, } + if ( this.navigator && this.viewport ) { + this.navigator.update( this.viewport ); + } + /** * Raised when the viewer has changed to/from full-page mode (see {@link OpenSeadragon.Viewer#setFullPage}). * @@ -991,6 +995,9 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, _this.element.style.height = _this.fullPageStyleHeight; } } + if ( _this.navigator && _this.viewport ) { + _this.navigator.update( _this.viewport ); + } /** * Raised when the viewer has changed to/from full-screen mode (see {@link OpenSeadragon.Viewer#setFullScreen}). * From 1e9ea154f2afd7ebecfd893d7258421740a5f22e Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Sat, 14 Dec 2013 14:45:11 -0800 Subject: [PATCH 05/11] Added navigatorAutoResize option Improved resizable navigator support. --- src/navigator.js | 53 ++++++++++++++++++++++++++++++++++++++------ src/openseadragon.js | 5 +++++ src/viewer.js | 1 + 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/navigator.js b/src/navigator.js index bfd51980..6461659a 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -105,7 +105,8 @@ $.Navigator = function( options ){ showSequenceControl: false, immediateRender: true, blendTime: 0, - animationTime: 0 + animationTime: 0, + autoResize: options.autoResize }); options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio; @@ -193,6 +194,8 @@ $.Navigator = function( options ){ } } + this.oldContainerSize = new $.Point( 0, 0 ); + $.Viewer.apply( this, [ options ] ); this.element.getElementsByTagName('form')[0].appendChild( this.displayRegion ); @@ -206,9 +209,43 @@ $.Navigator = function( options ){ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /** @lends OpenSeadragon.Navigator.prototype */{ /** + * Used to notify the navigator when its size has changed. + * Especially useful when {@link OpenSeadragon.Options}.navigatorAutoResize is set to false and the navigator is resizable. * @function */ - update: function( viewport ){ + updateSize: function () { + if ( this.viewport ) { + var containerSize = new $.Point( + (this.container.clientWidth === 0 ? 1 : this.container.clientWidth), + (this.container.clientHeight === 0 ? 1 : this.container.clientHeight) + ); + if ( !containerSize.equals( this.oldContainerSize ) ) { + var oldBounds = this.viewport.getBounds(); + var oldCenter = this.viewport.getCenter(); + this.viewport.resize( containerSize, true ); + var imageHeight = 1 / this.source.aspectRatio; + var newWidth = oldBounds.width <= 1 ? oldBounds.width : 1; + var newHeight = oldBounds.height <= imageHeight ? + oldBounds.height : imageHeight; + var newBounds = new $.Rect( + oldCenter.x - ( newWidth / 2.0 ), + oldCenter.y - ( newHeight / 2.0 ), + newWidth, + newHeight + ); + this.viewport.fitBounds( newBounds, true ); + this.oldContainerSize = containerSize; + this.drawer.update(); + } + } + }, + + /** + * Used to update the navigator minimap's viewport rectangle when a change in the viewer's viewport occurs. + * @function + * @param {OpenSeadragon.Viewport} The viewport this navigator is tracking. + */ + update: function( viewport ) { var viewerSize, bounds, @@ -217,17 +254,18 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /* if ( this.maintainSizeRatio ) { viewerSize = $.getElementSize( this.viewer.element ); - if ( !viewerSize.equals ( this.oldViewerSize ) ) { + if ( !viewerSize.equals( this.oldViewerSize ) ) { this.element.style.height = ( viewerSize.y * this.sizeRatio ) + 'px'; this.element.style.width = ( viewerSize.x * this.sizeRatio ) + 'px'; this.oldViewerSize = viewerSize; + this.updateSize(); } } - if( viewport && this.viewport ){ + if( viewport && this.viewport ) { bounds = viewport.getBounds( true ); - topleft = this.viewport.pixelFromPoint( bounds.getTopLeft()); - bottomright = this.viewport.pixelFromPoint( bounds.getBottomRight()).minus(this.totalBorderWidths); + topleft = this.viewport.pixelFromPoint( bounds.getTopLeft(), false ); + bottomright = this.viewport.pixelFromPoint( bounds.getBottomRight(), false ).minus( this.totalBorderWidths ); //update style for navigator-box (function(style) { @@ -246,7 +284,8 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /* }, - open: function( source ){ + open: function( source ) { + this.updateSize(); var containerSize = this.viewer.viewport.containerSize.times( this.sizeRatio ); if( source.tileSize > containerSize.x || source.tileSize > containerSize.y ){ diff --git a/src/openseadragon.js b/src/openseadragon.js index 43ad51a9..9ee18112 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -300,6 +300,10 @@ * Specifies the size of the navigator minimap (see navigatorPosition). * If specified, navigatorSizeRatio and navigatorMaintainSizeRatio are ignored. * + * @property {Boolean} [navigatorAutoResize=true] + * Set to false to prevent polling for navigator size changes. Useful for providing custom resize behavior. + * Setting to false can also improve performance when the navigator is configured to a fixed size. + * * @property {Number} [controlsFadeDelay=2000] * The number of milliseconds to wait once the user has stopped interacting * with the interface before begining to fade the controls. Assumes @@ -736,6 +740,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ navigatorLeft: null, navigatorHeight: null, navigatorWidth: null, + navigatorAutoResize: true, // INITIAL ROTATION degrees: 0, diff --git a/src/viewer.js b/src/viewer.js index 06a8858f..2139678e 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1484,6 +1484,7 @@ function openTileSource( viewer, source ) { left: _this.navigatorLeft, width: _this.navigatorWidth, height: _this.navigatorHeight, + autoResize: _this.navigatorAutoResize, tileSources: source, tileHost: _this.tileHost, prefixUrl: _this.prefixUrl, From 1cac9fa5337cc637547e68772c91e84397f4c03f Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Mon, 16 Dec 2013 07:17:35 -0800 Subject: [PATCH 06/11] Navigator cursor fix --- src/navigator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/navigator.js b/src/navigator.js index 6461659a..687a8b10 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -153,7 +153,7 @@ $.Navigator = function( options ){ style.cssFloat = 'left'; //Firefox style.styleFloat = 'left'; //IE style.zIndex = 999999999; - style.cursor = 'pointer'; + style.cursor = 'default'; }( this.displayRegion.style, this.borderWidth )); From 7ce552caf9c069eddb18bd0165a73a87cf2098f2 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Mon, 13 Jan 2014 14:51:22 -0800 Subject: [PATCH 07/11] Navigator update Allow navigators hosted in a user-supplied element to be styled by user. --- src/navigator.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/navigator.js b/src/navigator.js index 687a8b10..a7ae7384 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -118,14 +118,16 @@ $.Navigator = function( options ){ this.totalBorderWidths = new $.Point(this.borderWidth*2, this.borderWidth*2).minus(this.fudge); - (function( style, borderWidth ){ - style.margin = '0px'; - style.border = borderWidth + 'px solid #555'; - style.padding = '0px'; - style.background = '#000'; - style.opacity = 0.8; - style.overflow = 'hidden'; - }( this.element.style, this.borderWidth)); + if ( options.controlOptions.anchor != $.ControlAnchor.NONE ) { + (function( style, borderWidth ){ + style.margin = '0px'; + style.border = borderWidth + 'px solid #555'; + style.padding = '0px'; + style.background = '#000'; + style.opacity = 0.8; + style.overflow = 'hidden'; + }( this.element.style, this.borderWidth)); + } this.displayRegion = $.makeNeutralElement( "div" ); this.displayRegion.id = this.element.id + '-displayregion'; @@ -180,7 +182,7 @@ $.Navigator = function( options ){ options.controlOptions ); - if ( options.controlOptions.anchor != $.ControlAnchor.ABSOLUTE ) { + if ( options.controlOptions.anchor != $.ControlAnchor.ABSOLUTE && options.controlOptions.anchor != $.ControlAnchor.NONE ) { if ( options.width && options.height ) { this.element.style.height = typeof ( options.height ) == "number" ? ( options.height + 'px' ) : options.height; this.element.style.width = typeof ( options.width ) == "number" ? ( options.width + 'px' ) : options.width; From d874bb63ac8dba28ab76b95097030fbe0aa89f27 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Thu, 16 Jan 2014 12:11:35 -0800 Subject: [PATCH 08/11] Navigator Tests Update Tests added for all navigator placements. Work in progress: Adding tests for viewer resizing. --- test/navigator.js | 317 ++++++++++++++++++++++++++++++++++++---------- test/test.css | 5 + test/test.js | 2 + 3 files changed, 254 insertions(+), 70 deletions(-) diff --git a/test/navigator.js b/test/navigator.js index f63c8cd0..77927532 100644 --- a/test/navigator.js +++ b/test/navigator.js @@ -3,12 +3,11 @@ QUnit.config.autostart = false; (function () { - var viewer, + var debug = false, + viewer, displayRegion, navigator, - navigatorAspectRatio, - leftScalingFactor, - maxHeightFactor, + navigatorScaleFactor, contentStartFromLeft, contentStartFromTop, displayRegionWidth, @@ -42,9 +41,7 @@ QUnit.config.autostart = false; } displayRegion = null; navigator = null; - navigatorAspectRatio = null; - leftScalingFactor = null; - maxHeightFactor = null; + navigatorScaleFactor = null; contentStartFromLeft = null; contentStartFromTop = null; displayRegionWidth = null; @@ -55,57 +52,71 @@ QUnit.config.autostart = false; var assessNavigatorLocation = function (expectedX, expectedY) { var navigator = $(".navigator"); - Util.assessNumericValue(expectedX, navigator.offset().left, 4, ' Navigator x position'); - Util.assessNumericValue(expectedY, navigator.offset().top, 4, ' Navigator y position'); + Util.assessNumericValue(expectedX, navigator.offset().left, 10, ' Navigator x position'); + Util.assessNumericValue(expectedY, navigator.offset().top, 10, ' Navigator y position'); }; - var navigatorRegionBoundsInPoints = function () { + var assessNavigatorSize = function (expectedWidth, expectedHeight) { + var navigator = $(".navigator"); + + Util.assessNumericValue(expectedWidth, navigator.width(), 2, ' Navigator width'); + Util.assessNumericValue(expectedHeight, navigator.height(), 2, ' Navigator height'); + }; + + var assessNavigatorAspectRatio = function (expectedAspectRatio) { + var navigator = $(".navigator"); + + Util.assessNumericValue(expectedAspectRatio, navigator.width() / navigator.height(), 0.0001, ' Navigator aspect ratio'); + }; + + var navigatorRegionBoundsInPoints = function (recalcForResize) { var regionBoundsInPoints, expectedDisplayRegionWidth, expectedDisplayRegionHeight, expectedDisplayRegionXLocation, expectedDisplayRegionYLocation; - if (navigator === null) { - maxHeightFactor = 1; - navigator = $(".navigator"); - navigatorAspectRatio = navigator.height() / navigator.width(); - leftScalingFactor = navigatorAspectRatio * viewer.source.aspectRatio; - if (viewer.source.aspectRatio < 1) { - if (viewer.source.aspectRatio < navigatorAspectRatio) { - maxHeightFactor = viewer.source.aspectRatio * navigatorAspectRatio; - } - else { - maxHeightFactor = viewer.source.aspectRatio; - } - contentStartFromLeft = ((1 / maxHeightFactor) - 1) / 2 * maxHeightFactor * navigator.width(); - contentStartFromTop = 0; - } - else { - if (viewer.source.aspectRatio < navigatorAspectRatio) { - contentStartFromTop = (navigatorAspectRatio - (1 / viewer.source.aspectRatio)) / 2 / navigatorAspectRatio * navigator.height(); - } - else { - contentStartFromTop = (navigatorAspectRatio - (1 / viewer.source.aspectRatio)) / 2 / navigatorAspectRatio * navigator.height(); - leftScalingFactor = 1; - } - } - displayRegionWidth = navigator.width() - 2 * contentStartFromLeft; - displayRegionHeight = navigator.height() - 2 * contentStartFromTop; - } - expectedDisplayRegionWidth = navigator.width() / viewer.viewport.getZoom() * maxHeightFactor; - expectedDisplayRegionHeight = navigator.height() / viewer.viewport.getZoom() * maxHeightFactor; - expectedDisplayRegionXLocation = viewer.viewport.getBounds().x * maxHeightFactor * navigator.width() + contentStartFromLeft; - expectedDisplayRegionYLocation = viewer.viewport.getBounds().y * leftScalingFactor * navigator.width() + contentStartFromTop; + if (navigator === null || recalcForResize) { + navigator = $(".navigator"); + navigatorScaleFactor = Math.min(navigator.width() / viewer.viewport.contentSize.x, navigator.height() / viewer.viewport.contentSize.y); + displayRegionWidth = viewer.viewport.contentSize.x * navigatorScaleFactor; + displayRegionHeight = viewer.viewport.contentSize.y * navigatorScaleFactor; + contentStartFromLeft = (navigator.width() - displayRegionWidth) / 2; + contentStartFromTop = (navigator.height() - displayRegionHeight) / 2; + } + expectedDisplayRegionWidth = viewer.viewport.getBounds().width * displayRegionWidth; + expectedDisplayRegionHeight = viewer.viewport.getBounds().height * displayRegionHeight * viewer.source.aspectRatio; + expectedDisplayRegionXLocation = viewer.viewport.getBounds().x * displayRegionWidth + contentStartFromLeft; + expectedDisplayRegionYLocation = viewer.viewport.getBounds().y * displayRegionHeight * viewer.source.aspectRatio + contentStartFromTop; regionBoundsInPoints = new OpenSeadragon.Rect(expectedDisplayRegionXLocation, expectedDisplayRegionYLocation, expectedDisplayRegionWidth, expectedDisplayRegionHeight); + if (debug) { + console.log('Image width: ' + viewer.viewport.contentSize.x + '\n' + + 'Image height: ' + viewer.viewport.contentSize.y + '\n' + + 'navigator.width(): ' + navigator.width() + '\n' + + 'navigator.height(): ' + navigator.height() + '\n' + + 'navigatorScaleFactor: ' + navigatorScaleFactor + '\n' + + 'contentStartFromLeft: ' + contentStartFromLeft + '\n' + + 'contentStartFromTop: ' + contentStartFromTop + '\n' + + 'displayRegionWidth: ' + displayRegionWidth + '\n' + + 'displayRegionHeight: ' + displayRegionHeight + '\n' + + 'expectedDisplayRegionXLocation: ' + expectedDisplayRegionXLocation + '\n' + + 'expectedDisplayRegionYLocation: ' + expectedDisplayRegionYLocation + '\n' + + 'expectedDisplayRegionWidth: ' + expectedDisplayRegionWidth + '\n' + + 'expectedDisplayRegionHeight: ' + expectedDisplayRegionHeight + '\n' + ); + } + return regionBoundsInPoints; }; - var assessDisplayRegion = function (status) { + var assessDisplayRegion = function (status, recalcForResize) { - var expectedBounds = navigatorRegionBoundsInPoints(); + if (debug) { + console.log(status); + } + var expectedBounds = navigatorRegionBoundsInPoints(recalcForResize); Util.assessNumericValue(expectedBounds.width, displayRegion.width() + viewer.navigator.totalBorderWidths.x, 2, status + ' Width synchronization'); Util.assessNumericValue(expectedBounds.height, displayRegion.height() + viewer.navigator.totalBorderWidths.y, 2, status + ' Height synchronization'); Util.assessNumericValue(expectedBounds.x, displayRegion.position().left, 2, status + ' Left synchronization'); @@ -379,6 +390,7 @@ QUnit.config.autostart = false; prefixUrl:'/build/openseadragon/images/', tileSources:'/test/data/wide.dzi', showNavigator:true, + navigatorSizeRatio:0.2, animationTime:0 }, { @@ -390,11 +402,187 @@ QUnit.config.autostart = false; navigatorElement = $(testProperties.navigatorLocator); assessNavigatorLocation(mainViewerElement.offset().left + mainViewerElement.width() - navigatorElement.width(), mainViewerElement.offset().top); + assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); } }); }); - asyncTest('CustomNavigatorLocationWithWideImageWideViewer', function () { + asyncTest('DefaultNavigatorLocationWithTallImageWideViewer', function () { + assessNavigatorViewerPlacement({ + id:'wideexample', + prefixUrl:'/build/openseadragon/images/', + tileSources:'/test/data/tall.dzi', + showNavigator:true, + navigatorSizeRatio:0.2, + animationTime:0, + controlsFadeDelay:0, + controlsFadeLength:1 + }, + { + displayRegionLocator:'.navigator .displayregion', + navigatorLocator:'.navigator', + testAutoFade: true, + expectedAutoFade: true, + determineExpectationsAndAssessNavigatorLocation:function (seadragonProperties, testProperties) { + var mainViewerElement = $("#" + seadragonProperties.id), + navigatorElement = $(testProperties.navigatorLocator); + assessNavigatorLocation(mainViewerElement.offset().left + mainViewerElement.width() - navigatorElement.width(), + mainViewerElement.offset().top); + assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + } + }); + }); + + asyncTest('TopLeftNavigatorLocation', function () { + assessNavigatorViewerPlacement({ + id:'example', + prefixUrl:'/build/openseadragon/images/', + tileSources:'/test/data/testpattern.dzi', + showNavigationControl: false, + showNavigator:true, + navigatorSizeRatio:0.2, + navigatorPosition: 'TOP_LEFT', + animationTime:0, + controlsFadeDelay:0, + controlsFadeLength:1 + }, + { + displayRegionLocator:'.navigator .displayregion', + navigatorLocator:'.navigator', + testAutoFade: true, + expectedAutoFade: true, + determineExpectationsAndAssessNavigatorLocation:function (seadragonProperties, testProperties) { + var mainViewerElement = $("#" + seadragonProperties.id), + navigatorElement = $(testProperties.navigatorLocator); + assessNavigatorLocation(mainViewerElement.offset().left, + mainViewerElement.offset().top); + assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + } + }); + }); + + asyncTest('TopRightNavigatorLocation', function () { + assessNavigatorViewerPlacement({ + id:'example', + prefixUrl:'/build/openseadragon/images/', + tileSources:'/test/data/testpattern.dzi', + showNavigationControl: false, + showNavigator:true, + navigatorSizeRatio:0.2, + navigatorPosition: 'TOP_RIGHT', + animationTime:0, + controlsFadeDelay:0, + controlsFadeLength:1 + }, + { + displayRegionLocator:'.navigator .displayregion', + navigatorLocator:'.navigator', + testAutoFade: true, + expectedAutoFade: true, + determineExpectationsAndAssessNavigatorLocation:function (seadragonProperties, testProperties) { + var mainViewerElement = $("#" + seadragonProperties.id), + navigatorElement = $(testProperties.navigatorLocator); + assessNavigatorLocation(mainViewerElement.offset().left + mainViewerElement.width() - navigatorElement.width(), + mainViewerElement.offset().top); + assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + } + }); + }); + + asyncTest('BottomLeftNavigatorLocation', function () { + assessNavigatorViewerPlacement({ + id:'example', + prefixUrl:'/build/openseadragon/images/', + tileSources:'/test/data/testpattern.dzi', + showNavigationControl: false, + showNavigator:true, + navigatorSizeRatio:0.2, + navigatorPosition: 'BOTTOM_LEFT', + animationTime:0, + controlsFadeDelay:0, + controlsFadeLength:1 + }, + { + displayRegionLocator:'.navigator .displayregion', + navigatorLocator:'.navigator', + testAutoFade: true, + expectedAutoFade: true, + determineExpectationsAndAssessNavigatorLocation:function (seadragonProperties, testProperties) { + var mainViewerElement = $("#" + seadragonProperties.id), + navigatorElement = $(testProperties.navigatorLocator); + assessNavigatorLocation(mainViewerElement.offset().left, + mainViewerElement.offset().top + mainViewerElement.height() - navigatorElement.height()); + assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + } + }); + }); + + asyncTest('BottomRightNavigatorLocation', function () { + assessNavigatorViewerPlacement({ + id:'example', + prefixUrl:'/build/openseadragon/images/', + tileSources:'/test/data/testpattern.dzi', + showNavigationControl: false, + showNavigator:true, + navigatorSizeRatio:0.2, + navigatorPosition: 'BOTTOM_RIGHT', + animationTime:0, + controlsFadeDelay:0, + controlsFadeLength:1 + }, + { + displayRegionLocator:'.navigator .displayregion', + navigatorLocator:'.navigator', + testAutoFade: true, + expectedAutoFade: true, + determineExpectationsAndAssessNavigatorLocation:function (seadragonProperties, testProperties) { + var mainViewerElement = $("#" + seadragonProperties.id), + navigatorElement = $(testProperties.navigatorLocator); + assessNavigatorLocation(mainViewerElement.offset().left + mainViewerElement.width() - navigatorElement.width(), + mainViewerElement.offset().top + mainViewerElement.height() - navigatorElement.height()); + assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + } + }); + }); + + asyncTest('AbsoluteNavigatorLocation', function () { + assessNavigatorViewerPlacement({ + id:'example', + prefixUrl:'/build/openseadragon/images/', + tileSources:'/test/data/testpattern.dzi', + showNavigationControl: false, + showNavigator:true, + navigatorPosition: 'ABSOLUTE', + navigatorTop: 10, + navigatorLeft: 10, + navigatorHeight: 150, + navigatorWidth: 175, + animationTime:0, + controlsFadeDelay:0, + controlsFadeLength:1 + }, + { + displayRegionLocator:'.navigator .displayregion', + navigatorLocator:'.navigator', + testAutoFade: true, + expectedAutoFade: true, + determineExpectationsAndAssessNavigatorLocation:function (seadragonProperties, testProperties) { + var mainViewerElement = $("#" + seadragonProperties.id), + navigatorElement = $(testProperties.navigatorLocator); + assessNavigatorLocation(mainViewerElement.offset().left + seadragonProperties.navigatorLeft, + mainViewerElement.offset().top + seadragonProperties.navigatorTop); + assessNavigatorSize(seadragonProperties.navigatorWidth, seadragonProperties.navigatorHeight); + } + }); + }); + + asyncTest('CustomNavigatorElementWithWideImageWideViewer', function () { assessNavigatorViewerPlacement({ id:'wideexample', navigatorId:'exampleNavigator', @@ -416,8 +604,20 @@ QUnit.config.autostart = false; }); }); - asyncTest('CustomDialogNavigatorLocationWithTallImageTallViewer', function () { - $('#exampleNavigator').dialog(); + asyncTest('CustomDialogNavigatorElementWithTallImageTallViewer', function () { + $('#exampleNavigator').dialog({ width: 200, + height:200, + open: function (event, ui) { + $('#exampleNavigator').width(200); + $('#exampleNavigator').height(200); + }, + resize: function (event, ui) { + //ui.size.width + //ui.size.height + //$('#exampleNavigator').dialog("option", "width", 200); + //$('#exampleNavigator').dialog("option", "width", 200); + } + }); assessNavigatorViewerPlacement({ id:'tallexample', navigatorId:'exampleNavigator', @@ -440,30 +640,7 @@ QUnit.config.autostart = false; var jqueryDialog = $(testProperties.navigatorLocator); assessNavigatorLocation(jqueryDialog.offset().left, jqueryDialog.offset().top); - } - }); - }); - - asyncTest('DefaultNavigatorLocationWithTallImageWideViewer', function () { - assessNavigatorViewerPlacement({ - id:'wideexample', - prefixUrl:'/build/openseadragon/images/', - tileSources:'/test/data/tall.dzi', - showNavigator:true, - animationTime:0, - controlsFadeDelay:0, - controlsFadeLength:1 - }, - { - displayRegionLocator:'.navigator .displayregion', - navigatorLocator:'.navigator', - testAutoFade: true, - expectedAutoFade: true, - determineExpectationsAndAssessNavigatorLocation:function (seadragonProperties, testProperties) { - var mainViewerElement = $("#" + seadragonProperties.id), - navigatorElement = $(testProperties.navigatorLocator); - assessNavigatorLocation(mainViewerElement.offset().left + mainViewerElement.width() - navigatorElement.width(), - mainViewerElement.offset().top); + assessNavigatorSize(jqueryDialog.width(), jqueryDialog.height()); } }); }); diff --git a/test/test.css b/test/test.css index eb651b16..88dca730 100644 --- a/test/test.css +++ b/test/test.css @@ -3,6 +3,11 @@ width: 500px; } +#exampleNavigator { + height: 100px; + width: 150px; +} + #wideexample { height: 300px; width: 700px; diff --git a/test/test.js b/test/test.js index 2272ea9d..e03d778e 100644 --- a/test/test.js +++ b/test/test.js @@ -51,6 +51,8 @@ }, initializeTestDOM: function () { +// style="margin:0px;padding:0px;width:100px;height:100px;overflow:hidden;" +// style="margin:0px;padding:0px;width:100%;height:100%;" $( "#qunit-fixture" ) .append( '
' ) .append( '
' ) From 5c94df34a1e37462ca73c8cfb0e960a491c6c6c7 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Thu, 16 Jan 2014 12:13:48 -0800 Subject: [PATCH 09/11] Navigator Tests Update Removed leftover comments --- test/test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test.js b/test/test.js index e03d778e..2272ea9d 100644 --- a/test/test.js +++ b/test/test.js @@ -51,8 +51,6 @@ }, initializeTestDOM: function () { -// style="margin:0px;padding:0px;width:100px;height:100px;overflow:hidden;" -// style="margin:0px;padding:0px;width:100%;height:100%;" $( "#qunit-fixture" ) .append( '
' ) .append( '
' ) From 601f533fcfd2fbf7ae4d8a84a68db727d22826c5 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Sat, 18 Jan 2014 18:19:22 -0800 Subject: [PATCH 10/11] Navigator update with tests update Navigator hosted in viewer with navigatorMaintainSizeRatio==false (the default) now maintains its area and aspect ratio. Tests added for most (all?) navigator configurations. --- src/navigator.js | 29 ++++--- test/navigator.js | 188 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 152 insertions(+), 65 deletions(-) diff --git a/src/navigator.js b/src/navigator.js index a7ae7384..ffb7102f 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -51,6 +51,7 @@ $.Navigator = function( options ){ var viewer = options.viewer, viewerSize, + navigatorSize, unneededElement; //We may need to create a new element and id if they did not @@ -190,10 +191,10 @@ $.Navigator = function( options ){ viewerSize = $.getElementSize( viewer.element ); this.element.style.height = ( viewerSize.y * options.sizeRatio ) + 'px'; this.element.style.width = ( viewerSize.x * options.sizeRatio ) + 'px'; - if ( options.maintainSizeRatio ) { - this.oldViewerSize = viewerSize; - } + this.oldViewerSize = viewerSize; } + navigatorSize = $.getElementSize( this.element ); + this.elementArea = navigatorSize.x * navigatorSize.y; } this.oldContainerSize = new $.Point( 0, 0 ); @@ -250,18 +251,26 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /* update: function( viewport ) { var viewerSize, + newWidth, + newHeight, bounds, topleft, bottomright; - if ( this.maintainSizeRatio ) { - viewerSize = $.getElementSize( this.viewer.element ); - if ( !viewerSize.equals( this.oldViewerSize ) ) { - this.element.style.height = ( viewerSize.y * this.sizeRatio ) + 'px'; - this.element.style.width = ( viewerSize.x * this.sizeRatio ) + 'px'; - this.oldViewerSize = viewerSize; - this.updateSize(); + viewerSize = $.getElementSize( this.viewer.element ); + if ( !viewerSize.equals( this.oldViewerSize ) ) { + this.oldViewerSize = viewerSize; + if ( this.maintainSizeRatio ) { + newWidth = viewerSize.x * this.sizeRatio; + newHeight = viewerSize.y * this.sizeRatio; } + else { + newWidth = Math.sqrt(this.elementArea * (viewerSize.x / viewerSize.y)); + newHeight = this.elementArea / newWidth; + } + this.element.style.width = newWidth + 'px'; + this.element.style.height = newHeight + 'px'; + this.updateSize(); } if( viewport && this.viewport ) { diff --git a/test/navigator.js b/test/navigator.js index 77927532..3b8ee0dc 100644 --- a/test/navigator.js +++ b/test/navigator.js @@ -52,21 +52,27 @@ QUnit.config.autostart = false; var assessNavigatorLocation = function (expectedX, expectedY) { var navigator = $(".navigator"); - Util.assessNumericValue(expectedX, navigator.offset().left, 10, ' Navigator x position'); - Util.assessNumericValue(expectedY, navigator.offset().top, 10, ' Navigator y position'); + Util.assessNumericValue(expectedX, navigator.offset().left, 10, ' Navigator x Position'); + Util.assessNumericValue(expectedY, navigator.offset().top, 10, ' Navigator y Position'); }; - var assessNavigatorSize = function (expectedWidth, expectedHeight) { + var assessNavigatorSize = function (expectedWidth, expectedHeight, msg) { var navigator = $(".navigator"); - Util.assessNumericValue(expectedWidth, navigator.width(), 2, ' Navigator width'); - Util.assessNumericValue(expectedHeight, navigator.height(), 2, ' Navigator height'); + Util.assessNumericValue(expectedWidth, navigator.width(), 2, ' Navigator Width ' + (msg ? msg : '')); + Util.assessNumericValue(expectedHeight, navigator.height(), 2, ' Navigator Height ' + (msg ? msg : '')); }; - var assessNavigatorAspectRatio = function (expectedAspectRatio) { + var assessNavigatorAspectRatio = function (expectedAspectRatio, variance, msg) { var navigator = $(".navigator"); - Util.assessNumericValue(expectedAspectRatio, navigator.width() / navigator.height(), 0.0001, ' Navigator aspect ratio'); + Util.assessNumericValue(expectedAspectRatio, navigator.width() / navigator.height(), variance, ' Navigator Aspect Ratio ' + (msg ? msg : '')); + }; + + var assessNavigatorArea = function (expectedArea, msg) { + var navigator = $(".navigator"); + + Util.assessNumericValue(expectedArea, navigator.width() * navigator.height(), Math.max(navigator.width(), navigator.height()), ' Navigator Area ' + (msg ? msg : '')); }; var navigatorRegionBoundsInPoints = function (recalcForResize) { @@ -270,34 +276,48 @@ QUnit.config.autostart = false; simulateNavigatorDrag(viewer.navigator, delta.x * displayRegionWidth, delta.y * displayRegionHeight); }; + var resizeElement = function ($element, width, height) { + $element.width(width); + $element.height(height); + }; + var assessNavigatorViewerPlacement = function (seadragonProperties, testProperties) { var navigatorOperationScenarios = [ - {interactionOperation:clickOnNavigator("TOPRIGHT"), - assessmentOperation:assessViewerInCorner("TOPRIGHT"), - assessmentMessage:"After click on navigator on top right" }, - {interactionOperation:dragNavigatorBackToCenter, - assessmentOperation:assessViewerInCenter, - assessmentMessage:"After drag on navigator from top right" }, - {interactionOperation:clickOnNavigator("BOTTOMLEFT"), - assessmentOperation:assessViewerInCorner("BOTTOMLEFT"), - assessmentMessage:"After click on navigator on bottom left" }, - {interactionOperation:dragNavigatorBackToCenter, - assessmentOperation:assessViewerInCenter, - assessmentMessage:"After drag on navigator from bottom left" }, - {interactionOperation:clickOnNavigator("BOTTOMRIGHT"), - assessmentOperation:assessViewerInCorner("BOTTOMRIGHT"), - assessmentMessage:"After click on navigator on bottom right" }, - {interactionOperation:dragNavigatorBackToCenter, - assessmentOperation:assessViewerInCenter, - assessmentMessage:"After drag on navigator from bottom right" }, - {interactionOperation:clickOnNavigator("TOPLEFT"), - assessmentOperation:assessViewerInCorner("TOPLEFT"), - assessmentMessage:"After click on navigator on top left" }, - {interactionOperation:dragNavigatorBackToCenter, - assessmentOperation:assessViewerInCenter, - assessmentMessage:"After drag on navigator from top left" } - ], - autoFadeWaitTime = 100; + {interactionOperation:clickOnNavigator("TOPRIGHT"), + assessmentOperation:assessViewerInCorner("TOPRIGHT"), + assessmentMessage:"After click on navigator on top right" }, + {interactionOperation:dragNavigatorBackToCenter, + assessmentOperation:assessViewerInCenter, + assessmentMessage:"After drag on navigator from top right" }, + {interactionOperation:clickOnNavigator("BOTTOMLEFT"), + assessmentOperation:assessViewerInCorner("BOTTOMLEFT"), + assessmentMessage:"After click on navigator on bottom left" }, + {interactionOperation:dragNavigatorBackToCenter, + assessmentOperation:assessViewerInCenter, + assessmentMessage:"After drag on navigator from bottom left" }, + {interactionOperation:clickOnNavigator("BOTTOMRIGHT"), + assessmentOperation:assessViewerInCorner("BOTTOMRIGHT"), + assessmentMessage:"After click on navigator on bottom right" }, + {interactionOperation:dragNavigatorBackToCenter, + assessmentOperation:assessViewerInCenter, + assessmentMessage:"After drag on navigator from bottom right" }, + {interactionOperation:clickOnNavigator("TOPLEFT"), + assessmentOperation:assessViewerInCorner("TOPLEFT"), + assessmentMessage:"After click on navigator on top left" }, + {interactionOperation:dragNavigatorBackToCenter, + assessmentOperation:assessViewerInCenter, + assessmentMessage:"After drag on navigator from top left" } + ], + viewerResizeScenarios = [ + {resizeFactorX:0.5, resizeFactorY:1.0, assessmentMessage:"After Viewer Resize (50%, 100%)"}, + {resizeFactorX:1.0, resizeFactorY:0.5, assessmentMessage:"After Viewer Resize (100%, 50%)"}, + {resizeFactorX:1.0, resizeFactorY:1.0, assessmentMessage:"After Viewer Resize (100%, 100%)"} + ], + autoFadeWaitTime = 100, + navigatorElement = null, + viewerElement = null, + viewerOriginalSize = null, + navigatorOriginalSize = null; seadragonProperties.visibilityRatio = 1; viewer = OpenSeadragon(seadragonProperties); @@ -341,38 +361,89 @@ QUnit.config.autostart = false; waitForViewer(assessAfterDragOnViewer); }; + var assessAfterResizeViewer = function () { + viewer.viewport.zoomTo(viewer.viewport.getZoom() * 2); + waitForViewer(assessAfterZoomOnViewer); + }; + + var assessViewerResizeAndTakeNextStep = function (step) { + return function () { + var nextStep = step + 1; + if (seadragonProperties.navigatorId) { + // Navigator hosted in outside element...size shouldn't change + assessNavigatorSize(navigatorOriginalSize.x, navigatorOriginalSize.y, viewerResizeScenarios[step].assessmentMessage); + } + else { + // Navigator hosted in viewer + if (seadragonProperties.navigatorPosition && seadragonProperties.navigatorPosition == 'ABSOLUTE') { + // Navigator positioned 'ABSOLUTE'...size shouldn't change + assessNavigatorSize(navigatorOriginalSize.x, navigatorOriginalSize.y, viewerResizeScenarios[step].assessmentMessage); + } + else { + // Navigator positioned 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', or 'BOTTOM_RIGHT' + if (seadragonProperties.navigatorMaintainSizeRatio) { + // Navigator should maintain aspect ratio and size proportioned to viewer size + assessNavigatorAspectRatio(viewerElement.width() / viewerElement.height(), 0.0001, viewerResizeScenarios[step].assessmentMessage); + assessNavigatorSize(viewerElement.width() * seadragonProperties.navigatorSizeRatio, viewerElement.height() * seadragonProperties.navigatorSizeRatio, viewerResizeScenarios[step].assessmentMessage); + } + else { + // Navigator should maintain aspect ratio and area + // Variances are loosened up here, since 1 pixel rounding difference in resizing to maintain area + // can cause a relatively large difference in area and aspect ratio. + assessNavigatorAspectRatio(viewerElement.width() / viewerElement.height(), 0.1, viewerResizeScenarios[step].assessmentMessage); + assessNavigatorArea(navigatorOriginalSize.x * navigatorOriginalSize.y, viewerResizeScenarios[step].assessmentMessage); + } + } + } + + if (step === viewerResizeScenarios.length - 1) { + assessAfterResizeViewer(); + } + else { + resizeElement(viewerElement, viewerOriginalSize.x * viewerResizeScenarios[nextStep].resizeFactorX, viewerOriginalSize.y * viewerResizeScenarios[nextStep].resizeFactorY); + waitForViewer(assessViewerResizeAndTakeNextStep(nextStep)); + } + }; + }; + var captureInitialStateThenAct = function () { assessDisplayRegion("After image load"); testProperties.determineExpectationsAndAssessNavigatorLocation(seadragonProperties, testProperties); - viewer.viewport.zoomTo(viewer.viewport.getZoom() * 2); - waitForViewer(assessAfterZoomOnViewer); + viewerOriginalSize = new OpenSeadragon.Point(viewerElement.width(), viewerElement.height()); + navigatorOriginalSize = new OpenSeadragon.Point(navigatorElement.width(), navigatorElement.height()); + + resizeElement(viewerElement, viewerOriginalSize.x * viewerResizeScenarios[0].resizeFactorX, viewerOriginalSize.y * viewerResizeScenarios[0].resizeFactorY); + waitForViewer(assessViewerResizeAndTakeNextStep(0)); }; var assessAutoFadeTriggered = function () { - ok($(testProperties.navigatorLocator).parent().css("opacity") < 1, "Expecting navigator to be autofade when in the default location"); + ok(navigatorElement.parent().css("opacity") < 1, "Expecting navigator to be autofade when in the default location"); waitForViewer(captureInitialStateThenAct); }; var assessAutoFadeDisabled = function () { - ok($(testProperties.navigatorLocator).parent().css("opacity") > 0, "Expecting navigator to be always visible when in a custom location"); + ok(navigatorElement.parent().css("opacity") > 0, "Expecting navigator to be always visible when in a custom location"); waitForViewer(captureInitialStateThenAct); }; var openHandler = function () { viewer.removeHandler('open', openHandler); + navigatorElement = $(testProperties.navigatorLocator); + viewerElement = $("#" + seadragonProperties.id); + //TODO This should be testProperties.testAutoFade, but test hangs. Fix this! if (!testProperties.testAutohide) { waitForViewer(captureInitialStateThenAct); } else { - ok($(testProperties.navigatorLocator).parent().css("opacity") > 0, "Expecting navigator to be visible initially"); + ok(navigatorElement.parent().css("opacity") > 0, "Expecting navigator to be visible initially"); var event = { clientX:1, clientY:1 }; - $("#" + seadragonProperties.id).simulate('blur', event); + viewerrElement.simulate('blur', event); if (testProperties.expectedAutoFade) { setTimeout(assessAutoFadeTriggered,autoFadeWaitTime); @@ -391,6 +462,7 @@ QUnit.config.autostart = false; tileSources:'/test/data/wide.dzi', showNavigator:true, navigatorSizeRatio:0.2, + navigatorMaintainSizeRatio: false, animationTime:0 }, { @@ -403,7 +475,7 @@ QUnit.config.autostart = false; assessNavigatorLocation(mainViewerElement.offset().left + mainViewerElement.width() - navigatorElement.width(), mainViewerElement.offset().top); assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); - assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height(), 0.0001); } }); }); @@ -415,6 +487,7 @@ QUnit.config.autostart = false; tileSources:'/test/data/tall.dzi', showNavigator:true, navigatorSizeRatio:0.2, + navigatorMaintainSizeRatio: false, animationTime:0, controlsFadeDelay:0, controlsFadeLength:1 @@ -430,7 +503,7 @@ QUnit.config.autostart = false; assessNavigatorLocation(mainViewerElement.offset().left + mainViewerElement.width() - navigatorElement.width(), mainViewerElement.offset().top); assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); - assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height(), 0.0001); } }); }); @@ -443,6 +516,7 @@ QUnit.config.autostart = false; showNavigationControl: false, showNavigator:true, navigatorSizeRatio:0.2, + navigatorMaintainSizeRatio: false, navigatorPosition: 'TOP_LEFT', animationTime:0, controlsFadeDelay:0, @@ -459,7 +533,7 @@ QUnit.config.autostart = false; assessNavigatorLocation(mainViewerElement.offset().left, mainViewerElement.offset().top); assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); - assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height(), 0.0001); } }); }); @@ -472,6 +546,7 @@ QUnit.config.autostart = false; showNavigationControl: false, showNavigator:true, navigatorSizeRatio:0.2, + navigatorMaintainSizeRatio: true, navigatorPosition: 'TOP_RIGHT', animationTime:0, controlsFadeDelay:0, @@ -488,7 +563,7 @@ QUnit.config.autostart = false; assessNavigatorLocation(mainViewerElement.offset().left + mainViewerElement.width() - navigatorElement.width(), mainViewerElement.offset().top); assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); - assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height(), 0.0001); } }); }); @@ -501,6 +576,7 @@ QUnit.config.autostart = false; showNavigationControl: false, showNavigator:true, navigatorSizeRatio:0.2, + navigatorMaintainSizeRatio: false, navigatorPosition: 'BOTTOM_LEFT', animationTime:0, controlsFadeDelay:0, @@ -517,7 +593,7 @@ QUnit.config.autostart = false; assessNavigatorLocation(mainViewerElement.offset().left, mainViewerElement.offset().top + mainViewerElement.height() - navigatorElement.height()); assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); - assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height(), 0.0001); } }); }); @@ -530,6 +606,7 @@ QUnit.config.autostart = false; showNavigationControl: false, showNavigator:true, navigatorSizeRatio:0.2, + navigatorMaintainSizeRatio: false, navigatorPosition: 'BOTTOM_RIGHT', animationTime:0, controlsFadeDelay:0, @@ -546,7 +623,7 @@ QUnit.config.autostart = false; assessNavigatorLocation(mainViewerElement.offset().left + mainViewerElement.width() - navigatorElement.width(), mainViewerElement.offset().top + mainViewerElement.height() - navigatorElement.height()); assessNavigatorSize(mainViewerElement.width() * seadragonProperties.navigatorSizeRatio, mainViewerElement.height() * seadragonProperties.navigatorSizeRatio); - assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height()); + assessNavigatorAspectRatio(mainViewerElement.width() / mainViewerElement.height(), 0.0001); } }); }); @@ -605,18 +682,19 @@ QUnit.config.autostart = false; }); asyncTest('CustomDialogNavigatorElementWithTallImageTallViewer', function () { - $('#exampleNavigator').dialog({ width: 200, - height:200, + $('#exampleNavigator').dialog({ width: 150, + height:100, open: function (event, ui) { - $('#exampleNavigator').width(200); - $('#exampleNavigator').height(200); - }, - resize: function (event, ui) { - //ui.size.width - //ui.size.height - //$('#exampleNavigator').dialog("option", "width", 200); - //$('#exampleNavigator').dialog("option", "width", 200); + $('#exampleNavigator').width(150); + $('#exampleNavigator').height(100); } + //TODO Use this in testing resizable navigator + //resize: function (event, ui) { + // //ui.size.width + // //ui.size.height + // //$('#exampleNavigator').dialog("option", "width", 200); + // //$('#exampleNavigator').dialog("option", "width", 200); + //} }); assessNavigatorViewerPlacement({ id:'tallexample', From 6774fca39e528f6c11a4a85cf8349204fe6388dd Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Tue, 21 Jan 2014 08:44:04 -0800 Subject: [PATCH 11/11] Navigator Tests Update Added tests for resizable navigators. Fixed typo. --- test/navigator.js | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/test/navigator.js b/test/navigator.js index 3b8ee0dc..95631a91 100644 --- a/test/navigator.js +++ b/test/navigator.js @@ -75,14 +75,14 @@ QUnit.config.autostart = false; Util.assessNumericValue(expectedArea, navigator.width() * navigator.height(), Math.max(navigator.width(), navigator.height()), ' Navigator Area ' + (msg ? msg : '')); }; - var navigatorRegionBoundsInPoints = function (recalcForResize) { + var navigatorRegionBoundsInPoints = function () { var regionBoundsInPoints, expectedDisplayRegionWidth, expectedDisplayRegionHeight, expectedDisplayRegionXLocation, expectedDisplayRegionYLocation; - if (navigator === null || recalcForResize) { + if (navigator === null) { navigator = $(".navigator"); navigatorScaleFactor = Math.min(navigator.width() / viewer.viewport.contentSize.x, navigator.height() / viewer.viewport.contentSize.y); displayRegionWidth = viewer.viewport.contentSize.x * navigatorScaleFactor; @@ -117,12 +117,12 @@ QUnit.config.autostart = false; }; - var assessDisplayRegion = function (status, recalcForResize) { + var assessDisplayRegion = function (status) { if (debug) { console.log(status); } - var expectedBounds = navigatorRegionBoundsInPoints(recalcForResize); + var expectedBounds = navigatorRegionBoundsInPoints(); Util.assessNumericValue(expectedBounds.width, displayRegion.width() + viewer.navigator.totalBorderWidths.x, 2, status + ' Width synchronization'); Util.assessNumericValue(expectedBounds.height, displayRegion.height() + viewer.navigator.totalBorderWidths.y, 2, status + ' Height synchronization'); Util.assessNumericValue(expectedBounds.x, displayRegion.position().left, 2, status + ' Left synchronization'); @@ -313,6 +313,11 @@ QUnit.config.autostart = false; {resizeFactorX:1.0, resizeFactorY:0.5, assessmentMessage:"After Viewer Resize (100%, 50%)"}, {resizeFactorX:1.0, resizeFactorY:1.0, assessmentMessage:"After Viewer Resize (100%, 100%)"} ], + navigatorResizeScenarios = [ + {resizeFactorX:0.75, resizeFactorY:1.0, assessmentMessage:"After Navigator Resize (75%, 100%)"}, + {resizeFactorX:1.0, resizeFactorY:0.75, assessmentMessage:"After Navigator Resize (100%, 75%)"}, + {resizeFactorX:1.0, resizeFactorY:1.0, assessmentMessage:"After Navigator Resize (100%, 100%)"} + ], autoFadeWaitTime = 100, navigatorElement = null, viewerElement = null, @@ -361,11 +366,26 @@ QUnit.config.autostart = false; waitForViewer(assessAfterDragOnViewer); }; - var assessAfterResizeViewer = function () { + var assessAfterResizeNavigator = function () { viewer.viewport.zoomTo(viewer.viewport.getZoom() * 2); waitForViewer(assessAfterZoomOnViewer); }; + var assessNavigatorResizeAndTakeNextStep = function (step) { + return function () { + var nextStep = step + 1; + assessNavigatorSize(navigatorOriginalSize.x * navigatorResizeScenarios[step].resizeFactorX, navigatorOriginalSize.y * navigatorResizeScenarios[step].resizeFactorY, navigatorResizeScenarios[step].assessmentMessage); + assessDisplayRegion(navigatorResizeScenarios[step].assessmentMessage); + if (step === viewerResizeScenarios.length - 1) { + assessAfterResizeNavigator(); + } + else { + resizeElement(navigatorElement, navigatorOriginalSize.x * navigatorResizeScenarios[nextStep].resizeFactorX, navigatorOriginalSize.y * navigatorResizeScenarios[nextStep].resizeFactorY); + waitForViewer(assessNavigatorResizeAndTakeNextStep(nextStep)); + } + }; + }; + var assessViewerResizeAndTakeNextStep = function (step) { return function () { var nextStep = step + 1; @@ -397,7 +417,15 @@ QUnit.config.autostart = false; } if (step === viewerResizeScenarios.length - 1) { - assessAfterResizeViewer(); + if (seadragonProperties.navigatorId) { + // Navigator hosted in outside element...run navigator resize tests + resizeElement(navigatorElement, navigatorOriginalSize.x * navigatorResizeScenarios[0].resizeFactorX, navigatorOriginalSize.y * navigatorResizeScenarios[0].resizeFactorY); + waitForViewer(assessNavigatorResizeAndTakeNextStep(0)); + } + else { + // Navigator hosted in viewer...skip navigator resize tests + assessAfterResizeNavigator(); + } } else { resizeElement(viewerElement, viewerOriginalSize.x * viewerResizeScenarios[nextStep].resizeFactorX, viewerOriginalSize.y * viewerResizeScenarios[nextStep].resizeFactorY); @@ -443,7 +471,7 @@ QUnit.config.autostart = false; clientY:1 }; - viewerrElement.simulate('blur', event); + viewerElement.simulate('blur', event); if (testProperties.expectedAutoFade) { setTimeout(assessAutoFadeTriggered,autoFadeWaitTime);