Splitting drawer into drawer/tileCache/tiledImage; adding World

This commit is contained in:
Ian Gilman 2014-08-06 13:48:18 -07:00
parent 973ef29d66
commit dbb60c0ab2
7 changed files with 603 additions and 1484 deletions

View File

@ -48,7 +48,10 @@ module.exports = function(grunt) {
"src/tile.js",
"src/overlay.js",
"src/drawer.js",
"src/viewport.js"
"src/viewport.js",
"src/tiledimage.js",
"src/tilecache.js",
"src/world.js"
];
// ----------

File diff suppressed because it is too large Load Diff

View File

@ -2224,7 +2224,8 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
debug: nullfunction,
info: nullfunction,
warn: nullfunction,
error: nullfunction
error: nullfunction,
assert: nullfunction
};

113
src/tilecache.js Normal file
View File

@ -0,0 +1,113 @@
/*
* OpenSeadragon - TileCache
*
* Copyright (C) 2009 CodePlex Foundation
* Copyright (C) 2010-2013 OpenSeadragon contributors
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of CodePlex Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
(function( $ ){
/**
* @class TileCache
* @classdesc
*/
$.TileCache = function( options ) {
options = options || {};
this._tilesLoaded = [];
this._maxImageCacheCount = options.maxImageCacheCount || $.DEFAULT_SETTINGS.maxImageCacheCount;
};
$.TileCache.prototype = /** @lends OpenSeadragon.TileCache.prototype */{
/**
* Returns the total number of tiles that have been loaded by this TileCache.
* @method
* @returns {Number} - The total number of tiles that have been loaded by
* this TileCache.
*/
numTilesLoaded: function() {
return this._tilesLoaded.length;
},
cacheTile: function( tile, cutoff ) {
cutoff = cutoff || 0;
var insertionIndex = this._tilesLoaded.length;
if ( this._tilesLoaded.length >= this._maxImageCacheCount ) {
var worstTile = null;
var worstTileIndex = -1;
var prevTile, worstTime, worstLevel, prevTime, prevLevel;
for ( var i = this._tilesLoaded.length - 1; i >= 0; i-- ) {
prevTile = this._tilesLoaded[ i ];
if ( prevTile.level <= 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;
}
}
this._tilesLoaded[ insertionIndex ] = tile;
},
/**
* Clears all tiles.
* @method
*/
reset: function() {
for ( var i = 0; i < this._tilesLoaded.length; ++i ) {
this._tilesLoaded[i].unload();
}
this._tilesLoaded = [];
}
};
}( OpenSeadragon ));

File diff suppressed because it is too large Load Diff

View File

