Merge pull request #888 from avandecreme/fit-in-bounds

Add TiledImage.fitInBounds method.
This commit is contained in:
Ian Gilman 2016-03-24 09:47:15 -07:00
commit 430804ef16
9 changed files with 405 additions and 65 deletions

View File

@ -28,6 +28,7 @@ module.exports = function(grunt) {
"src/mousetracker.js", "src/mousetracker.js",
"src/control.js", "src/control.js",
"src/controldock.js", "src/controldock.js",
"src/placement.js",
"src/viewer.js", "src/viewer.js",
"src/navigator.js", "src/navigator.js",
"src/strings.js", "src/strings.js",

View File

@ -154,7 +154,7 @@
* created. * created.
* * placement a string to define the relative position to the viewport. * * placement a string to define the relative position to the viewport.
* Only used if no width and height are specified. Default: 'TOP_LEFT'. * Only used if no width and height are specified. Default: 'TOP_LEFT'.
* See {@link OpenSeadragon.OverlayPlacement} for possible values. * See {@link OpenSeadragon.Placement} for possible values.
* *
* @property {String} [xmlPath=null] * @property {String} [xmlPath=null]
* <strong>DEPRECATED</strong>. A relative path to load a DZI file from the server. * <strong>DEPRECATED</strong>. A relative path to load a DZI file from the server.
@ -842,6 +842,21 @@ if (typeof define === 'function' && define.amd) {
return true; return true;
}; };
/**
* Shim around Object.freeze. Does nothing if Object.freeze is not supported.
* @param {Object} obj The object to freeze.
* @return {Object} obj The frozen object.
*/
$.freezeObject = function(obj) {
if (Object.freeze) {
$.freezeObject = Object.freeze;
} else {
$.freezeObject = function(obj) {
return obj;
};
}
return $.freezeObject(obj);
};
/** /**
* True if the browser supports the HTML5 canvas element * True if the browser supports the HTML5 canvas element

View File

@ -37,6 +37,8 @@
/** /**
* An enumeration of positions that an overlay may be assigned relative to * An enumeration of positions that an overlay may be assigned relative to
* the viewport. * the viewport.
* It is identical to OpenSeadragon.Placement but is kept for backward
* compatibility.
* @member OverlayPlacement * @member OverlayPlacement
* @memberof OpenSeadragon * @memberof OpenSeadragon
* @static * @static
@ -51,17 +53,7 @@
* @property {Number} BOTTOM_LEFT * @property {Number} BOTTOM_LEFT
* @property {Number} LEFT * @property {Number} LEFT
*/ */
$.OverlayPlacement = { $.OverlayPlacement = $.Placement;
CENTER: 0,
TOP_LEFT: 1,
TOP: 2,
TOP_RIGHT: 3,
RIGHT: 4,
BOTTOM_RIGHT: 5,
BOTTOM: 6,
BOTTOM_LEFT: 7,
LEFT: 8
};
/** /**
* @class Overlay * @class Overlay
@ -75,7 +67,7 @@
* is specified, the overlay will keep a constant size independently of the * is specified, the overlay will keep a constant size independently of the
* zoom. If a {@link OpenSeadragon.Rect} is specified, the overlay size will * zoom. If a {@link OpenSeadragon.Rect} is specified, the overlay size will
* be adjusted when the zoom changes. * be adjusted when the zoom changes.
* @param {OpenSeadragon.OverlayPlacement} [options.placement=OpenSeadragon.OverlayPlacement.TOP_LEFT] * @param {OpenSeadragon.Placement} [options.placement=OpenSeadragon.Placement.TOP_LEFT]
* Relative position to the viewport. * Relative position to the viewport.
* Only used if location is a {@link OpenSeadragon.Point}. * Only used if location is a {@link OpenSeadragon.Point}.
* @param {OpenSeadragon.Overlay.OnDrawCallback} [options.onDraw] * @param {OpenSeadragon.Overlay.OnDrawCallback} [options.onDraw]
@ -126,8 +118,7 @@
this.style = options.element.style; this.style = options.element.style;
// rects are always top-left // rects are always top-left
this.placement = options.location instanceof $.Point ? this.placement = options.location instanceof $.Point ?
options.placement : options.placement : $.Placement.TOP_LEFT;
$.OverlayPlacement.TOP_LEFT;
this.onDraw = options.onDraw; this.onDraw = options.onDraw;
this.checkResize = options.checkResize === undefined ? this.checkResize = options.checkResize === undefined ?
true : options.checkResize; true : options.checkResize;
@ -138,42 +129,23 @@
/** /**
* @function * @function
* @param {OpenSeadragon.OverlayPlacement} position * @param {OpenSeadragon.Point} position
* @param {OpenSeadragon.Point} size * @param {OpenSeadragon.Point} size
*/ */
adjust: function( position, size ) { adjust: function(position, size) {
switch ( this.placement ) { var properties = $.Placement.properties[this.placement];
case $.OverlayPlacement.TOP_LEFT: if (!properties) {
break; return;
case $.OverlayPlacement.TOP: }
if (properties.isHorizontallyCentered) {
position.x -= size.x / 2; position.x -= size.x / 2;
break; } else if (properties.isRight) {
case $.OverlayPlacement.TOP_RIGHT:
position.x -= size.x;
break;
case $.OverlayPlacement.RIGHT:
position.x -= size.x; position.x -= size.x;
}
if (properties.isVerticallyCentered) {
position.y -= size.y / 2; position.y -= size.y / 2;
break; } else if (properties.isBottom) {
case $.OverlayPlacement.BOTTOM_RIGHT:
position.x -= size.x;
position.y -= size.y; position.y -= size.y;
break;
case $.OverlayPlacement.BOTTOM:
position.x -= size.x / 2;
position.y -= size.y;
break;
case $.OverlayPlacement.BOTTOM_LEFT:
position.y -= size.y;
break;
case $.OverlayPlacement.LEFT:
position.y -= size.y / 2;
break;
default:
case $.OverlayPlacement.CENTER:
position.x -= size.x / 2;
position.y -= size.y / 2;
break;
} }
}, },
@ -298,7 +270,7 @@
/** /**
* @function * @function
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} location * @param {OpenSeadragon.Point|OpenSeadragon.Rect} location
* @param {OpenSeadragon.OverlayPlacement} position * @param {OpenSeadragon.Placement} position
*/ */
update: function( location, placement ) { update: function( location, placement ) {
this.scales = location instanceof $.Rect; this.scales = location instanceof $.Rect;
@ -310,8 +282,7 @@
); );
// rects are always top-left // rects are always top-left
this.placement = location instanceof $.Point ? this.placement = location instanceof $.Point ?
placement : placement : $.Placement.TOP_LEFT;
$.OverlayPlacement.TOP_LEFT;
}, },
/** /**

136
src/placement.js Normal file
View File

@ -0,0 +1,136 @@
/*
* OpenSeadragon - Placement
*
* Copyright (C) 2010-2016 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($) {
/**
* An enumeration of positions to anchor an element.
* @memberOf OpenSeadragon
* @static
* @property {OpenSeadragon.Placement} CENTER
* @property {OpenSeadragon.Placement} TOP_LEFT
* @property {OpenSeadragon.Placement} TOP
* @property {OpenSeadragon.Placement} TOP_RIGHT
* @property {OpenSeadragon.Placement} RIGHT
* @property {OpenSeadragon.Placement} BOTTOM_RIGHT
* @property {OpenSeadragon.Placement} BOTTOM
* @property {OpenSeadragon.Placement} BOTTOM_LEFT
* @property {OpenSeadragon.Placement} LEFT
*/
$.Placement = $.freezeObject({
CENTER: 0,
TOP_LEFT: 1,
TOP: 2,
TOP_RIGHT: 3,
RIGHT: 4,
BOTTOM_RIGHT: 5,
BOTTOM: 6,
BOTTOM_LEFT: 7,
LEFT: 8,
properties: {
0: {
isLeft: false,
isHorizontallyCentered: true,
isRight: false,
isTop: false,
isVerticallyCentered: true,
isBottom: false
},
1: {
isLeft: true,
isHorizontallyCentered: false,
isRight: false,
isTop: true,
isVerticallyCentered: false,
isBottom: false
},
2: {
isLeft: false,
isHorizontallyCentered: true,
isRight: false,
isTop: true,
isVerticallyCentered: false,
isBottom: false
},
3: {
isLeft: false,
isHorizontallyCentered: false,
isRight: true,
isTop: true,
isVerticallyCentered: false,
isBottom: false
},
4: {
isLeft: false,
isHorizontallyCentered: false,
isRight: true,
isTop: false,
isVerticallyCentered: true,
isBottom: false
},
5: {
isLeft: false,
isHorizontallyCentered: false,
isRight: true,
isTop: false,
isVerticallyCentered: false,
isBottom: true
},
6: {
isLeft: false,
isHorizontallyCentered: true,
isRight: false,
isTop: false,
isVerticallyCentered: false,
isBottom: true
},
7: {
isLeft: true,
isHorizontallyCentered: false,
isRight: false,
isTop: false,
isVerticallyCentered: false,
isBottom: true
},
8: {
isLeft: true,
isHorizontallyCentered: false,
isRight: false,
isTop: false,
isVerticallyCentered: true,
isBottom: false
}
}
});
}(OpenSeadragon));

