From 5b2c6d7ed9448ff431e3857074bf8afffcdd9687 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 9 Feb 2024 15:06:52 -0500 Subject: [PATCH 1/4] add support for placeholderFillStyle to webgl drawer. fix spring logic to avoid getting stuck updating due to floating point math. update tilesource-swap demo. --- src/spring.js | 32 +++++++++++++++++--------------- src/webgldrawer.js | 28 ++++++++++++++++++++++++++++ test/demo/tilesource-swap.html | 17 ++++++++--------- 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/src/spring.js b/src/spring.js index f65f076e..77162188 100644 --- a/src/spring.js +++ b/src/spring.js @@ -212,7 +212,7 @@ $.Spring.prototype = { update: function() { this.current.time = $.now(); - var startValue, targetValue; + let startValue, targetValue; if (this._exponential) { startValue = this.start._logValue; targetValue = this.target._logValue; @@ -221,23 +221,25 @@ $.Spring.prototype = { targetValue = this.target.value; } - var currentValue = (this.current.time >= this.target.time) ? - targetValue : - startValue + - ( targetValue - startValue ) * - transform( - this.springStiffness, - ( this.current.time - this.start.time ) / - ( this.target.time - this.start.time ) - ); - - if (this._exponential) { - this.current.value = Math.exp(currentValue); + if(this.current.time >= this.target.time){ + this.current.value = this.target.value; } else { - this.current.value = currentValue; + let currentValue = startValue + + ( targetValue - startValue ) * + transform( + this.springStiffness, + ( this.current.time - this.start.time ) / + ( this.target.time - this.start.time ) + ); + + if (this._exponential) { + this.current.value = Math.exp(currentValue); + } else { + this.current.value = currentValue; + } } - return currentValue !== targetValue; + return this.current.value !== this.target.value; }, /** diff --git a/src/webgldrawer.js b/src/webgldrawer.js index bf40266d..67834f4c 100644 --- a/src/webgldrawer.js +++ b/src/webgldrawer.js @@ -239,6 +239,10 @@ let tilesToDraw = tiledImage.getTilesToDraw(); + if ( tiledImage.placeholderFillStyle && tiledImage._hasOpaqueTile === false ) { + this._drawPlaceholder(tiledImage); + } + if(tilesToDraw.length === 0 || tiledImage.getOpacity() === 0){ return; } @@ -1077,6 +1081,30 @@ context.restore(); } + _drawPlaceholder(tiledImage){ + + const bounds = tiledImage.getBounds(true); + const rect = this.viewportToDrawerRectangle(tiledImage.getBounds(true)); + const context = this._outputContext; + + let fillStyle; + if ( typeof tiledImage.placeholderFillStyle === "function" ) { + fillStyle = tiledImage.placeholderFillStyle(tiledImage, context); + } + else { + fillStyle = tiledImage.placeholderFillStyle; + } + + context.save(); + context.fillStyle = fillStyle; + context.translate(rect.x, rect.y); + context.rotate(Math.PI / 180 * bounds.degrees); + context.translate(-rect.x, -rect.y); + context.fillRect(rect.x, rect.y, rect.width, rect.height); + context.restore(); + + } + // private _restoreRotationChanges() { var context = this._outputContext; diff --git a/test/demo/tilesource-swap.html b/test/demo/tilesource-swap.html index 5b1f6dee..f5fbc084 100644 --- a/test/demo/tilesource-swap.html +++ b/test/demo/tilesource-swap.html @@ -32,17 +32,18 @@ type: 'legacy-image-pyramid', levels: [ { - url: 'http://openseadragon.github.io/example-images/duomo/duomo_files/8/0_0.jpg', + url: 'https://openseadragon.github.io/example-images/duomo/duomo_files/8/0_0.jpg', width: 218, height: 160 } - ] + ], + degrees: 30, }; var duomo = { Image: { xmlns: 'http://schemas.microsoft.com/deepzoom/2008', - Url: 'http://openseadragon.github.io/example-images/duomo/duomo_files/', + Url: 'https://openseadragon.github.io/example-images/duomo/duomo_files/', Format: 'jpg', Overlap: '2', TileSize: '256', @@ -59,10 +60,11 @@ tileSources: duomoStandin, minZoomImageRatio: 0.1, defaultZoomLevel: 0.1, - zoomPerClick: 1 + zoomPerClick: 1, + crossOriginPolicy: 'Anonymous' }); - viewer.addHandler('canvas-click', function(event) { + viewer.addOnceHandler('canvas-click', function(event) { if (event.quick) { var standin = viewer.world.getItemAt(0); var standinBounds = standin.getBounds(); @@ -76,13 +78,10 @@ index: 0, // Add the new image below the stand-in. success: function(event) { var fullImage = event.item; - - // The changeover will look better if we wait for the first tile to be drawn. + // The changeover will look better if we wait for the first draw after the changeover. var tileDrawnHandler = function(event) { - if (event.tiledImage === fullImage) { viewer.removeHandler('update-viewport', tileDrawnHandler); viewer.world.removeItem(standin); - } }; viewer.addHandler('update-viewport', tileDrawnHandler); From d4e82d374e3633190ed618e434d0bba9fe7e8137 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 9 Feb 2024 15:19:40 -0500 Subject: [PATCH 2/4] account for viewport rotation in addition to tiledImage rotation --- src/webgldrawer.js | 9 ++++++--- test/demo/tilesource-swap.html | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/webgldrawer.js b/src/webgldrawer.js index 67834f4c..d8b33f93 100644 --- a/src/webgldrawer.js +++ b/src/webgldrawer.js @@ -242,7 +242,10 @@ if ( tiledImage.placeholderFillStyle && tiledImage._hasOpaqueTile === false ) { this._drawPlaceholder(tiledImage); } - + this._drawPlaceholder(tiledImage); + if(!window.draw){ + return; + } if(tilesToDraw.length === 0 || tiledImage.getOpacity() === 0){ return; } @@ -1095,13 +1098,13 @@ fillStyle = tiledImage.placeholderFillStyle; } - context.save(); + this._offsetForRotation({degrees: this.viewer.viewport.getRotation(true)}); context.fillStyle = fillStyle; context.translate(rect.x, rect.y); context.rotate(Math.PI / 180 * bounds.degrees); context.translate(-rect.x, -rect.y); context.fillRect(rect.x, rect.y, rect.width, rect.height); - context.restore(); + this._restoreRotationChanges(); } diff --git a/test/demo/tilesource-swap.html b/test/demo/tilesource-swap.html index f5fbc084..d8da3dfb 100644 --- a/test/demo/tilesource-swap.html +++ b/test/demo/tilesource-swap.html @@ -64,8 +64,10 @@ crossOriginPolicy: 'Anonymous' }); - viewer.addOnceHandler('canvas-click', function(event) { - if (event.quick) { + let swapped = false; + viewer.addHandler('canvas-click', function(event) { + if (event.quick && !swapped) { + swapped = true; var standin = viewer.world.getItemAt(0); var standinBounds = standin.getBounds(); viewer.viewport.fitBounds(standinBounds); From c734de531fd94cbbd912f96be046b953ccf65399 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 9 Feb 2024 17:18:54 -0500 Subject: [PATCH 3/4] fix placeholder positioning for canvas drawer --- src/canvasdrawer.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/canvasdrawer.js b/src/canvasdrawer.js index d4ec6231..2ec6b17b 100644 --- a/src/canvasdrawer.js +++ b/src/canvasdrawer.js @@ -382,9 +382,9 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{ } usedClip = true; } - + tiledImage._hasOpaqueTile = false; if ( tiledImage.placeholderFillStyle && tiledImage._hasOpaqueTile === false ) { - var placeholderRect = this.viewportToDrawerRectangle(tiledImage.getBounds(true)); + let placeholderRect = this.viewportToDrawerRectangle(tiledImage.getBoundsNoRotate(true)); if (sketchScale) { placeholderRect = placeholderRect.times(sketchScale); } @@ -392,7 +392,7 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{ placeholderRect = placeholderRect.translate(sketchTranslate); } - var fillStyle = null; + let fillStyle = null; if ( typeof tiledImage.placeholderFillStyle === "function" ) { fillStyle = tiledImage.placeholderFillStyle(tiledImage, this.context); } @@ -402,7 +402,9 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{ this._drawRectangle(placeholderRect, fillStyle, useSketch); } - + if(!window.draw){ + lastDrawn = []; + } var subPixelRoundingRule = determineSubPixelRoundingRule(tiledImage.subPixelRoundingForTransparency); var shouldRoundPositionAndSize = false; From 3f21f84df436fde7bbd435a8602856ceea0f9d8e Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 9 Feb 2024 18:16:30 -0500 Subject: [PATCH 4/4] clean up code added for testing --- src/canvasdrawer.js | 4 +--- src/webgldrawer.js | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/canvasdrawer.js b/src/canvasdrawer.js index 2ec6b17b..6a00a294 100644 --- a/src/canvasdrawer.js +++ b/src/canvasdrawer.js @@ -402,9 +402,7 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{ this._drawRectangle(placeholderRect, fillStyle, useSketch); } - if(!window.draw){ - lastDrawn = []; - } + var subPixelRoundingRule = determineSubPixelRoundingRule(tiledImage.subPixelRoundingForTransparency); var shouldRoundPositionAndSize = false; diff --git a/src/webgldrawer.js b/src/webgldrawer.js index d8b33f93..ac450b3c 100644 --- a/src/webgldrawer.js +++ b/src/webgldrawer.js @@ -242,10 +242,7 @@ if ( tiledImage.placeholderFillStyle && tiledImage._hasOpaqueTile === false ) { this._drawPlaceholder(tiledImage); } - this._drawPlaceholder(tiledImage); - if(!window.draw){ - return; - } + if(tilesToDraw.length === 0 || tiledImage.getOpacity() === 0){ return; }