@ -151,7 +151,7 @@ $.Viewer = function( options ) {
* @memberof OpenSeadragon.Viewer#
*/
drawer: null,
drawers: [],
world: null,
// Container inside the canvas where drawers (layers) are drawn.
drawersContainer: null,
/**
@ -554,7 +554,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
this.source = null;
this.drawer = null;
this.drawers = [];
this.world = null;
this.viewport = this.preserveViewport ? this.viewport : null;
@ -1102,11 +1102,10 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
return;
}
var drawer = new $.Drawer({
var tiledImage = new $.TiledImage({
viewer: _this,
source: tileSource,
viewport: _this.viewport,
element: _this.drawersContainer,
x: options.x,
y: options.y,
width: options.width,
@ -1126,7 +1125,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
debugMode: _this.debugMode,
debugGridColor: _this.debugGridColor
});
_this.drawers.push( drawer );
_this.world.add( tiledImage );
if ( options.level !== undefined ) {
_this.setLayerLevel( drawer, options.level );
}
@ -1971,17 +1970,16 @@ function openTileSource( viewer, source, options ) {
_this.source.overlays = _this.source.overlays || [];
_this.tileCache = new $.TileCache({
maxImageCacheCount: _this.maxImageCacheCount
});
_this.drawer = new $.Drawer({
viewer: _this,
source: _this.source,
viewport: _this.viewport,
element: _this.drawersContainer,
x: options.x,
y: options.y,
width: options.width,
height: options.height,
opacity: _this.opacity,
maxImageCacheCount: _this.maxImageCacheCount,
imageLoaderLimit: _this.imageLoaderLimit,
minZoomImageRatio: _this.minZoomImageRatio,
wrapHorizontal: _this.wrapHorizontal,
@ -1995,6 +1993,32 @@ function openTileSource( viewer, source, options ) {
debugGridColor: _this.debugGridColor,
crossOriginPolicy: _this.crossOriginPolicy
});
var tiledImage = new $.TiledImage({
viewer: _this,
source: _this.source,
viewport: _this.viewport,
drawer: _this.drawer,
tileCache: _this.tileCache,
x: options.x,
y: options.y,
width: options.width,
height: options.height,
opacity: _this.opacity,
imageLoaderLimit: _this.imageLoaderLimit,
minZoomImageRatio: _this.minZoomImageRatio,
wrapHorizontal: _this.wrapHorizontal,
wrapVertical: _this.wrapVertical,
immediateRender: _this.immediateRender,
blendTime: _this.blendTime,
alwaysBlend: _this.alwaysBlend,
minPixelRatio: _this.collectionMode ? 0 : _this.minPixelRatio,
timeout: _this.timeout,
debugMode: _this.debugMode,
debugGridColor: _this.debugGridColor,
crossOriginPolicy: _this.crossOriginPolicy
});
_this.drawers = [_this.drawer];
// Now that we have a drawer, see if it supports rotate. If not we need to remove the rotate buttons
@ -2711,7 +2735,7 @@ function updateOnce( viewer ) {
}
if ( animated ) {
updateDrawers( viewer );
updateWorld( viewer );
drawOverlays( viewer.viewport, viewer.currentOverlays, viewer.overlaysContainer );
if( viewer.navigator ){
viewer.navigator.update( viewer.viewport );
@ -2726,8 +2750,8 @@ function updateOnce( viewer ) {
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
viewer.raiseEvent( "animation" );
} else if ( THIS[ viewer.hash ].forceRedraw || drawersNeedUpdate( viewer ) ) {
updateDrawers( viewer );
} else if ( THIS[ viewer.hash ].forceRedraw || viewer.world.needsUpdate() ) {
updateWorld( viewer );
drawOverlays( viewer.viewport, viewer.currentOverlays, viewer.overlaysContainer );
if( viewer.navigator ){
viewer.navigator.update( viewer.viewport );
@ -2782,19 +2806,9 @@ function resizeViewportAndRecenter( viewer, containerSize, oldBounds, oldCenter
viewport.fitBounds( newBounds, true );
}
function updateDrawers( viewer ) {
for (var i = 0; i < viewer.drawers.length; i++ ) {
viewer.drawers[i].update();
}
}
function drawersNeedUpdate( viewer ) {
for (var i = 0; i < viewer.drawers.length; i++ ) {
if (viewer.drawers[i].needsUpdate()) {
return true;
}
}
return false;
function updateWorld( viewer ) {
viewer.drawer.clear();
viewer.world.update();
}
///////////////////////////////////////////////////////////////////////////////

164
src/world.js Normal file
View File

@ -0,0 +1,164 @@
/*
* OpenSeadragon - World
*
* Copyright (C) 2009 CodePlex Foundation
* Copyright (C) 2010-2013 OpenSeadragon contributors
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of CodePlex Foundation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
(function( $ ){
/**
* @class World
* @classdesc
*/
$.World = function( options ) {
$.console.assert( options.viewer, "[World] options.viewer is required" );
this.viewer = options.viewer;
this._items = [];
};
$.World.prototype = /** @lends OpenSeadragon.World.prototype */{
addItem: function( item ) {
this._items.push( item );
},
/**
* Get the item at the specified level.
* @param {Number} level The item to retrieve level.
* @returns {OpenSeadragon.TiledImage} The item at the specified level.
*/
getItemAt: function( level ) {
if ( level >= this._items.length ) {
throw new Error( "Level bigger than number of items." );
}
return this._items[ level ];
},
/**
* Get the level of the given item or -1 if not present.
* @param {OpenSeadragon.TiledImage} item The item.
* @returns {Number} The level of the item or -1 if not present.
*/
getLevelOfItem: function( item ) {
return $.indexOf( this._items, item );
},
/**
* Get the number of items used.
* @returns {Number} The number of items used.
*/
getItemCount: function() {
return this._items.length;
},
/**
* Change the level of a layer so that it appears over or under others.
* @param {OpenSeadragon.Drawer} drawer The underlying drawer of the changing
* level layer.
* @param {Number} level The new level
* @fires OpenSeadragon.Viewer.event:layer-level-changed
*/
setItemLevel: function( item, level ) {
var oldLevel = this.getLevelOfItem( item );
if ( level >= this._items.length ) {
throw new Error( "Level bigger than number of layers." );
}
if ( level === oldLevel || oldLevel === -1 ) {
return;
}
this._items.splice( oldLevel, 1 );
this._items.splice( level, 0, item );
/**
* Raised when the order of the layers has been changed.
* @event layer-level-changed
* @memberOf OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {OpenSeadragon.Drawer} drawer - The drawer which level has
* been changed
* @property {Number} previousLevel - The previous level of the drawer
* @property {Number} newLevel - The new level of the drawer
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
// TODO: deprecate
this.viewer.raiseEvent( 'layer-level-changed', {
drawer: item,
previousLevel: oldLevel,
newLevel: level
} );
},
/**
* Remove a layer. If there is only one layer, close the viewer.
* @function
* @param {OpenSeadragon.Drawer} drawer The underlying drawer of the layer
* to remove
* @fires OpenSeadragon.Viewer.event:remove-layer
*/
removeItem: function( item ) {
var index = this._items.indexOf( item );
if ( index === -1 ) {
return;
}
this._items.splice( index, 1 );
/**
* Raised when a layer is removed.
* @event remove-layer
* @memberOf OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {OpenSeadragon.Drawer} drawer The layer's underlying drawer.
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
// TODO: deprecate
this.raiseEvent( 'remove-layer', { drawer: item } );
},
update: function() {
for (var i = 0; i < this._items.length; i++ ) {
this._items[i].update();
}
},
needsUpdate: function() {
for (var i = 0; i < this._items.length; i++ ) {
if (this._items[i].needsUpdate()) {
return true;
}
}
return false;
}
};
}( OpenSeadragon ));