mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-22 05:06:09 +03:00
Merge pull request #520 from openseadragon/ian
Reinstated collectionMode
This commit is contained in:
commit
1ebfc28d47
@ -6,6 +6,7 @@ OPENSEADRAGON CHANGELOG
|
|||||||
* True multi-image mode (#450)
|
* True multi-image mode (#450)
|
||||||
* BREAKING CHANGE: Navigator no longer sends an open event when its viewer opens
|
* BREAKING CHANGE: Navigator no longer sends an open event when its viewer opens
|
||||||
* BREAKING CHANGE: Viewer.drawers and Viewer.drawersContainer no longer exist
|
* BREAKING CHANGE: Viewer.drawers and Viewer.drawersContainer no longer exist
|
||||||
|
* BREAKING CHANGE: A Viewer's Drawer and Viewport are now made once per Viewer and reused for every image that Viewer opens (rather than being recreated for every open); this means if you change Viewer options between opens, the behavior is different now.
|
||||||
* DEPRECATION: use Viewer.addTiledImage instead of Viewer.addLayer
|
* DEPRECATION: use Viewer.addTiledImage instead of Viewer.addLayer
|
||||||
* addTiledImage supports positioning config properties
|
* addTiledImage supports positioning config properties
|
||||||
* DEPRECATION: use World.getItemAt instead of Viewer.getLayerAtLevel
|
* DEPRECATION: use World.getItemAt instead of Viewer.getLayerAtLevel
|
||||||
@ -19,9 +20,11 @@ OPENSEADRAGON CHANGELOG
|
|||||||
* DEPRECATION: use Drawer.clear and World.update instead of Drawer.update
|
* DEPRECATION: use Drawer.clear and World.update instead of Drawer.update
|
||||||
* DEPRECATION: the layersAspectRatioEpsilon option is no longer necessary
|
* DEPRECATION: the layersAspectRatioEpsilon option is no longer necessary
|
||||||
* DEPRECATION: Viewer's add-layer event is now World's add-item event
|
* DEPRECATION: Viewer's add-layer event is now World's add-item event
|
||||||
* DEPRECATION: Viewer's layer-level-changed event is now World's item-index-changed event
|
* DEPRECATION: Viewer's layer-level-changed event is now World's item-index-change event
|
||||||
* DEPRECATION: Viewer's remove-layer event is now World's remove-item event
|
* DEPRECATION: Viewer's remove-layer event is now World's remove-item event
|
||||||
* DEPRECATION: Viewer's add-layer-failed event is now add-item-failed
|
* DEPRECATION: Viewer's add-layer-failed event is now add-item-failed
|
||||||
|
* DEPRECATION: TileSourceCollection has been retired in favor of World
|
||||||
|
* DEPRECATION: collectionMode no longer draws outlines or reflections for items
|
||||||
* Drawer has been split into three classes:
|
* Drawer has been split into three classes:
|
||||||
* TiledImage, tile management and positioning for a single tiled image
|
* TiledImage, tile management and positioning for a single tiled image
|
||||||
* TileCache, tile caching for all images
|
* TileCache, tile caching for all images
|
||||||
|
@ -239,7 +239,7 @@ $.Navigator = function( options ){
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
viewer.world.addHandler("item-index-changed", function(event) {
|
viewer.world.addHandler("item-index-change", function(event) {
|
||||||
var item = _this.world.getItemAt(event.previousIndex);
|
var item = _this.world.getItemAt(event.previousIndex);
|
||||||
_this.world.setItemIndex(item, event.newIndex);
|
_this.world.setItemIndex(item, event.newIndex);
|
||||||
});
|
});
|
||||||
|
@ -531,12 +531,21 @@
|
|||||||
* @property {Number} [referenceStripSizeRatio=0.2]
|
* @property {Number} [referenceStripSizeRatio=0.2]
|
||||||
*
|
*
|
||||||
* @property {Boolean} [collectionMode=false]
|
* @property {Boolean} [collectionMode=false]
|
||||||
|
* Set to true to have the viewer arrange your TiledImages in a grid or line.
|
||||||
*
|
*
|
||||||
* @property {Number} [collectionRows=3]
|
* @property {Number} [collectionRows=3]
|
||||||
|
* If collectionMode is true, specifies how many rows the grid should have. Use 1 to make a line.
|
||||||
|
* If collectionLayout is 'vertical', specifies how many columns instead.
|
||||||
*
|
*
|
||||||
* @property {String} [collectionLayout='horizontal']
|
* @property {String} [collectionLayout='horizontal']
|
||||||
|
* If collectionMode is true, specifies whether to arrange vertically or horizontally.
|
||||||
*
|
*
|
||||||
* @property {Number} [collectionTileSize=800]
|
* @property {Number} [collectionTileSize=800]
|
||||||
|
* If collectionMode is true, specifies the size, in world coordinates, for each TiledImage to fit into.
|
||||||
|
* The TiledImage will be centered within a square of the specified size.
|
||||||
|
*
|
||||||
|
* @property {Number} [collectionTileMargin=80]
|
||||||
|
* If collectionMode is true, specifies the margin, in world coordinates, between each TiledImage.
|
||||||
*
|
*
|
||||||
* @property {String|Boolean} [crossOriginPolicy=false]
|
* @property {String|Boolean} [crossOriginPolicy=false]
|
||||||
* Valid values are 'Anonymous', 'use-credentials', and false. If false, canvas requests will
|
* Valid values are 'Anonymous', 'use-credentials', and false. If false, canvas requests will
|
||||||
@ -984,6 +993,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
collectionLayout: 'horizontal', //vertical
|
collectionLayout: 'horizontal', //vertical
|
||||||
collectionMode: false,
|
collectionMode: false,
|
||||||
collectionTileSize: 800,
|
collectionTileSize: 800,
|
||||||
|
collectionTileMargin: 80,
|
||||||
|
|
||||||
//PERFORMANCE SETTINGS
|
//PERFORMANCE SETTINGS
|
||||||
imageLoaderLimit: 0,
|
imageLoaderLimit: 0,
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
* or {@link OpenSeadragon.Viewer#addTiledImage} instead.
|
* or {@link OpenSeadragon.Viewer#addTiledImage} instead.
|
||||||
* @class TiledImage
|
* @class TiledImage
|
||||||
* @memberof OpenSeadragon
|
* @memberof OpenSeadragon
|
||||||
|
* @extends OpenSeadragon.EventSource
|
||||||
* @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.
|
* A new instance is created for each TileSource opened.
|
||||||
* @param {Object} options - Configuration for this TiledImage.
|
* @param {Object} options - Configuration for this TiledImage.
|
||||||
@ -68,6 +69,8 @@ $.TiledImage = function( options ) {
|
|||||||
$.console.assert( options.imageLoader, "[TiledImage] options.imageLoader is required" );
|
$.console.assert( options.imageLoader, "[TiledImage] options.imageLoader is required" );
|
||||||
$.console.assert( options.source, "[TiledImage] options.source is required" );
|
$.console.assert( options.source, "[TiledImage] options.source is required" );
|
||||||
|
|
||||||
|
$.EventSource.call( this );
|
||||||
|
|
||||||
this._tileCache = options.tileCache;
|
this._tileCache = options.tileCache;
|
||||||
delete options.tileCache;
|
delete options.tileCache;
|
||||||
|
|
||||||
@ -86,7 +89,7 @@ $.TiledImage = function( options ) {
|
|||||||
this.normHeight = options.source.dimensions.y / options.source.dimensions.x;
|
this.normHeight = options.source.dimensions.y / options.source.dimensions.x;
|
||||||
|
|
||||||
if ( options.width ) {
|
if ( options.width ) {
|
||||||
this._scale = options.width;
|
this._setScale(options.width);
|
||||||
delete options.width;
|
delete options.width;
|
||||||
|
|
||||||
if ( options.height ) {
|
if ( options.height ) {
|
||||||
@ -94,15 +97,12 @@ $.TiledImage = function( options ) {
|
|||||||
delete options.height;
|
delete options.height;
|
||||||
}
|
}
|
||||||
} else if ( options.height ) {
|
} else if ( options.height ) {
|
||||||
this._scale = options.height / this.normHeight;
|
this._setScale(options.height / this.normHeight);
|
||||||
delete options.height;
|
delete options.height;
|
||||||
} else {
|
} else {
|
||||||
this._scale = 1;
|
this._setScale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._worldWidth = this._scale;
|
|
||||||
this._worldHeight = this.normHeight * this._scale;
|
|
||||||
|
|
||||||
$.extend( true, this, {
|
$.extend( true, this, {
|
||||||
|
|
||||||
//internal state properties
|
//internal state properties
|
||||||
@ -128,7 +128,7 @@ $.TiledImage = function( options ) {
|
|||||||
}, options );
|
}, options );
|
||||||
};
|
};
|
||||||
|
|
||||||
$.TiledImage.prototype = /** @lends OpenSeadragon.TiledImage.prototype */{
|
$.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.TiledImage.prototype */{
|
||||||
/**
|
/**
|
||||||
* @returns {Boolean} Whether the TiledImage is scheduled for an update at the
|
* @returns {Boolean} Whether the TiledImage is scheduled for an update at the
|
||||||
* soonest possible opportunity.
|
* soonest possible opportunity.
|
||||||
@ -166,17 +166,89 @@ $.TiledImage.prototype = /** @lends OpenSeadragon.TiledImage.prototype */{
|
|||||||
/**
|
/**
|
||||||
* @returns {OpenSeadragon.Rect} This TiledImage's bounds in world coordinates.
|
* @returns {OpenSeadragon.Rect} This TiledImage's bounds in world coordinates.
|
||||||
*/
|
*/
|
||||||
getWorldBounds: function() {
|
getBounds: function() {
|
||||||
return new $.Rect( this._worldX, this._worldY, this._worldWidth, this._worldHeight );
|
return new $.Rect( this._worldX, this._worldY, this._worldWidth, this._worldHeight );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// deprecated
|
||||||
|
getWorldBounds: function() {
|
||||||
|
$.console.error('[TiledImage.getWorldBounds] is deprecated; use TiledImage.getBounds instead');
|
||||||
|
return this.getBounds();
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {OpenSeadragon.Point} This TiledImage's content size, in original pixels.
|
* @returns {OpenSeadragon.Point} This TiledImage's content size, in original pixels.
|
||||||
*/
|
*/
|
||||||
getContentSize: function() {
|
getContentSize: function() {
|
||||||
return new $.Point(this.source.dimensions.x, this.source.dimensions.y);
|
return new $.Point(this.source.dimensions.x, this.source.dimensions.y);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the TiledImage's position in the world.
|
||||||
|
* @param {OpenSeadragon.Point} position - The new position, in world coordinates.
|
||||||
|
* @fires OpenSeadragon.TiledImage.event:bounds-change
|
||||||
|
*/
|
||||||
|
setPosition: function(position) {
|
||||||
|
if (this._worldX === position.x && this._worldY === position.y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._worldX = position.x;
|
||||||
|
this._worldY = position.y;
|
||||||
|
this.updateAgain = true;
|
||||||
|
this._raiseBoundsChange();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the TiledImage's width in the world, adjusting the height to match based on aspect ratio.
|
||||||
|
* @param {Number} width - The new width, in world coordinates.
|
||||||
|
* @fires OpenSeadragon.TiledImage.event:bounds-change
|
||||||
|
*/
|
||||||
|
setWidth: function(width) {
|
||||||
|
if (this._worldWidth === width) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._setScale(width);
|
||||||
|
this.updateAgain = true;
|
||||||
|
this._raiseBoundsChange();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the TiledImage's height in the world, adjusting the width to match based on aspect ratio.
|
||||||
|
* @param {Number} height - The new height, in world coordinates.
|
||||||
|
* @fires OpenSeadragon.TiledImage.event:bounds-change
|
||||||
|
*/
|
||||||
|
setHeight: function(height) {
|
||||||
|
if (this._worldHeight === height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._setScale(height / this.normHeight);
|
||||||
|
this.updateAgain = true;
|
||||||
|
this._raiseBoundsChange();
|
||||||
|
},
|
||||||
|
|
||||||
|
// private
|
||||||
|
_setScale: function(scale) {
|
||||||
|
this._scale = scale;
|
||||||
|
this._worldWidth = this._scale;
|
||||||
|
this._worldHeight = this.normHeight * this._scale;
|
||||||
|
},
|
||||||
|
|
||||||
|
// private
|
||||||
|
_raiseBoundsChange: function() {
|
||||||
|
/**
|
||||||
|
* Raised when the TiledImage's bounds are changed.
|
||||||
|
* @event bounds-change
|
||||||
|
* @memberOf OpenSeadragon.TiledImage
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.World} eventSource - A reference to the TiledImage which raised the event.
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
this.raiseEvent('bounds-change');
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@ -794,8 +866,7 @@ function drawTiles( tiledImage, lastDrawn ){
|
|||||||
viewer,
|
viewer,
|
||||||
viewport,
|
viewport,
|
||||||
position,
|
position,
|
||||||
tileSource,
|
tileSource;
|
||||||
collectionTileSource;
|
|
||||||
|
|
||||||
// We need a callback to give image manipulation a chance to happen
|
// We need a callback to give image manipulation a chance to happen
|
||||||
var drawingHandler = function(args) {
|
var drawingHandler = function(args) {
|
||||||
|
@ -34,110 +34,9 @@
|
|||||||
|
|
||||||
(function( $ ){
|
(function( $ ){
|
||||||
|
|
||||||
/**
|
// deprecated
|
||||||
* @class TileSourceCollection
|
|
||||||
* @memberof OpenSeadragon
|
|
||||||
* @extends OpenSeadragon.TileSource
|
|
||||||
*/
|
|
||||||
$.TileSourceCollection = function( tileSize, tileSources, rows, layout ) {
|
$.TileSourceCollection = function( tileSize, tileSources, rows, layout ) {
|
||||||
var options;
|
$.console.error('TileSourceCollection is deprecated; use World instead');
|
||||||
|
|
||||||
if( $.isPlainObject( tileSize ) ){
|
|
||||||
options = tileSize;
|
|
||||||
}else{
|
|
||||||
options = {
|
|
||||||
tileSize: arguments[ 0 ],
|
|
||||||
tileSources: arguments[ 1 ],
|
|
||||||
rows: arguments[ 2 ],
|
|
||||||
layout: arguments[ 3 ]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !options.layout ){
|
|
||||||
options.layout = 'horizontal';
|
|
||||||
}
|
|
||||||
|
|
||||||
var minLevel = 0,
|
|
||||||
levelSize = 1.0,
|
|
||||||
tilesPerRow = Math.ceil( options.tileSources.length / options.rows ),
|
|
||||||
longSide = tilesPerRow >= options.rows ?
|
|
||||||
tilesPerRow :
|
|
||||||
options.rows;
|
|
||||||
|
|
||||||
if( 'horizontal' == options.layout ){
|
|
||||||
options.width = ( options.tileSize ) * tilesPerRow;
|
|
||||||
options.height = ( options.tileSize ) * options.rows;
|
|
||||||
} else {
|
|
||||||
options.height = ( options.tileSize ) * tilesPerRow;
|
|
||||||
options.width = ( options.tileSize ) * options.rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
options.tileOverlap = -options.tileMargin;
|
|
||||||
options.tilesPerRow = tilesPerRow;
|
|
||||||
|
|
||||||
//Set min level to avoid loading sublevels since collection is a
|
|
||||||
//different kind of abstraction
|
|
||||||
|
|
||||||
while( levelSize < ( options.tileSize ) * longSide ){
|
|
||||||
//$.console.log( '%s levelSize %s minLevel %s', options.tileSize * longSide, levelSize, minLevel );
|
|
||||||
levelSize = levelSize * 2.0;
|
|
||||||
minLevel++;
|
|
||||||
}
|
|
||||||
options.minLevel = minLevel;
|
|
||||||
|
|
||||||
//for( var name in options ){
|
|
||||||
// $.console.log( 'Collection %s %s', name, options[ name ] );
|
|
||||||
//}
|
|
||||||
|
|
||||||
$.TileSource.apply( this, [ options ] );
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$.extend( $.TileSourceCollection.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.TileSourceCollection.prototype */{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
* @param {Number} level
|
|
||||||
* @param {Number} x
|
|
||||||
* @param {Number} y
|
|
||||||
*/
|
|
||||||
getTileBounds: function( level, x, y ) {
|
|
||||||
var dimensionsScaled = this.dimensions.times( this.getLevelScale( level ) ),
|
|
||||||
px = this.tileSize * x - this.tileOverlap,
|
|
||||||
py = this.tileSize * y - this.tileOverlap,
|
|
||||||
sx = this.tileSize + 1 * this.tileOverlap,
|
|
||||||
sy = this.tileSize + 1 * this.tileOverlap,
|
|
||||||
scale = 1.0 / dimensionsScaled.x;
|
|
||||||
|
|
||||||
sx = Math.min( sx, dimensionsScaled.x - px );
|
|
||||||
sy = Math.min( sy, dimensionsScaled.y - py );
|
|
||||||
|
|
||||||
return new $.Rect( px * scale, py * scale, sx * scale, sy * scale );
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @function
|
|
||||||
*/
|
|
||||||
configure: function( data, url ){
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
* @param {Number} level
|
|
||||||
* @param {Number} x
|
|
||||||
* @param {Number} y
|
|
||||||
*/
|
|
||||||
getTileUrl: function( level, x, y ) {
|
|
||||||
//$.console.log([ level, '/', x, '_', y ].join( '' ));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}( OpenSeadragon ));
|
}( OpenSeadragon ));
|
||||||
|
@ -384,10 +384,6 @@ $.Viewer = function( options ) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.world.addHandler('add-item', function(event) {
|
this.world.addHandler('add-item', function(event) {
|
||||||
if (_this.viewport) {
|
|
||||||
_this.viewport.setHomeBounds(_this.world.getHomeBounds(), _this.world.getContentFactor());
|
|
||||||
}
|
|
||||||
|
|
||||||
// For backwards compatibility, we maintain the source property
|
// For backwards compatibility, we maintain the source property
|
||||||
_this.source = _this.world.getItemAt(0).source;
|
_this.source = _this.world.getItemAt(0).source;
|
||||||
|
|
||||||
@ -399,10 +395,6 @@ $.Viewer = function( options ) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.world.addHandler('remove-item', function(event) {
|
this.world.addHandler('remove-item', function(event) {
|
||||||
if (_this.viewport) {
|
|
||||||
_this.viewport.setHomeBounds(_this.world.getHomeBounds(), _this.world.getContentFactor());
|
|
||||||
}
|
|
||||||
|
|
||||||
// For backwards compatibility, we maintain the source property
|
// For backwards compatibility, we maintain the source property
|
||||||
if (_this.world.getItemCount()) {
|
if (_this.world.getItemCount()) {
|
||||||
_this.source = _this.world.getItemAt(0).source;
|
_this.source = _this.world.getItemAt(0).source;
|
||||||
@ -413,7 +405,13 @@ $.Viewer = function( options ) {
|
|||||||
THIS[ _this.hash ].forceRedraw = true;
|
THIS[ _this.hash ].forceRedraw = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.world.addHandler('item-index-changed', function(event) {
|
this.world.addHandler('metrics-change', function(event) {
|
||||||
|
if (_this.viewport) {
|
||||||
|
_this.viewport.setHomeBounds(_this.world.getHomeBounds(), _this.world.getContentFactor());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.world.addHandler('item-index-change', function(event) {
|
||||||
// For backwards compatibility, we maintain the source property
|
// For backwards compatibility, we maintain the source property
|
||||||
_this.source = _this.world.getItemAt(0).source;
|
_this.source = _this.world.getItemAt(0).source;
|
||||||
});
|
});
|
||||||
@ -438,6 +436,8 @@ $.Viewer = function( options ) {
|
|||||||
margins: this.viewportMargins
|
margins: this.viewportMargins
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.viewport.setHomeBounds(this.world.getHomeBounds(), this.world.getContentFactor());
|
||||||
|
|
||||||
// Create the image loader
|
// Create the image loader
|
||||||
this.imageLoader = new $.ImageLoader();
|
this.imageLoader = new $.ImageLoader();
|
||||||
|
|
||||||
@ -1301,6 +1301,15 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
index: options.index
|
index: options.index
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (_this.collectionMode) {
|
||||||
|
_this.world.arrange({
|
||||||
|
rows: _this.collectionRows,
|
||||||
|
layout: _this.collectionLayout,
|
||||||
|
tileSize: _this.collectionTileSize,
|
||||||
|
tileMargin: _this.collectionTileMargin
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (_this.world.getItemCount() === 1 && !_this.preserveViewport) {
|
if (_this.world.getItemCount() === 1 && !_this.preserveViewport) {
|
||||||
_this.viewport.goHome(true);
|
_this.viewport.goHome(true);
|
||||||
}
|
}
|
||||||
|
139
src/world.js
139
src/world.js
@ -43,6 +43,8 @@
|
|||||||
* @param {OpenSeadragon.Viewer} options.viewer - The Viewer that owns this World.
|
* @param {OpenSeadragon.Viewer} options.viewer - The Viewer that owns this World.
|
||||||
**/
|
**/
|
||||||
$.World = function( options ) {
|
$.World = function( options ) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
$.console.assert( options.viewer, "[World] options.viewer is required" );
|
$.console.assert( options.viewer, "[World] options.viewer is required" );
|
||||||
|
|
||||||
$.EventSource.call( this );
|
$.EventSource.call( this );
|
||||||
@ -50,6 +52,10 @@ $.World = function( options ) {
|
|||||||
this.viewer = options.viewer;
|
this.viewer = options.viewer;
|
||||||
this._items = [];
|
this._items = [];
|
||||||
this._needsUpdate = false;
|
this._needsUpdate = false;
|
||||||
|
this._delegatedFigureSizes = function(event) {
|
||||||
|
_this._figureSizes();
|
||||||
|
};
|
||||||
|
|
||||||
this._figureSizes();
|
this._figureSizes();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -59,6 +65,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|||||||
* @param {OpenSeadragon.TiledImage} item - The item to add.
|
* @param {OpenSeadragon.TiledImage} item - The item to add.
|
||||||
* @param {Number} [options.index] - Index for the item. If not specified, goes at the top.
|
* @param {Number} [options.index] - Index for the item. If not specified, goes at the top.
|
||||||
* @fires OpenSeadragon.World.event:add-item
|
* @fires OpenSeadragon.World.event:add-item
|
||||||
|
* @fires OpenSeadragon.World.event:metrics-change
|
||||||
*/
|
*/
|
||||||
addItem: function( item, options ) {
|
addItem: function( item, options ) {
|
||||||
$.console.assert(item, "[World.addItem] item is required");
|
$.console.assert(item, "[World.addItem] item is required");
|
||||||
@ -75,6 +82,8 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|||||||
this._figureSizes();
|
this._figureSizes();
|
||||||
this._needsUpdate = true;
|
this._needsUpdate = true;
|
||||||
|
|
||||||
|
item.addHandler('bounds-change', this._delegatedFigureSizes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raised when an item is added to the World.
|
* Raised when an item is added to the World.
|
||||||
* @event add-item
|
* @event add-item
|
||||||
@ -120,7 +129,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|||||||
* Change the index of a item so that it appears over or under others.
|
* Change the index of a item so that it appears over or under others.
|
||||||
* @param {OpenSeadragon.TiledImage} item - The item to move.
|
* @param {OpenSeadragon.TiledImage} item - The item to move.
|
||||||
* @param {Number} index - The new index.
|
* @param {Number} index - The new index.
|
||||||
* @fires OpenSeadragon.World.event:item-index-changed
|
* @fires OpenSeadragon.World.event:item-index-change
|
||||||
*/
|
*/
|
||||||
setItemIndex: function( item, index ) {
|
setItemIndex: function( item, index ) {
|
||||||
$.console.assert(item, "[World.setItemIndex] item is required");
|
$.console.assert(item, "[World.setItemIndex] item is required");
|
||||||
@ -142,7 +151,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Raised when the order of the indexes has been changed.
|
* Raised when the order of the indexes has been changed.
|
||||||
* @event item-index-changed
|
* @event item-index-change
|
||||||
* @memberOf OpenSeadragon.World
|
* @memberOf OpenSeadragon.World
|
||||||
* @type {object}
|
* @type {object}
|
||||||
* @property {OpenSeadragon.World} eventSource - A reference to the World which raised the event.
|
* @property {OpenSeadragon.World} eventSource - A reference to the World which raised the event.
|
||||||
@ -152,7 +161,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|||||||
* @property {Number} newIndex - The new index of the item
|
* @property {Number} newIndex - The new index of the item
|
||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
*/
|
*/
|
||||||
this.raiseEvent( 'item-index-changed', {
|
this.raiseEvent( 'item-index-change', {
|
||||||
item: item,
|
item: item,
|
||||||
previousIndex: oldIndex,
|
previousIndex: oldIndex,
|
||||||
newIndex: index
|
newIndex: index
|
||||||
@ -163,6 +172,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|||||||
* Remove an item.
|
* Remove an item.
|
||||||
* @param {OpenSeadragon.TiledImage} item - The item to remove.
|
* @param {OpenSeadragon.TiledImage} item - The item to remove.
|
||||||
* @fires OpenSeadragon.World.event:remove-item
|
* @fires OpenSeadragon.World.event:remove-item
|
||||||
|
* @fires OpenSeadragon.World.event:metrics-change
|
||||||
*/
|
*/
|
||||||
removeItem: function( item ) {
|
removeItem: function( item ) {
|
||||||
$.console.assert(item, "[World.removeItem] item is required");
|
$.console.assert(item, "[World.removeItem] item is required");
|
||||||
@ -172,6 +182,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.removeHandler('bounds-change', this._delegatedFigureSizes);
|
||||||
this._items.splice( index, 1 );
|
this._items.splice( index, 1 );
|
||||||
this._figureSizes();
|
this._figureSizes();
|
||||||
this._needsUpdate = true;
|
this._needsUpdate = true;
|
||||||
@ -181,15 +192,23 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|||||||
/**
|
/**
|
||||||
* Remove all items.
|
* Remove all items.
|
||||||
* @fires OpenSeadragon.World.event:remove-item
|
* @fires OpenSeadragon.World.event:remove-item
|
||||||
|
* @fires OpenSeadragon.World.event:metrics-change
|
||||||
*/
|
*/
|
||||||
removeAll: function() {
|
removeAll: function() {
|
||||||
|
var item;
|
||||||
|
for (var i = 0; i < this._items.length; i++) {
|
||||||
|
item = this._items[i];
|
||||||
|
item.removeHandler('bounds-change', this._delegatedFigureSizes);
|
||||||
|
}
|
||||||
|
|
||||||
var removedItems = this._items;
|
var removedItems = this._items;
|
||||||
this._items = [];
|
this._items = [];
|
||||||
this._figureSizes();
|
this._figureSizes();
|
||||||
this._needsUpdate = true;
|
this._needsUpdate = true;
|
||||||
|
|
||||||
for (var i = 0; i < removedItems.length; i++) {
|
for (i = 0; i < removedItems.length; i++) {
|
||||||
this._raiseRemoveItem(removedItems[i]);
|
item = removedItems[i];
|
||||||
|
this._raiseRemoveItem(item);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -242,39 +261,109 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|||||||
return this._contentFactor;
|
return this._contentFactor;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arranges all of the TiledImages with the specified settings.
|
||||||
|
* @param {Object} options - Specifies how to arrange.
|
||||||
|
* @param {String} [options.layout] - See collectionLayout in {@link OpenSeadragon.Options}.
|
||||||
|
* @param {Number} [options.rows] - See collectionRows in {@link OpenSeadragon.Options}.
|
||||||
|
* @param {Number} [options.tileSize] - See collectionTileSize in {@link OpenSeadragon.Options}.
|
||||||
|
* @param {Number} [options.tileMargin] - See collectionTileMargin in {@link OpenSeadragon.Options}.
|
||||||
|
* @fires OpenSeadragon.World.event:metrics-change
|
||||||
|
*/
|
||||||
|
arrange: function(options) {
|
||||||
|
options = options || {};
|
||||||
|
var layout = options.layout || $.DEFAULT_SETTINGS.collectionLayout;
|
||||||
|
var rows = options.rows || $.DEFAULT_SETTINGS.collectionRows;
|
||||||
|
var tileSize = options.tileSize || $.DEFAULT_SETTINGS.collectionTileSize;
|
||||||
|
var tileMargin = options.tileMargin || $.DEFAULT_SETTINGS.collectionTileMargin;
|
||||||
|
var increment = tileSize + tileMargin;
|
||||||
|
var wrap = Math.ceil(this._items.length / rows);
|
||||||
|
var x = 0;
|
||||||
|
var y = 0;
|
||||||
|
var item, box, width, height, position;
|
||||||
|
for (var i = 0; i < this._items.length; i++) {
|
||||||
|
if (i && (i % wrap) === 0) {
|
||||||
|
if (layout === 'horizontal') {
|
||||||
|
y += increment;
|
||||||
|
x = 0;
|
||||||
|
} else {
|
||||||
|
x += increment;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item = this._items[i];
|
||||||
|
box = item.getBounds();
|
||||||
|
if (box.width > box.height) {
|
||||||
|
width = tileSize;
|
||||||
|
} else {
|
||||||
|
width = tileSize * (box.width / box.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
height = width * (box.height / box.width);
|
||||||
|
position = new $.Point(x + ((tileSize - width) / 2),
|
||||||
|
y + ((tileSize - height) / 2));
|
||||||
|
|
||||||
|
item.setPosition(position);
|
||||||
|
item.setWidth(width);
|
||||||
|
|
||||||
|
if (layout === 'horizontal') {
|
||||||
|
x += increment;
|
||||||
|
} else {
|
||||||
|
y += increment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_figureSizes: function() {
|
_figureSizes: function() {
|
||||||
|
var oldHomeBounds = this._homeBounds ? this._homeBounds.clone() : null;
|
||||||
|
var oldContentSize = this._contentSize ? this._contentSize.clone() : null;
|
||||||
|
var oldContentFactor = this._contentFactor || 0;
|
||||||
|
|
||||||
if ( !this._items.length ) {
|
if ( !this._items.length ) {
|
||||||
this._homeBounds = new $.Rect(0, 0, 1, 1);
|
this._homeBounds = new $.Rect(0, 0, 1, 1);
|
||||||
this._contentSize = new $.Point(1, 1);
|
this._contentSize = new $.Point(1, 1);
|
||||||
return;
|
} else {
|
||||||
|
var bounds = this._items[0].getBounds();
|
||||||
|
this._contentFactor = this._items[0].getContentSize().x / bounds.width;
|
||||||
|
var left = bounds.x;
|
||||||
|
var top = bounds.y;
|
||||||
|
var right = bounds.x + bounds.width;
|
||||||
|
var bottom = bounds.y + bounds.height;
|
||||||
|
var box;
|
||||||
|
for ( var i = 1; i < this._items.length; i++ ) {
|
||||||
|
box = this._items[i].getBounds();
|
||||||
|
this._contentFactor = Math.max(this._contentFactor, this._items[i].getContentSize().x / box.width);
|
||||||
|
left = Math.min( left, box.x );
|
||||||
|
top = Math.min( top, box.y );
|
||||||
|
right = Math.max( right, box.x + box.width );
|
||||||
|
bottom = Math.max( bottom, box.y + box.height );
|
||||||
|
}
|
||||||
|
|
||||||
|
this._homeBounds = new $.Rect( left, top, right - left, bottom - top );
|
||||||
|
this._contentSize = new $.Point(this._homeBounds.width * this._contentFactor,
|
||||||
|
this._homeBounds.height * this._contentFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
var bounds = this._items[0].getWorldBounds();
|
if (this._contentFactor !== oldContentFactor || !this._homeBounds.equals(oldHomeBounds) ||
|
||||||
this._contentFactor = this._items[0].getContentSize().x / bounds.width;
|
!this._contentSize.equals(oldContentSize)) {
|
||||||
var left = bounds.x;
|
/**
|
||||||
var top = bounds.y;
|
* Raised when the home bounds, content size, or content factor change.
|
||||||
var right = bounds.x + bounds.width;
|
* @event metrics-change
|
||||||
var bottom = bounds.y + bounds.height;
|
* @memberOf OpenSeadragon.World
|
||||||
var box;
|
* @type {object}
|
||||||
for ( var i = 1; i < this._items.length; i++ ) {
|
* @property {OpenSeadragon.World} eventSource - A reference to the World which raised the event.
|
||||||
box = this._items[i].getWorldBounds();
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
this._contentFactor = Math.max(this._contentFactor, this._items[i].getContentSize().x / box.width);
|
*/
|
||||||
left = Math.min( left, box.x );
|
this.raiseEvent('metrics-change', {});
|
||||||
top = Math.min( top, box.y );
|
|
||||||
right = Math.max( right, box.x + box.width );
|
|
||||||
bottom = Math.max( bottom, box.y + box.height );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._homeBounds = new $.Rect( left, top, right - left, bottom - top );
|
|
||||||
this._contentSize = new $.Point(this._homeBounds.width * this._contentFactor,
|
|
||||||
this._homeBounds.height * this._contentFactor);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_raiseRemoveItem: function(item) {
|
_raiseRemoveItem: function(item) {
|
||||||
/**
|
/**
|
||||||
* Raised when a item is removed.
|
* Raised when an item is removed.
|
||||||
* @event remove-item
|
* @event remove-item
|
||||||
* @memberOf OpenSeadragon.World
|
* @memberOf OpenSeadragon.World
|
||||||
* @type {object}
|
* @type {object}
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
// debugMode: true,
|
// debugMode: true,
|
||||||
zoomPerScroll: 1.02,
|
zoomPerScroll: 1.02,
|
||||||
showNavigator: testNavigator,
|
showNavigator: testNavigator,
|
||||||
|
collectionMode: true,
|
||||||
|
collectionRows: 3,
|
||||||
|
collectionLayout: 'vertical',
|
||||||
|
// collectionTileSize: 10,
|
||||||
|
// collectionTileMargin: 10,
|
||||||
// wrapHorizontal: true,
|
// wrapHorizontal: true,
|
||||||
// wrapVertical: true,
|
// wrapVertical: true,
|
||||||
id: "contentDiv",
|
id: "contentDiv",
|
||||||
@ -96,7 +101,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this.crossTest3();
|
// this.crossTest3();
|
||||||
this.basicTest();
|
this.collectionTest();
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
@ -189,6 +194,24 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
collectionTest: function() {
|
||||||
|
var tileSources = [];
|
||||||
|
var random;
|
||||||
|
for (var i = 0; i < 10; i++) {
|
||||||
|
random = Math.random();
|
||||||
|
if (random < 0.33) {
|
||||||
|
tileSources.push('../../data/testpattern.dzi');
|
||||||
|
} else if (random < 0.66) {
|
||||||
|
tileSources.push('../../data/tall.dzi');
|
||||||
|
} else {
|
||||||
|
tileSources.push('../../data/wide.dzi');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.viewer.open(tileSources);
|
||||||
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
gridTest: function() {
|
gridTest: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -63,9 +63,9 @@
|
|||||||
equal( viewer.world.getItemAt( 2 ), item2,
|
equal( viewer.world.getItemAt( 2 ), item2,
|
||||||
"The item at index 2 should be the second added item." );
|
"The item at index 2 should be the second added item." );
|
||||||
|
|
||||||
viewer.world.addHandler( "item-index-changed",
|
viewer.world.addHandler( "item-index-change",
|
||||||
function itemIndexChangedHandler( event ) {
|
function itemIndexChangedHandler( event ) {
|
||||||
viewer.world.removeHandler( "item-index-changed",
|
viewer.world.removeHandler( "item-index-change",
|
||||||
itemIndexChangedHandler );
|
itemIndexChangedHandler );
|
||||||
equal( event.item, item2,
|
equal( event.item, item2,
|
||||||
"The item which changed index should be item2" );
|
"The item which changed index should be item2" );
|
||||||
|
Loading…
Reference in New Issue
Block a user