diff --git a/src/drawer.js b/src/drawer.js index 34cf3506..be1438f3 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -49,7 +49,7 @@ var DEVICE_SCREEN = $.getWindowSize(), /** * @class Drawer - * @classdesc Handles rendering of tiles for an {@link OpenSeadragon.Viewer}. + * @classdesc Handles rendering of tiles for an {@link OpenSeadragon.Viewer}. * A new instance is created for each TileSource opened (see {@link OpenSeadragon.Viewer#drawer}). * * @memberof OpenSeadragon @@ -730,23 +730,10 @@ function loadTile( drawer, tile, time ) { } function onTileLoad( drawer, tile, time, image ) { - var insertionIndex, - cutoff, - worstTile, - worstTime, - worstLevel, - worstTileIndex, - prevTile, - prevTime, - prevLevel, - i; tile.loading = false; - if ( drawer.midUpdate ) { - $.console.warn( "Tile load callback in middle of drawing routine." ); - return; - } else if ( !image && !drawer.viewport.collectionMode ) { + if ( !image && !drawer.viewport.collectionMode ) { $.console.log( "Tile %s failed to load: %s", tile, tile.url ); if( !drawer.debugMode ){ tile.exists = false; @@ -760,47 +747,64 @@ function onTileLoad( drawer, tile, time, image ) { tile.loaded = true; tile.image = image; - insertionIndex = drawer.tilesLoaded.length; - - if ( drawer.tilesLoaded.length >= drawer.maxImageCacheCount ) { - cutoff = Math.ceil( Math.log( drawer.source.getTileSize(tile.level) ) / Math.log( 2 ) ); - - worstTile = null; - worstTileIndex = -1; - - for ( i = drawer.tilesLoaded.length - 1; i >= 0; i-- ) { - prevTile = drawer.tilesLoaded[ i ]; - - if ( prevTile.level <= drawer.cutoff || prevTile.beingDrawn ) { - continue; - } else if ( !worstTile ) { - worstTile = prevTile; - worstTileIndex = i; - continue; - } - - prevTime = prevTile.lastTouchTime; - worstTime = worstTile.lastTouchTime; - prevLevel = prevTile.level; - worstLevel = worstTile.level; - - if ( prevTime < worstTime || - ( prevTime == worstTime && prevLevel > worstLevel ) ) { - worstTile = prevTile; - worstTileIndex = i; - } + if ( drawer.tilesLoaded.length < drawer.maxImageCacheCount ) { + // always safe to append things to cache + drawer.tilesLoaded[ drawer.tilesLoaded.length ] = tile; + } + else { + // need to remove something from cache, + // make sure this doesn't happen mid update + if ( !drawer.midUpdate ) { + updateTileCache( tile, drawer ); } - - if ( worstTile && worstTileIndex >= 0 ) { - worstTile.unload(); - insertionIndex = worstTileIndex; + else { + window.setTimeout( function() { + updateTileCache( tile, drawer ); + }, 1); } } - drawer.tilesLoaded[ insertionIndex ] = tile; drawer.updateAgain = true; } +function updateTileCache( newTile, drawer ) { + var i, prevTile, prevTime, worstTime, prevLevel, worstLevel, + insertionIndex = drawer.tilesLoaded.length, + cutoff = Math.ceil( Math.log( drawer.source.getTileSize(newTile.level) ) / Math.log( 2 ) ), + worstTile = null, + worstTileIndex = -1; + + for ( i = drawer.tilesLoaded.length - 1; i >= 0; i-- ) { + prevTile = drawer.tilesLoaded[ i ]; + + if ( prevTile.level <= drawer.cutoff || prevTile.beingDrawn ) { + continue; + } else if ( !worstTile ) { + worstTile = prevTile; + worstTileIndex = i; + continue; + } + + prevTime = prevTile.lastTouchTime; + worstTime = worstTile.lastTouchTime; + prevLevel = prevTile.level; + worstLevel = worstTile.level; + + if ( prevTime < worstTime || + ( prevTime == worstTime && prevLevel > worstLevel ) ) { + worstTile = prevTile; + worstTileIndex = i; + } + } + + if ( worstTile && worstTileIndex >= 0 ) { + worstTile.unload(); + insertionIndex = worstTileIndex; + } + + drawer.tilesLoaded[ insertionIndex ] = newTile; +} + function positionTile( tile, overlap, viewport, viewportCenter, levelVisibility ){ var boundsTL = tile.bounds.getTopLeft(), diff --git a/src/imageLoader.js b/src/imageLoader.js index 0f79546c..9426fefb 100644 --- a/src/imageLoader.js +++ b/src/imageLoader.js @@ -145,7 +145,14 @@ $.ImageLoader.prototype = { else { this.jobQueue.push( newJob ); } + }, + /** + * Clear any unstarted image loading jobs from the queue. + * @method + */ + clear: function() { + this.jobQueue = []; } };