From 54af53cf4e86091d0ab50e5f192f06b8bbd174c1 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 7 Dec 2022 17:46:25 -0500 Subject: [PATCH 1/7] 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 From 2afd61b05d2067648ac1e36dba489f8c4dea5485 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 8 Dec 2022 23:12:28 -0500 Subject: [PATCH 2/7] updates to work in progress --- src/viewer.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/viewer.js b/src/viewer.js index 4dbec3c7..b7a1362f 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -330,7 +330,7 @@ $.Viewer = function( options ) { this._onViewerResize = onViewerResize; this._origViewerResize = origViewerResize; //for testing logic changes - if(ResizeObserver){ + if(window.ResizeObserver){ this._autoResizePolling = false; this._resizeObserver = new ResizeObserver(function(){ @@ -1700,15 +1700,10 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, }, /** - * 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. + * Force the viewer to reset its size to match its container. */ - forceResize: function(ignoreAutoResizeSetting) { - if(ignoreAutoResizeSetting || this.autoResize){ - this._onViewerResize(this, _getSafeElemSize(this.container)); - } - return this; + forceImmediateResize: function() { + this._onViewerResize(this, _getSafeElemSize(this.container)); }, /** From 69297c01815723f8b4927c0cc808fcecccd85e92 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 13 Dec 2022 16:49:23 -0500 Subject: [PATCH 3/7] Updated resize behavior --- src/viewer.js | 40 +++++++++---- test/demo/resizeviewer.html | 114 ++++++++++-------------------------- 2 files changed, 59 insertions(+), 95 deletions(-) diff --git a/src/viewer.js b/src/viewer.js index b7a1362f..4af8a714 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -204,6 +204,7 @@ $.Viewer = function( options ) { prevContainerSize: null, animating: false, forceRedraw: false, + needsResize: false, mouseInside: false, group: null, // whether we should be continuously zooming @@ -332,10 +333,9 @@ $.Viewer = function( options ) { this._origViewerResize = origViewerResize; //for testing logic changes if(window.ResizeObserver){ this._autoResizePolling = false; - this._resizeObserver = new ResizeObserver(function(){ if(_this.autoResize){ - _this._onViewerResize(_this, _getSafeElemSize(_this.container)); + THIS[_this.hash].needsResize = true; } }); @@ -1702,8 +1702,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, /** * Force the viewer to reset its size to match its container. */ - forceImmediateResize: function() { - this._onViewerResize(this, _getSafeElemSize(this.container)); + forceResize: function() { + THIS[this.hash].needsResize = true; }, /** @@ -3594,18 +3594,25 @@ function origViewerResize(viewer, containerSize){ } 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); + var resizeRatio; if (viewer.preserveImageSizeOnResize) { - viewport.zoomTo(zoom * resizeRatio, null, true); + resizeRatio = THIS[viewer.hash].prevContainerSize.x / containerSize.x; + // viewport.zoomTo(zoom * resizeRatio, null, true); } else { - viewport.zoomTo(zoom, null, true); + var o = new $.Point(0, 0); + var prevDiag = new $.Point(THIS[viewer.hash].prevContainerSize.x, THIS[viewer.hash].prevContainerSize.y).distanceTo(o); + var newDiag = new $.Point(containerSize.x, containerSize.y).distanceTo(o); + resizeRatio = newDiag / prevDiag * THIS[viewer.hash].prevContainerSize.x / containerSize.x; + // viewport.zoomTo(zoom, null, true); } + viewport.zoomTo(zoom * resizeRatio, null, true); THIS[viewer.hash].prevContainerSize = containerSize; THIS[viewer.hash].forceRedraw = true; + THIS[viewer.hash].needsResize = false; } function updateOnce( viewer ) { @@ -3614,14 +3621,23 @@ function updateOnce( viewer ) { if (viewer._opening || !THIS[viewer.hash]) { return; } - if (viewer.autoResize && viewer._autoResizePolling){ - var containerSize = _getSafeElemSize(viewer.container); - var prevContainerSize = THIS[viewer.hash].prevContainerSize; - if (!containerSize.equals(prevContainerSize)) { - viewer._onViewerResize(viewer, containerSize); + if (viewer.autoResize){ + var containerSize; + if(viewer._autoResizePolling){ + containerSize = _getSafeElemSize(viewer.container); + var prevContainerSize = THIS[viewer.hash].prevContainerSize; + if (!containerSize.equals(prevContainerSize)) { + THIS[viewer.hash].needsResize = true; + } } + if(THIS[viewer.hash].needsResize){ + viewer._onViewerResize(viewer, containerSize || _getSafeElemSize(viewer.container)); + } + } + + var viewportChange = viewer.viewport.update(); var animated = viewer.world.update() || viewportChange; diff --git a/test/demo/resizeviewer.html b/test/demo/resizeviewer.html index 9341feb7..74777552 100644 --- a/test/demo/resizeviewer.html +++ b/test/demo/resizeviewer.html @@ -4,6 +4,8 @@ OpenSeadragon Viewer Resizing Demo + +