Fixed home/constraints for multi-image.

This commit is contained in:
Ian Gilman 2014-08-18 16:04:49 -07:00
parent 26e9575f41
commit 8efad6f3a0
8 changed files with 137 additions and 74 deletions

View File

@ -1,6 +1,8 @@
OPENSEADRAGON CHANGELOG
=======================
2.0.0: (in progress)
1.2.0: (in progress)
* New combined IIIF TileSource for 1.0 through 2.0 (#441)

View File

@ -60,6 +60,13 @@ $.Point = function( x, y ) {
};
$.Point.prototype = /** @lends OpenSeadragon.Point.prototype */{
/**
* @function
* @returns {OpenSeadragon.Point} a duplicate of this Point
*/
clone: function() {
return new $.Point(this.x, this.y);
},
/**
* Add another Point to this point and return a new Point.

View File

@ -75,6 +75,13 @@ $.Rect = function( x, y, width, height ) {
};
$.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
/**
* @function
* @returns {OpenSeadragon.Rect} a duplicate of this Rect
*/
clone: function() {
return new $.Rect(this.x, this.y, this.width, this.height);
},
/**
* The aspect ratio is simply the ratio of width to height.

View File

@ -155,6 +155,10 @@ $.TiledImage.prototype = /** @lends OpenSeadragon.TiledImage.prototype */{
getWorldBounds: function() {
return new $.Rect( this._worldX, this._worldY, this._worldWidth, this._worldHeight );
},
getContentSize: function() {
return new $.Point(this.source.dimensions.x, this.source.dimensions.y);
}
};

View File

@ -333,7 +333,7 @@ $.Viewer = function( options ) {
_this.viewport.applyConstraints();
return false;
case 48://0|)
_this.goHome();
_this.viewport.goHome();
_this.viewport.applyConstraints();
return false;
case 119://w
@ -622,29 +622,6 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
this.element = null;
},
/**
* @function
* @param {Boolean} immediately
* @fires OpenSeadragon.Viewer.event:home
*/
goHome: function(immediately) {
/**
* Raised when the "home" operation occurs (see {@link OpenSeadragon.Viewport#goHome}).
*
* @event home
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
* @property {Boolean} immediately
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.raiseEvent( 'home', {
immediately: immediately
});
this.viewport.fitBounds( this.world.getHomeBounds(), immediately );
},
/**
* @function
* @return {Boolean}
@ -1137,6 +1114,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
debugGridColor: _this.debugGridColor
});
_this.world.addItem( tiledImage );
_this.viewport.setHomeBounds(_this.world.getHomeBounds(), _this.world.getContentFactor());
if ( options.level !== undefined ) {
_this.world.setItemLevel( tiledImage, options.level );
}
@ -1868,7 +1846,6 @@ function openTileSource( viewer, source, options ) {
collectionMode: true,
collectionTileSource: _this.source,
containerSize: THIS[ _this.hash ].prevContainerSize,
contentSize: _this.source.dimensions,
springStiffness: _this.springStiffness,
animationTime: _this.animationTime,
showNavigator: false,
@ -1886,7 +1863,6 @@ function openTileSource( viewer, source, options ) {
}
_this.viewport = _this.viewport ? _this.viewport : new $.Viewport({
containerSize: THIS[ _this.hash ].prevContainerSize,
contentSize: _this.source.dimensions,
springStiffness: _this.springStiffness,
animationTime: _this.animationTime,
minZoomImageRatio: _this.minZoomImageRatio,
@ -1903,9 +1879,10 @@ function openTileSource( viewer, source, options ) {
});
}
if( _this.preserveViewport ){
_this.viewport.resetContentSize( _this.source.dimensions );
}
// TODO: what to do about this?
// if( _this.preserveViewport ){
// _this.viewport.resetContentSize( _this.source.dimensions );
// }
_this.source.overlays = _this.source.overlays || [];
@ -1952,7 +1929,8 @@ function openTileSource( viewer, source, options ) {
});
_this.world.addItem( tiledImage );
_this.goHome( true );
_this.viewport.setHomeBounds(_this.world.getHomeBounds(), _this.world.getContentFactor());
_this.viewport.goHome( true );
// Now that we have a drawer, see if it supports rotate. If not we need to remove the rotate buttons
if (!_this.drawer.canRotate()) {
@ -2818,7 +2796,7 @@ function lightUp() {
function onHome() {
this.goHome();
this.viewport.goHome();
}

View File

@ -104,43 +104,82 @@ $.Viewport = function( options ) {
animationTime: this.animationTime
});
this.resetContentSize( this.contentSize );
if (this.contentSize) {
this.resetContentSize( this.contentSize );
} else {
this.setHomeBounds(new $.Rect(0, 0, 1, 1), 1);
}
this.goHome( true );
this.update();
};
$.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
/**
* Updates the viewport's home bounds and constraints for the given content size.
* @function
* @param {OpenSeadragon.Point} contentSize - size of the content in content units
* @return {OpenSeadragon.Viewport} Chainable.
* @fires OpenSeadragon.Viewer.event:reset-size
*/
resetContentSize: function( contentSize ){
this.contentSize = contentSize;
$.console.assert(contentSize, "[Viewport.resetContentSize] contentSize is required");
$.console.assert(contentSize instanceof $.Point, "[Viewport.resetContentSize] contentSize must be an OpenSeadragon.Point");
$.console.assert(contentSize.x > 0, "[Viewport.resetContentSize] contentSize.x must be greater than 0");
$.console.assert(contentSize.y > 0, "[Viewport.resetContentSize] contentSize.y must be greater than 0");
this.setHomeBounds(new $.Rect(0, 0, 1, contentSize.y / contentSize.x), contentSize.x);
return this;
},
/**
* Updates the viewport's home bounds and constraints.
* @function
* @param {OpenSeadragon.Rect} bounds - the new bounds in world coordinates
* @param {Number} contentFactor - how many content units per world unit
* @fires OpenSeadragon.Viewer.event:reset-size
*/
setHomeBounds: function(bounds, contentFactor) {
$.console.assert(bounds, "[Viewport.setHomeBounds] bounds is required");
$.console.assert(bounds instanceof $.Rect, "[Viewport.setHomeBounds] bounds must be an OpenSeadragon.Rect");
$.console.assert(bounds.width > 0, "[Viewport.setHomeBounds] bounds.width must be greater than 0");
$.console.assert(bounds.height > 0, "[Viewport.setHomeBounds] bounds.height must be greater than 0");
this.homeBounds = bounds.clone();
this.contentSize = this.homeBounds.getSize().times(contentFactor);
this.contentAspectX = this.contentSize.x / this.contentSize.y;
this.contentAspectY = this.contentSize.y / this.contentSize.x;
this.fitWidthBounds = new $.Rect( 0, 0, 1, this.contentAspectY );
this.fitHeightBounds = new $.Rect( 0, 0, this.contentAspectY, this.contentAspectY);
this.homeBounds = new $.Rect( 0, 0, 1, this.contentAspectY );
// TODO: seems like fitWidthBounds and fitHeightBounds should be thin slices
// across the appropriate axis, centered in the image, rather than what we have
// here.
this.fitWidthBounds = new $.Rect(this.homeBounds.x, this.homeBounds.y,
this.homeBounds.width, this.homeBounds.width);
this.fitHeightBounds = new $.Rect(this.homeBounds.x, this.homeBounds.y,
this.homeBounds.height, this.homeBounds.height);
if( this.viewer ){
/**
* Raised when the viewer's content size is reset (see {@link OpenSeadragon.Viewport#resetContentSize}).
* Raised when the viewer's content size or home bounds are reset
* (see {@link OpenSeadragon.Viewport#resetContentSize},
* {@link OpenSeadragon.Viewport#setHomeBounds}).
*
* @event reset-size
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
* @property {OpenSeadragon.Point} contentSize
* @property {OpenSeadragon.Rect} homeBounds
* @property {Number} contentFactor
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.viewer.raiseEvent( 'reset-size', {
contentSize: contentSize
contentSize: this.contentSize.clone(),
contentFactor: contentFactor,
homeBounds: this.homeBounds.clone()
});
}
return this;
},
/**
@ -153,9 +192,11 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
if( this.defaultZoomLevel ){
return this.defaultZoomLevel;
} else {
return ( aspectFactor >= 1 ) ?
var output = ( aspectFactor >= 1 ) ?
1 :
aspectFactor;
return output / this.homeBounds.width;
}
},
@ -163,29 +204,31 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
* @function
*/
getHomeBounds: function() {
var center = this.homeBounds.getCenter( ),
width = 1.0 / this.getHomeZoom( ),
height = width / this.getAspectRatio();
return new $.Rect(
center.x - ( width / 2.0 ),
center.y - ( height / 2.0 ),
width,
height
);
return this.homeBounds.clone();
},
/**
* @function
* @private
* @param {Boolean} immediately
* @fires OpenSeadragon.Viewer.event:home
*/
goHome: function( immediately ) {
$.console.error("[Viewport.goHome] this function is deprecated; use Viewer.goHome instead");
if( this.viewer ){
this.viewer.goHome(immediately);
/**
* Raised when the "home" operation occurs (see {@link OpenSeadragon.Viewport#goHome}).
*
* @event home
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
* @property {Boolean} immediately
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.viewer.raiseEvent( 'home', {
immediately: immediately
});
}
return this;
return this.fitBounds( this.getHomeBounds(), immediately );
},
/**
@ -204,9 +247,11 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
* @function
*/
getMaxZoom: function() {
var zoom = this.maxZoomLevel ?
this.maxZoomLevel :
( this.contentSize.x * this.maxZoomPixelRatio / this.containerSize.x );
var zoom = this.maxZoomLevel;
if (!zoom) {
zoom = this.contentSize.x * this.maxZoomPixelRatio / this.containerSize.x;
zoom /= this.homeBounds.width;
}
return Math.max( zoom, this.getHomeZoom() );
},
@ -335,9 +380,9 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
verticalThreshold = this.visibilityRatio * newBounds.height;
left = newBounds.x + newBounds.width;
right = 1 - newBounds.x;
right = this.homeBounds.width - newBounds.x;
top = newBounds.y + newBounds.height;
bottom = this.contentAspectY - newBounds.y;
bottom = this.homeBounds.height - newBounds.y;
if ( this.wrapHorizontal ) {
//do nothing
@ -368,11 +413,11 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
if ( dx || dy || immediately ) {
newBounds.x += dx;
newBounds.y += dy;
if( newBounds.width > 1 ){
newBounds.x = 0.5 - newBounds.width/2;
if( newBounds.width > this.homeBounds.width ){
newBounds.x = this.homeBounds.width / 2 - newBounds.width/2;
}
if( newBounds.height > this.contentAspectY ){
newBounds.y = this.contentAspectY/2 - newBounds.height/2;
if( newBounds.height > this.homeBounds.height){
newBounds.y = this.homeBounds.height / 2 - newBounds.height/2;
}
}
@ -401,10 +446,6 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
* @fires OpenSeadragon.Viewer.event:constrain
*/
applyConstraints: function( immediately ) {
if (true) {
return; // TEMP
}
var actualZoom = this.getZoom(),
constrainedZoom = Math.max(
Math.min( actualZoom, this.getMaxZoom() ),

View File

@ -43,11 +43,13 @@ $.World = function( options ) {
this.viewer = options.viewer;
this._items = [];
this._figureSizes();
};
$.World.prototype = /** @lends OpenSeadragon.World.prototype */{
addItem: function( item ) {
this._items.push( item );
this._figureSizes();
},
/**
@ -132,6 +134,8 @@ $.World.prototype = /** @lends OpenSeadragon.World.prototype */{
}
this._items.splice( index, 1 );
this._figureSizes();
/**
* Raised when a layer is removed.
* @event remove-layer
@ -167,11 +171,26 @@ $.World.prototype = /** @lends OpenSeadragon.World.prototype */{
},
getHomeBounds: function() {
return this._homeBounds.clone();
},
getContentSize: function() {
return this._contentSize.clone();
},
getContentFactor: function() {
return this._contentFactor;
},
_figureSizes: function() {
if ( !this._items.length ) {
return new $.Rect(0, 0, 1, 1);
this._homeBounds = new $.Rect(0, 0, 1, 1);
this._contentSize = new $.Point(1, 1);
return;
}
var bounds = this._items[0].getWorldBounds();
this._contentFactor = this._items[0].getContentSize().x / bounds.width;
var left = bounds.x;
var top = bounds.y;
var right = bounds.x + bounds.width;
@ -179,13 +198,16 @@ $.World.prototype = /** @lends OpenSeadragon.World.prototype */{
var box;
for ( var i = 1; i < this._items.length; i++ ) {
box = this._items[i].getWorldBounds();
this._contentFactor = Math.max(this._contentFactor, this._items[i].getContentSize().x / bounds.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 );
}
return new $.Rect( left, top, right - left, bottom - top );
this._homeBounds = new $.Rect( left, top, right - left, bottom - top );
this._contentSize = new $.Point(this._homeBounds.width * this._contentFactor,
this._homeBounds.height * this._contentFactor);
}
};

View File

@ -1,6 +1,8 @@
/* globals $, App */
(function() {
var App = {
window.App = {
init: function() {
var self = this;
@ -38,7 +40,7 @@
var addLayerHandler = function( event ) {
if ( event.options === options ) {
self.viewer.removeHandler( "add-layer", addLayerHandler );
self.viewer.goHome();
self.viewer.viewport.goHome();
}
};
this.viewer.addHandler( "add-layer", addLayerHandler );