mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-24 22:26:10 +03:00
Add TiledImage.fitInBounds method.
This commit is contained in:
parent
030fec590e
commit
e4fca14c33
@ -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",
|
||||||
|
125
src/placement.js
Normal file
125
src/placement.js
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* 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 = {
|
||||||
|
CENTER: {
|
||||||
|
isLeft: false,
|
||||||
|
isHorizontallyCentered: true,
|
||||||
|
isRight: false,
|
||||||
|
isTop: false,
|
||||||
|
isVerticallyCentered: true,
|
||||||
|
isBottom: false
|
||||||
|
},
|
||||||
|
TOP_LEFT: {
|
||||||
|
isLeft: true,
|
||||||
|
isHorizontallyCentered: false,
|
||||||
|
isRight: false,
|
||||||
|
isTop: true,
|
||||||
|
isVerticallyCentered: false,
|
||||||
|
isBottom: false
|
||||||
|
},
|
||||||
|
TOP: {
|
||||||
|
isLeft: false,
|
||||||
|
isHorizontallyCentered: true,
|
||||||
|
isRight: false,
|
||||||
|
isTop: true,
|
||||||
|
isVerticallyCentered: false,
|
||||||
|
isBottom: false
|
||||||
|
},
|
||||||
|
TOP_RIGHT: {
|
||||||
|
isLeft: false,
|
||||||
|
isHorizontallyCentered: false,
|
||||||
|
isRight: true,
|
||||||
|
isTop: true,
|
||||||
|
isVerticallyCentered: false,
|
||||||
|
isBottom: false
|
||||||
|
},
|
||||||
|
RIGHT: {
|
||||||
|
isLeft: false,
|
||||||
|
isHorizontallyCentered: false,
|
||||||
|
isRight: true,
|
||||||
|
isTop: false,
|
||||||
|
isVerticallyCentered: true,
|
||||||
|
isBottom: false
|
||||||
|
},
|
||||||
|
BOTTOM_RIGHT: {
|
||||||
|
isLeft: false,
|
||||||
|
isHorizontallyCentered: false,
|
||||||
|
isRight: true,
|
||||||
|
isTop: false,
|
||||||
|
isVerticallyCentered: false,
|
||||||
|
isBottom: true
|
||||||
|
},
|
||||||
|
BOTTOM: {
|
||||||
|
isLeft: false,
|
||||||
|
isHorizontallyCentered: true,
|
||||||
|
isRight: false,
|
||||||
|
isTop: false,
|
||||||
|
isVerticallyCentered: false,
|
||||||
|
isBottom: true
|
||||||
|
},
|
||||||
|
BOTTOM_LEFT: {
|
||||||
|
isLeft: true,
|
||||||
|
isHorizontallyCentered: false,
|
||||||
|
isRight: false,
|
||||||
|
isTop: false,
|
||||||
|
isVerticallyCentered: false,
|
||||||
|
isBottom: true
|
||||||
|
},
|
||||||
|
LEFT: {
|
||||||
|
isLeft: true,
|
||||||
|
isHorizontallyCentered: false,
|
||||||
|
isRight: false,
|
||||||
|
isTop: false,
|
||||||
|
isVerticallyCentered: true,
|
||||||
|
isBottom: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}(OpenSeadragon));
|
@ -543,6 +543,48 @@ $.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
|
||||||
|
*/
|
||||||
|
fitInBounds: function(bounds, anchor, immediately) {
|
||||||
|
anchor = anchor || $.Placement.CENTER;
|
||||||
|
if (bounds.getAspectRatio() > this.contentAspectX) {
|
||||||
|
// We will have margins on the X axis
|
||||||
|
var targetWidth = bounds.height * this.contentAspectX;
|
||||||
|
var marginLeft = 0;
|
||||||
|
if (anchor.isHorizontallyCentered) {
|
||||||
|
marginLeft = (bounds.width - targetWidth) / 2;
|
||||||
|
} else if (anchor.isRight) {
|
||||||
|
marginLeft = bounds.width - targetWidth;
|
||||||
|
}
|
||||||
|
this.setPosition(
|
||||||
|
new $.Point(bounds.x + marginLeft, bounds.y),
|
||||||
|
immediately);
|
||||||
|
this.setHeight(bounds.height, immediately);
|
||||||
|
} else {
|
||||||
|
// We will have margins on the Y axis
|
||||||
|
var targetHeight = bounds.width / this.contentAspectX;
|
||||||
|
var marginTop = 0;
|
||||||
|
if (anchor.isVerticallyCentered) {
|
||||||
|
marginTop = (bounds.height - targetHeight) / 2;
|
||||||
|
} else if (anchor.isBottom) {
|
||||||
|
marginTop = bounds.height - targetHeight;
|
||||||
|
}
|
||||||
|
this.setPosition(
|
||||||
|
new $.Point(bounds.x, bounds.y + marginTop),
|
||||||
|
immediately);
|
||||||
|
this.setWidth(bounds.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.
|
||||||
|
@ -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>
|
||||||
|
@ -4,18 +4,18 @@
|
|||||||
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();
|
||||||
|
|
||||||
viewer = OpenSeadragon({
|
viewer = OpenSeadragon({
|
||||||
id: 'example',
|
id: 'example',
|
||||||
prefixUrl: '/build/openseadragon/images/',
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
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,50 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
asyncTest('fitInBounds', 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.fitInBounds(
|
||||||
|
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.fitInBounds(
|
||||||
|
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.fitInBounds(
|
||||||
|
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'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user