Merge branch 'master' into ms-reference-strip

This commit is contained in:
Mark Salsbery 2024-06-06 14:07:08 -07:00
commit b1f3434bc7
6 changed files with 59 additions and 59 deletions

View File

@ -5,7 +5,7 @@ OPENSEADRAGON CHANGELOG
* BREAKING CHANGE: Dropped support for IE11 (#2300, #2361 @AndrewADev) * BREAKING CHANGE: Dropped support for IE11 (#2300, #2361 @AndrewADev)
* DEPRECATION: The OpenSeadragon.createCallback function is no longer recommended (#2367 @akansjain) * DEPRECATION: The OpenSeadragon.createCallback function is no longer recommended (#2367 @akansjain)
* The viewer now uses WebGL when available (#2310, #2462, #2466, #2468, #2469, #2472, #2478, #2488, #2492 @pearcetm, @Aiosa, @thec0keman) * The viewer now uses WebGL when available (#2310, #2462, #2466, #2468, #2469, #2472, #2478, #2488, #2492, #2521, #2537 @pearcetm, @Aiosa, @thec0keman)
* Added webp to supported image formats (#2455 @BeebBenjamin) * Added webp to supported image formats (#2455 @BeebBenjamin)
* Introduced maxTilesPerFrame option to allow loading more tiles simultaneously (#2387 @jetic83) * Introduced maxTilesPerFrame option to allow loading more tiles simultaneously (#2387 @jetic83)
* Now when creating a viewer or navigator, we leave its position style alone if possible (#2393 @VIRAT9358) * Now when creating a viewer or navigator, we leave its position style alone if possible (#2393 @VIRAT9358)
@ -20,6 +20,8 @@ OPENSEADRAGON CHANGELOG
* Fixed: placeholderFillStyle didn't work properly when the image was rotated (#2469 @pearcetm) * Fixed: placeholderFillStyle didn't work properly when the image was rotated (#2469 @pearcetm)
* Fixed: Sometimes exponential springs wouldn't ever settle (#2469 @pearcetm) * Fixed: Sometimes exponential springs wouldn't ever settle (#2469 @pearcetm)
* Fixed: The navigator wouldn't update its tracking rectangle when the navigator was resized (#2491 @pearcetm) * Fixed: The navigator wouldn't update its tracking rectangle when the navigator was resized (#2491 @pearcetm)
* Fixed: The drawer would improperly crop when the viewport was flipped and a tiled image was rotated (#2511 @pearcetm, @eug-L)
* Fixed: Flipped viewport caused image to be flipped again when going fullscreen or resizing (#2518 @pearcetm)
4.1.1: 4.1.1:

View File

@ -80,8 +80,6 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
// Canvas default is "true", so this will only be changed if user specifies "false" in the options or via setImageSmoothinEnabled. // Canvas default is "true", so this will only be changed if user specifies "false" in the options or via setImageSmoothinEnabled.
this._imageSmoothingEnabled = true; this._imageSmoothingEnabled = true;
this._viewportFlipped = false;
// Since the tile-drawn and tile-drawing events are fired by this drawer, make sure handlers can be added for them // Since the tile-drawn and tile-drawing events are fired by this drawer, make sure handlers can be added for them
this.viewer.allowEventHandler("tile-drawn"); this.viewer.allowEventHandler("tile-drawn");
this.viewer.allowEventHandler("tile-drawing"); this.viewer.allowEventHandler("tile-drawing");
@ -118,7 +116,6 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
this._prepareNewFrame(); // prepare to draw a new frame this._prepareNewFrame(); // prepare to draw a new frame
if(this.viewer.viewport.getFlip() !== this._viewportFlipped){ if(this.viewer.viewport.getFlip() !== this._viewportFlipped){
this._flip(); this._flip();
this._viewportFlipped = !this._viewportFlipped;
} }
for(const tiledImage of tiledImages){ for(const tiledImage of tiledImages){
if (tiledImage.opacity !== 0) { if (tiledImage.opacity !== 0) {
@ -147,10 +144,12 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
} }
/** /**
* @param {TiledImage} tiledImage the tiled image that is calling the function
* @returns {Boolean} Whether this drawer requires enforcing minimum tile overlap to avoid showing seams. * @returns {Boolean} Whether this drawer requires enforcing minimum tile overlap to avoid showing seams.
* @private
*/ */
minimumOverlapRequired() { minimumOverlapRequired(tiledImage) {
return true; return true;
} }
@ -189,6 +188,14 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
context.restore(); context.restore();
} }
/**
* Test whether the current context is flipped or not
* @private
*/
get _viewportFlipped(){
return this.context.getTransform().a < 0;
}
/** /**
* Fires the tile-drawing event. * Fires the tile-drawing event.
* @private * @private

View File

@ -141,12 +141,13 @@ OpenSeadragon.DrawerBase = class DrawerBase{
} }
/** /**
* @param {TiledImage} tiledImage the tiled image that is calling the function
* @returns {Boolean} Whether this drawer requires enforcing minimum tile overlap to avoid showing seams. * @returns {Boolean} Whether this drawer requires enforcing minimum tile overlap to avoid showing seams.
* @private * @private
*/ */
minimumOverlapRequired() { minimumOverlapRequired(tiledImage) {
return false; return false;
} }
/** /**

View File

@ -86,11 +86,13 @@ class HTMLDrawer extends OpenSeadragon.DrawerBase{
} }
/** /**
* @param {TiledImage} tiledImage the tiled image that is calling the function
* @returns {Boolean} Whether this drawer requires enforcing minimum tile overlap to avoid showing seams. * @returns {Boolean} Whether this drawer requires enforcing minimum tile overlap to avoid showing seams.
* @private
*/ */
minimumOverlapRequired() { minimumOverlapRequired(tiledImage) {
return true; return true;
} }
/** /**
* create the HTML element (e.g. canvas, div) that the image will be drawn into * create the HTML element (e.g. canvas, div) that the image will be drawn into

View File

@ -72,8 +72,8 @@
* @param {Boolean} [options.iOSDevice] - See {@link OpenSeadragon.Options}. * @param {Boolean} [options.iOSDevice] - See {@link OpenSeadragon.Options}.
* @param {Number} [options.opacity=1] - Set to draw at proportional opacity. If zero, images will not draw. * @param {Number} [options.opacity=1] - Set to draw at proportional opacity. If zero, images will not draw.
* @param {Boolean} [options.preload=false] - Set true to load even when the image is hidden by zero opacity. * @param {Boolean} [options.preload=false] - Set true to load even when the image is hidden by zero opacity.
* @param {String} [options.compositeOperation] - How the image is composited onto other images; see compositeOperation in {@link OpenSeadragon.Options} for possible * @param {String} [options.compositeOperation] - How the image is composited onto other images;
values. * see compositeOperation in {@link OpenSeadragon.Options} for possible values.
* @param {Boolean} [options.debugMode] - See {@link OpenSeadragon.Options}. * @param {Boolean} [options.debugMode] - See {@link OpenSeadragon.Options}.
* @param {String|CanvasGradient|CanvasPattern|Function} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}. * @param {String|CanvasGradient|CanvasPattern|Function} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}.
* @param {String|Boolean} [options.crossOriginPolicy] - See {@link OpenSeadragon.Options}. * @param {String|Boolean} [options.crossOriginPolicy] - See {@link OpenSeadragon.Options}.
@ -1081,7 +1081,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
// _tilesToDraw might have been updated by the update; refresh it // _tilesToDraw might have been updated by the update; refresh it
tileArray = this._tilesToDraw.flat(); tileArray = this._tilesToDraw.flat();
// mark the tiles as being drawn, so that they won't be discarded from // mark the tiles as being drawn, so that they won't be discarded from
// the tileCache // the tileCache
tileArray.forEach(tileInfo => { tileArray.forEach(tileInfo => {
tileInfo.tile.beingDrawn = true; tileInfo.tile.beingDrawn = true;
@ -1312,10 +1312,9 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
// returns boolean flag of whether the image should be marked as fully loaded // returns boolean flag of whether the image should be marked as fully loaded
_updateLevelsForViewport: function(){ _updateLevelsForViewport: function(){
var levelsInterval = this._getLevelsInterval(); var levelsInterval = this._getLevelsInterval();
var lowestLevel = levelsInterval.lowestLevel; var lowestLevel = levelsInterval.lowestLevel; // the lowest level we should draw at our current zoom
var highestLevel = levelsInterval.highestLevel; var highestLevel = levelsInterval.highestLevel; // the highest level we should draw at our current zoom
var bestTiles = []; var bestTiles = [];
var haveDrawn = false;
var drawArea = this.getDrawArea(); var drawArea = this.getDrawArea();
var currentTime = $.now(); var currentTime = $.now();
@ -1339,6 +1338,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
for(let i = 0, level = highestLevel; level >= lowestLevel; level--, i++){ for(let i = 0, level = highestLevel; level >= lowestLevel; level--, i++){
levelList[i] = level; levelList[i] = level;
} }
// if a single-tile level is loaded, add that to the end of the list // if a single-tile level is loaded, add that to the end of the list
// as a fallback to use during zooming out, until a lower-res tile is // as a fallback to use during zooming out, until a lower-res tile is
// loaded // loaded
@ -1350,32 +1350,32 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
); );
if(tile && tile.isBottomMost && tile.isRightMost && tile.loaded){ if(tile && tile.isBottomMost && tile.isRightMost && tile.loaded){
levelList.push(level); levelList.push(level);
levelList.hasHigherResolutionFallback = true;
break; break;
} }
} }
// Update any level that will be drawn // Update any level that will be drawn.
// We are iterating from highest resolution to lowest resolution
// Once a level fully covers the viewport the loop is halted and
// lower-resolution levels are skipped
let useLevel = false;
for (let i = 0; i < levelList.length; i++) { for (let i = 0; i < levelList.length; i++) {
let level = levelList[i]; let level = levelList[i];
var drawLevel = false;
//Avoid calculations for draw if we have already drawn this
var currentRenderPixelRatio = this.viewport.deltaPixelsFromPointsNoRotate( var currentRenderPixelRatio = this.viewport.deltaPixelsFromPointsNoRotate(
this.source.getPixelRatio(level), this.source.getPixelRatio(level),
true true
).x * this._scaleSpring.current.value; ).x * this._scaleSpring.current.value;
if (i === levelList.length - 1 || // make sure we skip levels until currentRenderPixelRatio becomes >= minPixelRatio
(!haveDrawn && currentRenderPixelRatio >= this.minPixelRatio) ) { // but always use the last level in the list so we draw something
drawLevel = true; if (i === levelList.length - 1 || currentRenderPixelRatio >= this.minPixelRatio ) {
haveDrawn = true; useLevel = true;
} else if (!haveDrawn) { } else if (!useLevel) {
continue; continue;
} }
//Perform calculations for draw if we haven't drawn this
var targetRenderPixelRatio = this.viewport.deltaPixelsFromPointsNoRotate( var targetRenderPixelRatio = this.viewport.deltaPixelsFromPointsNoRotate(
this.source.getPixelRatio(level), this.source.getPixelRatio(level),
false false
@ -1398,10 +1398,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
); );
// Update the level and keep track of 'best' tiles to load // Update the level and keep track of 'best' tiles to load
// the bestTiles
var result = this._updateLevel( var result = this._updateLevel(
haveDrawn,
drawLevel,
level, level,
levelOpacity, levelOpacity,
levelVisibility, levelVisibility,
@ -1558,8 +1555,6 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
/** /**
* Updates all tiles at a given resolution level. * Updates all tiles at a given resolution level.
* @private * @private
* @param {Boolean} haveDrawn
* @param {Boolean} drawLevel
* @param {Number} level * @param {Number} level
* @param {Number} levelOpacity * @param {Number} levelOpacity
* @param {Number} levelVisibility * @param {Number} levelVisibility
@ -1568,8 +1563,8 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
* @param {OpenSeadragon.Tile[]} best Array of the current best tiles * @param {OpenSeadragon.Tile[]} best Array of the current best tiles
* @returns {Object} Dictionary {bestTiles: OpenSeadragon.Tile - the current "best" tiles to draw, updatedTiles: OpenSeadragon.Tile) - the updated tiles}. * @returns {Object} Dictionary {bestTiles: OpenSeadragon.Tile - the current "best" tiles to draw, updatedTiles: OpenSeadragon.Tile) - the updated tiles}.
*/ */
_updateLevel: function(haveDrawn, drawLevel, level, levelOpacity, _updateLevel: function(level, levelOpacity,
levelVisibility, drawArea, currentTime, best) { levelVisibility, drawArea, currentTime, best) {
var topLeftBound = drawArea.getBoundingBox().getTopLeft(); var topLeftBound = drawArea.getBoundingBox().getTopLeft();
var bottomRightBound = drawArea.getBoundingBox().getBottomRight(); var bottomRightBound = drawArea.getBoundingBox().getBottomRight();
@ -1583,7 +1578,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
* @type {object} * @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event. * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn. * @property {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn.
* @property {Object} havedrawn * @property {Object} havedrawn - deprecated, always true (kept for backwards compatibility)
* @property {Object} level * @property {Object} level
* @property {Object} opacity * @property {Object} opacity
* @property {Object} visibility * @property {Object} visibility
@ -1596,7 +1591,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
*/ */
this.viewer.raiseEvent('update-level', { this.viewer.raiseEvent('update-level', {
tiledImage: this, tiledImage: this,
havedrawn: haveDrawn, havedrawn: true, // deprecated, kept for backwards compatibility
level: level, level: level,
opacity: levelOpacity, opacity: levelOpacity,
visibility: levelVisibility, visibility: levelVisibility,
@ -1651,8 +1646,6 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
} }
var result = this._updateTile( var result = this._updateTile(
drawLevel,
haveDrawn,
flippedX, y, flippedX, y,
level, level,
levelVisibility, levelVisibility,
@ -1706,7 +1699,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
tileCenter = positionT.plus( sizeT.divide( 2 ) ), tileCenter = positionT.plus( sizeT.divide( 2 ) ),
tileSquaredDistance = viewportCenter.squaredDistanceTo( tileCenter ); tileSquaredDistance = viewportCenter.squaredDistanceTo( tileCenter );
if(this.viewer.drawer.minimumOverlapRequired()){ if(this.viewer.drawer.minimumOverlapRequired(this)){
if ( !overlap ) { if ( !overlap ) {
sizeC = sizeC.plus( new $.Point(1, 1)); sizeC = sizeC.plus( new $.Point(1, 1));
} }
@ -1729,8 +1722,6 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
/** /**
* Update a single tile at a particular resolution level. * Update a single tile at a particular resolution level.
* @private * @private
* @param {Boolean} haveDrawn
* @param {Boolean} drawLevel
* @param {Number} x * @param {Number} x
* @param {Number} y * @param {Number} y
* @param {Number} level * @param {Number} level
@ -1741,16 +1732,15 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
* @param {OpenSeadragon.Tile} best - The current "best" tile to draw. * @param {OpenSeadragon.Tile} best - The current "best" tile to draw.
* @returns {Object} Dictionary {bestTiles: OpenSeadragon.Tile[] - the current best tiles, tile: OpenSeadragon.Tile the current tile} * @returns {Object} Dictionary {bestTiles: OpenSeadragon.Tile[] - the current best tiles, tile: OpenSeadragon.Tile the current tile}
*/ */
_updateTile: function( haveDrawn, drawLevel, x, y, level, _updateTile: function( x, y, level,
levelVisibility, viewportCenter, numberOfTiles, currentTime, best){ levelVisibility, viewportCenter, numberOfTiles, currentTime, best){
var tile = this._getTile( var tile = this._getTile(
x, y, x, y,
level, level,
currentTime, currentTime,
numberOfTiles numberOfTiles
), );
drawTile = drawLevel;
if( this.viewer ){ if( this.viewer ){
/** /**
@ -1784,20 +1774,6 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
if (tile.loaded && tile.opacity === 1){ if (tile.loaded && tile.opacity === 1){
this._setCoverage( this.coverage, level, x, y, true ); this._setCoverage( this.coverage, level, x, y, true );
} }
if ( haveDrawn && !drawTile ) {
if ( this._isCovered( this.coverage, level, x, y ) ) {
this._setCoverage( this.coverage, level, x, y, true );
} else {
drawTile = true;
}
}
if ( !drawTile ) {
return {
bestTiles: best,
tile: tile
};
}
this._positionTile( this._positionTile(
tile, tile,
@ -2183,9 +2159,11 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
return -1; return -1;
} }
if (a.visibility === b.visibility) { if (a.visibility === b.visibility) {
// sort by smallest squared distance
return (a.squaredDistance - b.squaredDistance); return (a.squaredDistance - b.squaredDistance);
} else { } else {
return (a.visibility - b.visibility); // sort by largest visibility value
return (b.visibility - a.visibility);
} }
}); });
}, },

View File

@ -210,6 +210,16 @@
return 'webgl'; return 'webgl';
} }
/**
* @param {TiledImage} tiledImage the tiled image that is calling the function
* @returns {Boolean} Whether this drawer requires enforcing minimum tile overlap to avoid showing seams.
* @private
*/
minimumOverlapRequired(tiledImage) {
// return true if the tiled image is tainted, since the backup canvas drawer will be used.
return tiledImage.isTainted();
}
/** /**
* create the HTML element (canvas in this case) that the image will be drawn into * create the HTML element (canvas in this case) that the image will be drawn into
* @private * @private