From 54af53cf4e86091d0ab50e5f192f06b8bbd174c1 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 7 Dec 2022 17:46:25 -0500 Subject: [PATCH] work in progress about viewer resize behavior --- src/viewer.js | 84 +++++++-- test/demo/resizeviewer.html | 340 ++++++++++++++++++++++++++++++++++++ 2 files changed, 406 insertions(+), 18 deletions(-) create mode 100644 test/demo/resizeviewer.html diff --git a/src/viewer.js b/src/viewer.js index 748137fe..4dbec3c7 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -328,6 +328,22 @@ $.Viewer = function( options ) { THIS[ this.hash ].prevContainerSize = _getSafeElemSize( this.container ); + this._onViewerResize = onViewerResize; + this._origViewerResize = origViewerResize; //for testing logic changes + if(ResizeObserver){ + this._autoResizePolling = false; + + this._resizeObserver = new ResizeObserver(function(){ + if(_this.autoResize){ + _this._onViewerResize(_this, _getSafeElemSize(_this.container)); + } + }); + + this._resizeObserver.observe(this.container, {}); + } else { + this._autoResizePolling = true; + } + // Create the world this.world = new $.World({ viewer: this @@ -786,6 +802,9 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, //TODO: implement this... //this.unbindSequenceControls() //this.unbindStandardControls() + if (this._resizeObserver){ + this._resizeObserver.disconnect(); + } if (this.referenceStrip) { this.referenceStrip.destroy(); @@ -1680,6 +1699,18 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, return this; }, + /** + * Force the viewer to reset it's size to it's container. + * @param Boolean ignoreAutorResizeSetting (default: false) If true, forces the resize even if Viewer.autoResize==false + * @returns {OpenSeadragon.Viewer} Chainable. + */ + forceResize: function(ignoreAutoResizeSetting) { + if(ignoreAutoResizeSetting || this.autoResize){ + this._onViewerResize(this, _getSafeElemSize(this.container)); + } + return this; + }, + /** * @function * @returns {OpenSeadragon.Viewer} Chainable. @@ -3547,7 +3578,40 @@ function updateMulti( viewer ) { viewer._updateRequestId = false; } } +function origViewerResize(viewer, containerSize){ + var viewport = viewer.viewport; + if (viewer.preserveImageSizeOnResize) { + var resizeRatio = THIS[viewer.hash].prevContainerSize.x / containerSize.x; + var zoom = viewport.getZoom() * resizeRatio; + var center = viewport.getCenter(); + viewport.resize(containerSize, false); + viewport.zoomTo(zoom, null, true); + viewport.panTo(center, true); + } else { + // maintain image position + var oldBounds = viewport.getBounds(); + viewport.resize(containerSize, true); + viewport.fitBoundsWithConstraints(oldBounds, true); + } + THIS[viewer.hash].prevContainerSize = containerSize; + THIS[viewer.hash].forceRedraw = true; +} +function onViewerResize(viewer, containerSize){ + var viewport = viewer.viewport; + var resizeRatio = THIS[viewer.hash].prevContainerSize.x / containerSize.x; + var zoom = viewport.getZoom(); + var center = viewport.getCenter(); + viewport.resize(containerSize, viewer.preserveImageSizeOnResize); + viewport.panTo(center, true); + if (viewer.preserveImageSizeOnResize) { + viewport.zoomTo(zoom * resizeRatio, null, true); + } else { + viewport.zoomTo(zoom, null, true); + } + THIS[viewer.hash].prevContainerSize = containerSize; + THIS[viewer.hash].forceRedraw = true; +} function updateOnce( viewer ) { //viewer.profiler.beginUpdate(); @@ -3555,27 +3619,11 @@ function updateOnce( viewer ) { if (viewer._opening || !THIS[viewer.hash]) { return; } - - if (viewer.autoResize) { + if (viewer.autoResize && viewer._autoResizePolling){ var containerSize = _getSafeElemSize(viewer.container); var prevContainerSize = THIS[viewer.hash].prevContainerSize; if (!containerSize.equals(prevContainerSize)) { - var viewport = viewer.viewport; - if (viewer.preserveImageSizeOnResize) { - var resizeRatio = prevContainerSize.x / containerSize.x; - var zoom = viewport.getZoom() * resizeRatio; - var center = viewport.getCenter(); - viewport.resize(containerSize, false); - viewport.zoomTo(zoom, null, true); - viewport.panTo(center, true); - } else { - // maintain image position - var oldBounds = viewport.getBounds(); - viewport.resize(containerSize, true); - viewport.fitBoundsWithConstraints(oldBounds, true); - } - THIS[viewer.hash].prevContainerSize = containerSize; - THIS[viewer.hash].forceRedraw = true; + viewer._onViewerResize(viewer, containerSize); } } diff --git a/test/demo/resizeviewer.html b/test/demo/resizeviewer.html new file mode 100644 index 00000000..9341feb7 --- /dev/null +++ b/test/demo/resizeviewer.html @@ -0,0 +1,340 @@ + + + + OpenSeadragon Viewer Resizing Demo + + + + + +
+
+
+
+
+
+
+
+ Simple demo page to show viewer behavior during resizing of the container. + The viewers' container elements are styled with width and height of 100%, + with dimensions set by CSS properties on a parent element. +
+ +

Pick options to test:

+

These options apply to both of the demo viewers on the left (top and bottom).

+
+
+
Use v3.1 resize logic
+
+
+
Use new resize logic
+
+ +
+
Use polling
+
+
+
Use ResizeObserver
+
+ +
+
preserveImageSizeOnResize: false
+
+
+
preserveImageSizeOnResize: true
+
+ +
+
autoResize: true
+
+
+
autoResize: false
+
+ +
+

Click to resize the viewer:

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
+ +
+
+

Demo: Issues with styling the viewer element when an image is opened

+

If a DOM/CSS operation is triggered by a viewer event (e.g. the 'page') event + for multi-page images, the timing of the viewer resizing itself (if autoResize=true) + can be inconsistent - sometimes before, sometimes after the image has finished loading + and the Viewport.goHome() call is generated. To ensure consistency, call viewer.forceResize() + after altering the page layout. +

+

Note: to see this in action most clearly, select the options for "preserveImageSizeOnResize: false" + and "Use polling" above. +

+
+
+
//pseudocode
+//container will change size
+setSidebarForImage();
+
+// image might not "open" at home
+// viewer.forceResize();
+                    
+
+
+
//pseudocode
+//container will change size
+setSidebarForImage();
+
+//image should always "open" at home
+viewer.forceResize();
+                    
+
+
+
+
+ + + + + \ No newline at end of file