diff --git a/changelog.txt b/changelog.txt index af542783..582f2d53 100644 --- a/changelog.txt +++ b/changelog.txt @@ -58,7 +58,7 @@ OPENSEADRAGON CHANGELOG * Explicitly set passive:false for wheel event handlers to suppress console warnings. Fixes #1669 (#2043 @msalsbery) * Viewer's canvas-click events now include an originalTarget property so you can know which element received the click (#2037 @iangilman) * Added method for getting the size of an image in window coordinates (#2049 @superbland) -* Fixed an issue with TileSource's getLevelScale that would arise if you changed maxLevel (#2059 @kim-sanghoon) +* Added a setMaxLevel function to TileSource so you can change its maxLevel if needed (#2059, #2066 @kim-sanghoon) 2.4.2: diff --git a/src/tilesource.js b/src/tilesource.js index 32f10da8..32df56cf 100644 --- a/src/tilesource.js +++ b/src/tilesource.js @@ -275,28 +275,43 @@ $.TileSource.prototype = { return this._tileHeight; }, + /** + * Set the maxLevel to the given level, and perform the memoization of + * getLevelScale with the new maxLevel. This function can be useful if the + * memoization is required before the first call of getLevelScale, or both + * memoized getLevelScale and maxLevel should be changed accordingly. + * @function + * @param {Number} level + */ + setMaxLevel: function( level ) { + this.maxLevel = level; + this._memoizeLevelScale(); + }, + /** * @function * @param {Number} level */ getLevelScale: function( level ) { + // if getLevelScale is not memoized, we generate the memoized version + // at the first call and return the result + this._memoizeLevelScale(); + return this.getLevelScale( level ); + }, + // private + _memoizeLevelScale: function() { // see https://github.com/openseadragon/openseadragon/issues/22 // we use the tilesources implementation of getLevelScale to generate // a memoized re-implementation - var maxLevel = Math.ceil( - Math.log( Math.max( this.dimensions.x, this.dimensions.y ) ) / - Math.log( 2 ) - ), - levelScaleCache = {}, + var levelScaleCache = {}, i; - for( i = 0; i <= maxLevel; i++ ){ - levelScaleCache[ i ] = 1 / Math.pow(2, maxLevel - i); + for( i = 0; i <= this.maxLevel; i++ ){ + levelScaleCache[ i ] = 1 / Math.pow(2, this.maxLevel - i); } this.getLevelScale = function( _level ){ return levelScaleCache[ _level ]; }; - return this.getLevelScale( level ); }, /** diff --git a/test/modules/tilesource.js b/test/modules/tilesource.js index 16fbb292..2f752c4a 100644 --- a/test/modules/tilesource.js +++ b/test/modules/tilesource.js @@ -128,8 +128,6 @@ assert.equal(tileSource.maxLevel, 12, 'The initial max level should be 12.'); - tileSource.maxLevel = 9; - function assertLevelScale(level, expected) { var actual = tileSource.getLevelScale(level); assert.ok(Math.abs(actual - expected) < Number.EPSILON, "The scale at level " + level + @@ -141,6 +139,13 @@ assertLevelScale(10, 1 / 4); assertLevelScale(8, 1 / 16); assertLevelScale(6, 1 / 64); + + tileSource.setMaxLevel(9); + + assertLevelScale(9, 1); + assertLevelScale(7, 1 / 4); + assertLevelScale(5, 1 / 16); + assertLevelScale(3, 1 / 64); }); }());