From 3cacc8edcf96d318e85b88cde91b9dadaf8936b1 Mon Sep 17 00:00:00 2001 From: Antoine Vandecreme Date: Tue, 22 Mar 2016 16:41:28 -0400 Subject: [PATCH] Add fitBounds option to TiledImage constructor. --- src/tiledimage.js | 15 ++++++++++- src/viewer.js | 6 +++++ test/modules/tiledimage.js | 52 +++++++++++++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/tiledimage.js b/src/tiledimage.js index bec4a6ef..a925104c 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -52,6 +52,10 @@ * @param {Number} [options.y=0] - Top position, in viewport coordinates. * @param {Number} [options.width=1] - Width, 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 * (portions of the image outside of this area will not be visible). Only works on * browsers that support the HTML5 canvas. @@ -122,6 +126,11 @@ $.TiledImage = function( options ) { delete options.height; } + var fitBounds = options.fitBounds; + delete options.fitBounds; + var fitBoundsPlacement = options.fitBoundsPlacement || OpenSeadragon.Placement.CENTER; + delete options.fitBoundsPlacement; + $.extend( true, this, { //internal state properties @@ -172,6 +181,10 @@ $.TiledImage = function( options ) { this._updateForScale(); + if (fitBounds) { + this.fitBounds(fitBounds, fitBoundsPlacement, true); + } + // We need a callback to give image manipulation a chance to happen this._drawingHandler = function(args) { /** @@ -554,7 +567,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag * or snap immediately. * @fires OpenSeadragon.TiledImage.event:bounds-change */ - fitInBounds: function(bounds, anchor, immediately) { + fitBounds: function(bounds, anchor, immediately) { anchor = anchor || $.Placement.CENTER; var anchorProperties = $.Placement.properties[anchor]; if (bounds.getAspectRatio() > this.contentAspectX) { diff --git a/src/viewer.js b/src/viewer.js index 3e5e4b04..f0434037 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -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.width=1] The width 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 * (portions of the image outside of this area will not be visible). Only works on * browsers that support the HTML5 canvas. @@ -1341,6 +1345,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, y: queueItem.options.y, width: queueItem.options.width, height: queueItem.options.height, + fitBounds: queueItem.options.fitBounds, + fitBoundsPlacement: queueItem.options.fitBoundsPlacement, clip: queueItem.options.clip, placeholderFillStyle: queueItem.options.placeholderFillStyle, opacity: queueItem.options.opacity, diff --git a/test/modules/tiledimage.js b/test/modules/tiledimage.js index d43ec41b..76b55541 100644 --- a/test/modules/tiledimage.js +++ b/test/modules/tiledimage.js @@ -257,7 +257,7 @@ }); }); - asyncTest('fitInBounds', function() { + asyncTest('fitBounds', function() { function assertRectEquals(actual, expected, message) { ok(actual.equals(expected), message + ' should be ' + @@ -268,7 +268,7 @@ viewer.removeHandler('open', openHandler); var squareImage = viewer.world.getItemAt(0); - squareImage.fitInBounds( + squareImage.fitBounds( new OpenSeadragon.Rect(0, 0, 1, 2), OpenSeadragon.Placement.CENTER, true); @@ -277,7 +277,7 @@ assertRectEquals(actualBounds, expectedBounds, 'Square image bounds'); var tallImage = viewer.world.getItemAt(1); - tallImage.fitInBounds( + tallImage.fitBounds( new OpenSeadragon.Rect(0, 0, 1, 2), OpenSeadragon.Placement.TOP_LEFT, true); @@ -286,7 +286,7 @@ assertRectEquals(actualBounds, expectedBounds, 'Tall image bounds'); var wideImage = viewer.world.getItemAt(2); - wideImage.fitInBounds( + wideImage.fitBounds( new OpenSeadragon.Rect(0, 0, 1, 2), OpenSeadragon.Placement.BOTTOM_RIGHT, true); @@ -303,4 +303,48 @@ ]); }); + 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 + }]); + }); })();