View File

@ -52,6 +52,10 @@
* @param {Number} [options.y=0] - Top position, in viewport coordinates. * @param {Number} [options.y=0] - Top position, in viewport coordinates.
* @param {Number} [options.width=1] - Width, in viewport coordinates. * @param {Number} [options.width=1] - Width, in viewport coordinates.
* @param {Number} [options.height] - Height, in viewport coordinates. * @param {Number} [options.height] - Height, in viewport coordinates.
* @param {OpenSeadragon.Rect} [options.fitBounds] The bounds in viewport coordinates
* to fit the image into. If specified, x, y, width and height get ignored.
* @param {OpenSeadragon.Placement} [options.fitBoundsPlacement=OpenSeadragon.Placement.CENTER]
* How to anchor the image in the bounds if options.fitBounds is set.
* @param {OpenSeadragon.Rect} [options.clip] - An area, in image pixels, to clip to * @param {OpenSeadragon.Rect} [options.clip] - An area, in image pixels, to clip to
* (portions of the image outside of this area will not be visible). Only works on * (portions of the image outside of this area will not be visible). Only works on
* browsers that support the HTML5 canvas. * browsers that support the HTML5 canvas.
@ -122,6 +126,11 @@ $.TiledImage = function( options ) {
delete options.height; delete options.height;
} }
var fitBounds = options.fitBounds;
delete options.fitBounds;
var fitBoundsPlacement = options.fitBoundsPlacement || OpenSeadragon.Placement.CENTER;
delete options.fitBoundsPlacement;
$.extend( true, this, { $.extend( true, this, {
//internal state properties //internal state properties
@ -172,6 +181,10 @@ $.TiledImage = function( options ) {
this._updateForScale(); this._updateForScale();
if (fitBounds) {
this.fitBounds(fitBounds, fitBoundsPlacement, true);
}
// We need a callback to give image manipulation a chance to happen // We need a callback to give image manipulation a chance to happen
this._drawingHandler = function(args) { this._drawingHandler = function(args) {
/** /**
@ -543,6 +556,67 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
this._setScale(height / this.normHeight, immediately); this._setScale(height / this.normHeight, immediately);
}, },
/**
* Positions and scales the TiledImage to fit in the specified bounds.
* Note: this method fires OpenSeadragon.TiledImage.event:bounds-change
* twice
* @param {OpenSeadragon.Rect} bounds The bounds to fit the image into.
* @param {OpenSeadragon.Placement} [anchor=OpenSeadragon.Placement.CENTER]
* How to anchor the image in the bounds.
* @param {Boolean} [immediately=false] Whether to animate to the new size
* or snap immediately.
* @fires OpenSeadragon.TiledImage.event:bounds-change
*/
fitBounds: function(bounds, anchor, immediately) {
anchor = anchor || $.Placement.CENTER;
var anchorProperties = $.Placement.properties[anchor];
var aspectRatio = this.contentAspectX;
var xOffset = 0;
var yOffset = 0;
var displayedWidthRatio = 1;
var displayedHeightRatio = 1;
if (this._clip) {
aspectRatio = this._clip.getAspectRatio();
displayedWidthRatio = this._clip.width / this.source.dimensions.x;
displayedHeightRatio = this._clip.height / this.source.dimensions.y;
if (bounds.getAspectRatio() > aspectRatio) {
xOffset = this._clip.x / this._clip.height * bounds.height;
yOffset = this._clip.y / this._clip.height * bounds.height;
} else {
xOffset = this._clip.x / this._clip.width * bounds.width;
yOffset = this._clip.y / this._clip.width * bounds.width;
}
}
if (bounds.getAspectRatio() > aspectRatio) {
// We will have margins on the X axis
var height = bounds.height / displayedHeightRatio;
var marginLeft = 0;
if (anchorProperties.isHorizontallyCentered) {
marginLeft = (bounds.width - bounds.height * aspectRatio) / 2;
} else if (anchorProperties.isRight) {
marginLeft = bounds.width - bounds.height * aspectRatio;
}
this.setPosition(
new $.Point(bounds.x - xOffset + marginLeft, bounds.y - yOffset),
immediately);
this.setHeight(height, immediately);
} else {
// We will have margins on the Y axis
var width = bounds.width / displayedWidthRatio;
var marginTop = 0;
if (anchorProperties.isVerticallyCentered) {
marginTop = (bounds.height - bounds.width / aspectRatio) / 2;
} else if (anchorProperties.isBottom) {
marginTop = bounds.height - bounds.width / aspectRatio;
}
this.setPosition(
new $.Point(bounds.x - xOffset, bounds.y - yOffset + marginTop),
immediately);
this.setWidth(width, immediately);
}
},
/** /**
* @returns {OpenSeadragon.Rect|null} The TiledImage's current clip rectangle, * @returns {OpenSeadragon.Rect|null} The TiledImage's current clip rectangle,
* in image pixels, or null if none. * in image pixels, or null if none.

View File

@ -1206,6 +1206,10 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
* @param {Number} [options.y=0] The Y position for the image in viewport coordinates. * @param {Number} [options.y=0] The Y position for the image in viewport coordinates.
* @param {Number} [options.width=1] The width for the image in viewport coordinates. * @param {Number} [options.width=1] The width for the image in viewport coordinates.
* @param {Number} [options.height] The height for the image in viewport coordinates. * @param {Number} [options.height] The height for the image in viewport coordinates.
* @param {OpenSeadragon.Rect} [options.fitBounds] The bounds in viewport coordinates
* to fit the image into. If specified, x, y, width and height get ignored.
* @param {OpenSeadragon.Placement} [options.fitBoundsPlacement=OpenSeadragon.Placement.CENTER]
* How to anchor the image in the bounds if options.fitBounds is set.
* @param {OpenSeadragon.Rect} [options.clip] - An area, in image pixels, to clip to * @param {OpenSeadragon.Rect} [options.clip] - An area, in image pixels, to clip to
* (portions of the image outside of this area will not be visible). Only works on * (portions of the image outside of this area will not be visible). Only works on
* browsers that support the HTML5 canvas. * browsers that support the HTML5 canvas.
@ -1341,6 +1345,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
y: queueItem.options.y, y: queueItem.options.y,
width: queueItem.options.width, width: queueItem.options.width,
height: queueItem.options.height, height: queueItem.options.height,
fitBounds: queueItem.options.fitBounds,
fitBoundsPlacement: queueItem.options.fitBoundsPlacement,
clip: queueItem.options.clip, clip: queueItem.options.clip,
placeholderFillStyle: queueItem.options.placeholderFillStyle, placeholderFillStyle: queueItem.options.placeholderFillStyle,
opacity: queueItem.options.opacity, opacity: queueItem.options.opacity,
@ -1785,7 +1791,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
* the element which will be overlayed. Or an Object specifying the configuration for the overlay * the element which will be overlayed. Or an Object specifying the configuration for the overlay
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point or * @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point or
* rectangle which will be overlayed. This is a viewport relative location. * rectangle which will be overlayed. This is a viewport relative location.
* @param {OpenSeadragon.OverlayPlacement} placement - The position of the * @param {OpenSeadragon.Placement} placement - The position of the
* viewport which the location coordinates will be treated as relative * viewport which the location coordinates will be treated as relative
* to. * to.
* @param {function} onDraw - If supplied the callback is called when the overlay * @param {function} onDraw - If supplied the callback is called when the overlay
@ -1827,7 +1833,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event. * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {Element} element - The overlay element. * @property {Element} element - The overlay element.
* @property {OpenSeadragon.Point|OpenSeadragon.Rect} location * @property {OpenSeadragon.Point|OpenSeadragon.Rect} location
* @property {OpenSeadragon.OverlayPlacement} placement * @property {OpenSeadragon.Placement} placement
* @property {?Object} userData - Arbitrary subscriber-defined object. * @property {?Object} userData - Arbitrary subscriber-defined object.
*/ */
this.raiseEvent( 'add-overlay', { this.raiseEvent( 'add-overlay', {
@ -1846,7 +1852,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
* the element which is overlayed. * the element which is overlayed.
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point or * @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point or
* rectangle which will be overlayed. This is a viewport relative location. * rectangle which will be overlayed. This is a viewport relative location.
* @param {OpenSeadragon.OverlayPlacement} placement - The position of the * @param {OpenSeadragon.Placement} placement - The position of the
* viewport which the location coordinates will be treated as relative * viewport which the location coordinates will be treated as relative
* to. * to.
* @return {OpenSeadragon.Viewer} Chainable. * @return {OpenSeadragon.Viewer} Chainable.
@ -1872,7 +1878,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
* Viewer which raised the event. * Viewer which raised the event.
* @property {Element} element * @property {Element} element
* @property {OpenSeadragon.Point|OpenSeadragon.Rect} location * @property {OpenSeadragon.Point|OpenSeadragon.Rect} location
* @property {OpenSeadragon.OverlayPlacement} placement * @property {OpenSeadragon.Placement} placement
* @property {?Object} userData - Arbitrary subscriber-defined object. * @property {?Object} userData - Arbitrary subscriber-defined object.
*/ */
this.raiseEvent( 'update-overlay', { this.raiseEvent( 'update-overlay', {
@ -2222,8 +2228,8 @@ function getOverlayObject( viewer, overlay ) {
} }
var placement = overlay.placement; var placement = overlay.placement;
if ( placement && ( $.type( placement ) === "string" ) ) { if (placement && $.type(placement) === "string") {
placement = $.OverlayPlacement[ overlay.placement.toUpperCase() ]; placement = $.Placement[overlay.placement.toUpperCase()];
} }
return new $.Overlay({ return new $.Overlay({

View File

@ -22,6 +22,7 @@
<script src="/src/mousetracker.js"></script> <script src="/src/mousetracker.js"></script>
<script src="/src/control.js"></script> <script src="/src/control.js"></script>
<script src="/src/controldock.js"></script> <script src="/src/controldock.js"></script>
<script src="/src/placement.js"></script>
<script src="/src/viewer.js"></script> <script src="/src/viewer.js"></script>
<script src="/src/navigator.js"></script> <script src="/src/navigator.js"></script>
<script src="/src/strings.js"></script> <script src="/src/strings.js"></script>

View File

@ -397,6 +397,7 @@
checkFixedOverlayPosition( new OpenSeadragon.Point( 0, 0 ), checkFixedOverlayPosition( new OpenSeadragon.Point( 0, 0 ),
"with TOP_LEFT placement." ); "with TOP_LEFT placement." );
// Check that legacy OpenSeadragon.OverlayPlacement is still working
viewer.updateOverlay( "overlay", scalableOverlayLocation, viewer.updateOverlay( "overlay", scalableOverlayLocation,
OpenSeadragon.OverlayPlacement.CENTER ); OpenSeadragon.OverlayPlacement.CENTER );
viewer.updateOverlay( "fixed-overlay", fixedOverlayLocation, viewer.updateOverlay( "fixed-overlay", fixedOverlayLocation,
@ -407,10 +408,11 @@
checkFixedOverlayPosition( new OpenSeadragon.Point( -35, -30 ), checkFixedOverlayPosition( new OpenSeadragon.Point( -35, -30 ),
"with CENTER placement." ); "with CENTER placement." );
// Check that new OpenSeadragon.Placement is working
viewer.updateOverlay( "overlay", scalableOverlayLocation, viewer.updateOverlay( "overlay", scalableOverlayLocation,
OpenSeadragon.OverlayPlacement.BOTTOM_RIGHT ); OpenSeadragon.Placement.BOTTOM_RIGHT );
viewer.updateOverlay( "fixed-overlay", fixedOverlayLocation, viewer.updateOverlay( "fixed-overlay", fixedOverlayLocation,
OpenSeadragon.OverlayPlacement.BOTTOM_RIGHT ); OpenSeadragon.Placement.BOTTOM_RIGHT );
setTimeout( function() { setTimeout( function() {
checkScalableOverlayPosition( "with BOTTOM_RIGHT placement." ); checkScalableOverlayPosition( "with BOTTOM_RIGHT placement." );
checkFixedOverlayPosition( new OpenSeadragon.Point( -70, -60 ), checkFixedOverlayPosition( new OpenSeadragon.Point( -70, -60 ),

View File

@ -4,7 +4,7 @@
var viewer; var viewer;
module('TiledImage', { module('TiledImage', {
setup: function () { setup: function() {
var example = $('<div id="example"></div>').appendTo("#qunit-fixture"); var example = $('<div id="example"></div>').appendTo("#qunit-fixture");
testLog.reset(); testLog.reset();
@ -15,7 +15,7 @@
springStiffness: 100 // Faster animation = faster tests springStiffness: 100 // Faster animation = faster tests
}); });
}, },
teardown: function () { teardown: function() {
if (viewer && viewer.close) { if (viewer && viewer.close) {
viewer.close(); viewer.close();
} }
@ -87,7 +87,7 @@
// ---------- // ----------
asyncTest('animation', function() { asyncTest('animation', function() {
viewer.addHandler("open", function () { viewer.addHandler("open", function() {
var image = viewer.world.getItemAt(0); var image = viewer.world.getItemAt(0);
propEqual(image.getBounds(), new OpenSeadragon.Rect(0, 0, 1, 1), 'target bounds on open'); propEqual(image.getBounds(), new OpenSeadragon.Rect(0, 0, 1, 1), 'target bounds on open');
propEqual(image.getBounds(true), new OpenSeadragon.Rect(0, 0, 1, 1), 'current bounds on open'); propEqual(image.getBounds(true), new OpenSeadragon.Rect(0, 0, 1, 1), 'current bounds on open');
@ -257,4 +257,138 @@
}); });
}); });
asyncTest('fitBounds', function() {
function assertRectEquals(actual, expected, message) {
ok(actual.equals(expected), message + ' should be ' +
expected.toString() + ', found ' + actual.toString());
}
viewer.addHandler('open', function openHandler() {
viewer.removeHandler('open', openHandler);
var squareImage = viewer.world.getItemAt(0);
squareImage.fitBounds(
new OpenSeadragon.Rect(0, 0, 1, 2),
OpenSeadragon.Placement.CENTER,
true);
var actualBounds = squareImage.getBounds(true);
var expectedBounds = new OpenSeadragon.Rect(0, 0.5, 1, 1);
assertRectEquals(actualBounds, expectedBounds, 'Square image bounds');
var tallImage = viewer.world.getItemAt(1);
tallImage.fitBounds(
new OpenSeadragon.Rect(0, 0, 1, 2),
OpenSeadragon.Placement.TOP_LEFT,
true);
actualBounds = tallImage.getBounds(true);
expectedBounds = new OpenSeadragon.Rect(0, 0, 0.5, 2);
assertRectEquals(actualBounds, expectedBounds, 'Tall image bounds');
var wideImage = viewer.world.getItemAt(2);
wideImage.fitBounds(
new OpenSeadragon.Rect(0, 0, 1, 2),
OpenSeadragon.Placement.BOTTOM_RIGHT,
true);
actualBounds = wideImage.getBounds(true);
expectedBounds = new OpenSeadragon.Rect(0, 1.75, 1, 0.25);
assertRectEquals(actualBounds, expectedBounds, 'Wide image bounds');
start();
});
viewer.open([
'/test/data/testpattern.dzi',
'/test/data/tall.dzi',
'/test/data/wide.dzi'
]);
});
asyncTest('fitBounds in constructor', function() {
function assertRectEquals(actual, expected, message) {
ok(actual.equals(expected), message + ' should be ' +
expected.toString() + ', found ' + actual.toString());
}
viewer.addHandler('open', function openHandler() {
viewer.removeHandler('open', openHandler);
var squareImage = viewer.world.getItemAt(0);
var actualBounds = squareImage.getBounds(true);
var expectedBounds = new OpenSeadragon.Rect(0, 0.5, 1, 1);
assertRectEquals(actualBounds, expectedBounds, 'Square image bounds');
var tallImage = viewer.world.getItemAt(1);
actualBounds = tallImage.getBounds(true);
expectedBounds = new OpenSeadragon.Rect(0, 0, 0.5, 2);
assertRectEquals(actualBounds, expectedBounds, 'Tall image bounds');
var wideImage = viewer.world.getItemAt(2);
actualBounds = wideImage.getBounds(true);
expectedBounds = new OpenSeadragon.Rect(0, 1.75, 1, 0.25);
assertRectEquals(actualBounds, expectedBounds, 'Wide image bounds');
start();
});
viewer.open([{
tileSource: '/test/data/testpattern.dzi',
x: 1, // should be ignored
y: 1, // should be ignored
width: 2, // should be ignored
fitBounds: new OpenSeadragon.Rect(0, 0, 1, 2)
// No placement specified, should default to CENTER
}, {
tileSource: '/test/data/tall.dzi',
fitBounds: new OpenSeadragon.Rect(0, 0, 1, 2),
fitBoundsPlacement: OpenSeadragon.Placement.TOP_LEFT
}, {
tileSource: '/test/data/wide.dzi',
fitBounds: new OpenSeadragon.Rect(0, 0, 1, 2),
fitBoundsPlacement: OpenSeadragon.Placement.BOTTOM_RIGHT
}]);
});
asyncTest('fitBounds with clipping', function() {
function assertRectEquals(actual, expected, message) {
ok(actual.equals(expected), message + ' should be ' +
expected.toString() + ', found ' + actual.toString());
}
viewer.addHandler('open', function openHandler() {
viewer.removeHandler('open', openHandler);
var squareImage = viewer.world.getItemAt(0);
var actualBounds = squareImage.getBounds(true);
var expectedBounds = new OpenSeadragon.Rect(-1, -1, 2, 2);
assertRectEquals(actualBounds, expectedBounds, 'Square image bounds');
var tallImage = viewer.world.getItemAt(1);
actualBounds = tallImage.getBounds(true);
expectedBounds = new OpenSeadragon.Rect(1, 1, 2, 8);
assertRectEquals(actualBounds, expectedBounds, 'Tall image bounds');
var wideImage = viewer.world.getItemAt(2);
actualBounds = wideImage.getBounds(true);
expectedBounds = new OpenSeadragon.Rect(1, 1, 16, 4);
assertRectEquals(actualBounds, expectedBounds, 'Wide image bounds');
start();
});
viewer.open([{
tileSource: '/test/data/testpattern.dzi',
clip: new OpenSeadragon.Rect(500, 500, 500, 500),
fitBounds: new OpenSeadragon.Rect(0, 0, 1, 1)
}, {
tileSource: '/test/data/tall.dzi',
clip: new OpenSeadragon.Rect(0, 0, 250, 100),
fitBounds: new OpenSeadragon.Rect(1, 1, 1, 2),
fitBoundsPlacement: OpenSeadragon.Placement.TOP
}, {
tileSource: '/test/data/wide.dzi',
clip: new OpenSeadragon.Rect(0, 0, 100, 250),
fitBounds: new OpenSeadragon.Rect(1, 1, 1, 2),
fitBoundsPlacement: OpenSeadragon.Placement.TOP_LEFT
}]);
});
})(); })();