mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-28 16:16:08 +03:00
Merge pull request #934 from avandecreme/fitBounds
Take rotation into account in viewport getBounds and fitBounds methods
This commit is contained in:
commit
c5fc9a6922
@ -306,8 +306,8 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
this.updateSize();
|
this.updateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( viewport && this.viewport ) {
|
if (viewport && this.viewport) {
|
||||||
bounds = viewport.getBounds( true );
|
bounds = viewport.getBoundsNoRotate(true);
|
||||||
topleft = this.viewport.pixelFromPointNoRotate(bounds.getTopLeft(), false);
|
topleft = this.viewport.pixelFromPointNoRotate(bounds.getTopLeft(), false);
|
||||||
bottomright = this.viewport.pixelFromPointNoRotate(bounds.getBottomRight(), false)
|
bottomright = this.viewport.pixelFromPointNoRotate(bounds.getBottomRight(), false)
|
||||||
.minus( this.totalBorderWidths );
|
.minus( this.totalBorderWidths );
|
||||||
|
@ -795,6 +795,7 @@ function updateViewport( tiledImage ) {
|
|||||||
levelOpacity,
|
levelOpacity,
|
||||||
levelVisibility;
|
levelVisibility;
|
||||||
|
|
||||||
|
viewportBounds = viewportBounds.getBoundingBox();
|
||||||
viewportBounds.x -= tiledImage._xSpring.current.value;
|
viewportBounds.x -= tiledImage._xSpring.current.value;
|
||||||
viewportBounds.y -= tiledImage._ySpring.current.value;
|
viewportBounds.y -= tiledImage._ySpring.current.value;
|
||||||
|
|
||||||
@ -804,18 +805,6 @@ function updateViewport( tiledImage ) {
|
|||||||
tile.beingDrawn = false;
|
tile.beingDrawn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Change bounds for rotation
|
|
||||||
if (degrees === 90 || degrees === 270) {
|
|
||||||
viewportBounds = viewportBounds.rotate( degrees );
|
|
||||||
} else if (degrees !== 0 && degrees !== 180) {
|
|
||||||
// This is just an approximation.
|
|
||||||
var orthBounds = viewportBounds.rotate(90);
|
|
||||||
viewportBounds.x -= orthBounds.width / 2;
|
|
||||||
viewportBounds.y -= orthBounds.height / 2;
|
|
||||||
viewportBounds.width += orthBounds.width;
|
|
||||||
viewportBounds.height += orthBounds.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
var viewportTL = viewportBounds.getTopLeft();
|
var viewportTL = viewportBounds.getTopLeft();
|
||||||
var viewportBR = viewportBounds.getBottomRight();
|
var viewportBR = viewportBounds.getBottomRight();
|
||||||
|
|
||||||
|
@ -2975,33 +2975,26 @@ function updateOnce( viewer ) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var containerSize;
|
if (viewer.autoResize) {
|
||||||
if ( viewer.autoResize ) {
|
var containerSize = _getSafeElemSize(viewer.container);
|
||||||
containerSize = _getSafeElemSize( viewer.container );
|
var prevContainerSize = THIS[viewer.hash].prevContainerSize;
|
||||||
if ( !containerSize.equals( THIS[ viewer.hash ].prevContainerSize ) ) {
|
if (!containerSize.equals(prevContainerSize)) {
|
||||||
if ( viewer.preserveImageSizeOnResize ) {
|
var viewport = viewer.viewport;
|
||||||
var prevContainerSize = THIS[ viewer.hash ].prevContainerSize;
|
if (viewer.preserveImageSizeOnResize) {
|
||||||
var bounds = viewer.viewport.getBounds(true);
|
var resizeRatio = prevContainerSize.x / containerSize.x;
|
||||||
var deltaX = (containerSize.x - prevContainerSize.x);
|
var zoom = viewport.getZoom() * resizeRatio;
|
||||||
var deltaY = (containerSize.y - prevContainerSize.y);
|
var center = viewport.getCenter();
|
||||||
var viewportDiff = viewer.viewport.deltaPointsFromPixels(new OpenSeadragon.Point(deltaX, deltaY), true);
|
viewport.resize(containerSize, false);
|
||||||
viewer.viewport.resize(new OpenSeadragon.Point(containerSize.x, containerSize.y), false);
|
viewport.zoomTo(zoom, null, true);
|
||||||
|
viewport.panTo(center, true);
|
||||||
// Keep the center of the image in the center and just adjust the amount of image shown
|
} else {
|
||||||
bounds.width += viewportDiff.x;
|
|
||||||
bounds.height += viewportDiff.y;
|
|
||||||
bounds.x -= (viewportDiff.x / 2);
|
|
||||||
bounds.y -= (viewportDiff.y / 2);
|
|
||||||
viewer.viewport.fitBoundsWithConstraints(bounds, true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// maintain image position
|
// maintain image position
|
||||||
var oldBounds = viewer.viewport.getBounds();
|
var oldBounds = viewport.getBounds();
|
||||||
var oldCenter = viewer.viewport.getCenter();
|
viewport.resize(containerSize, true);
|
||||||
resizeViewportAndRecenter(viewer, containerSize, oldBounds, oldCenter);
|
viewport.fitBoundsWithConstraints(oldBounds, true);
|
||||||
}
|
}
|
||||||
THIS[ viewer.hash ].prevContainerSize = containerSize;
|
THIS[viewer.hash].prevContainerSize = containerSize;
|
||||||
THIS[ viewer.hash ].forceRedraw = true;
|
THIS[viewer.hash].forceRedraw = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3086,27 +3079,6 @@ function updateOnce( viewer ) {
|
|||||||
//viewer.profiler.endUpdate();
|
//viewer.profiler.endUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function resizes the viewport and recenters the image
|
|
||||||
// as it was before resizing.
|
|
||||||
// TODO: better adjust width and height. The new width and height
|
|
||||||
// should depend on the image dimensions and on the dimensions
|
|
||||||
// of the viewport before and after switching mode.
|
|
||||||
function resizeViewportAndRecenter( viewer, containerSize, oldBounds, oldCenter ) {
|
|
||||||
var viewport = viewer.viewport;
|
|
||||||
|
|
||||||
viewport.resize( containerSize, true );
|
|
||||||
|
|
||||||
var newBounds = new $.Rect(
|
|
||||||
oldCenter.x - ( oldBounds.width / 2.0 ),
|
|
||||||
oldCenter.y - ( oldBounds.height / 2.0 ),
|
|
||||||
oldBounds.width,
|
|
||||||
oldBounds.height
|
|
||||||
);
|
|
||||||
|
|
||||||
// let the viewport decide if the bounds are too big or too small
|
|
||||||
viewport.fitBoundsWithConstraints( newBounds, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawWorld( viewer ) {
|
function drawWorld( viewer ) {
|
||||||
viewer.imageLoader.clear();
|
viewer.imageLoader.clear();
|
||||||
viewer.drawer.clear();
|
viewer.drawer.clear();
|
||||||
|
209
src/viewport.js
209
src/viewport.js
@ -237,6 +237,17 @@ $.Viewport.prototype = {
|
|||||||
* @returns {OpenSeadragon.Rect} The home bounds in vewport coordinates.
|
* @returns {OpenSeadragon.Rect} The home bounds in vewport coordinates.
|
||||||
*/
|
*/
|
||||||
getHomeBounds: function() {
|
getHomeBounds: function() {
|
||||||
|
return this.getHomeBoundsNoRotate().rotate(-this.getRotation());
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the home bounds in viewport coordinates.
|
||||||
|
* This method ignores the viewport rotation. Use
|
||||||
|
* {@link OpenSeadragon.Viewport#getHomeBounds} to take it into account.
|
||||||
|
* @function
|
||||||
|
* @returns {OpenSeadragon.Rect} The home bounds in vewport coordinates.
|
||||||
|
*/
|
||||||
|
getHomeBoundsNoRotate: function() {
|
||||||
var center = this._contentBounds.getCenter();
|
var center = this._contentBounds.getCenter();
|
||||||
var width = 1.0 / this.getHomeZoom();
|
var width = 1.0 / this.getHomeZoom();
|
||||||
var height = width / this.getAspectRatio();
|
var height = width / this.getAspectRatio();
|
||||||
@ -254,8 +265,8 @@ $.Viewport.prototype = {
|
|||||||
* @param {Boolean} immediately
|
* @param {Boolean} immediately
|
||||||
* @fires OpenSeadragon.Viewer.event:home
|
* @fires OpenSeadragon.Viewer.event:home
|
||||||
*/
|
*/
|
||||||
goHome: function( immediately ) {
|
goHome: function(immediately) {
|
||||||
if( this.viewer ){
|
if (this.viewer) {
|
||||||
/**
|
/**
|
||||||
* Raised when the "home" operation occurs (see {@link OpenSeadragon.Viewport#goHome}).
|
* Raised when the "home" operation occurs (see {@link OpenSeadragon.Viewport#goHome}).
|
||||||
*
|
*
|
||||||
@ -266,11 +277,11 @@ $.Viewport.prototype = {
|
|||||||
* @property {Boolean} immediately
|
* @property {Boolean} immediately
|
||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
*/
|
*/
|
||||||
this.viewer.raiseEvent( 'home', {
|
this.viewer.raiseEvent('home', {
|
||||||
immediately: immediately
|
immediately: immediately
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return this.fitBounds( this.getHomeBounds(), immediately );
|
return this.fitBounds(this.getHomeBounds(), immediately);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -352,14 +363,26 @@ $.Viewport.prototype = {
|
|||||||
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
||||||
* @returns {OpenSeadragon.Rect} The location you are zoomed/panned to, in viewport coordinates.
|
* @returns {OpenSeadragon.Rect} The location you are zoomed/panned to, in viewport coordinates.
|
||||||
*/
|
*/
|
||||||
getBounds: function( current ) {
|
getBounds: function(current) {
|
||||||
var center = this.getCenter( current ),
|
return this.getBoundsNoRotate(current).rotate(-this.getRotation());
|
||||||
width = 1.0 / this.getZoom( current ),
|
},
|
||||||
height = width / this.getAspectRatio();
|
|
||||||
|
/**
|
||||||
|
* Returns the bounds of the visible area in viewport coordinates.
|
||||||
|
* This method ignores the viewport rotation. Use
|
||||||
|
* {@link OpenSeadragon.Viewport#getBounds} to take it into account.
|
||||||
|
* @function
|
||||||
|
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
||||||
|
* @returns {OpenSeadragon.Rect} The location you are zoomed/panned to, in viewport coordinates.
|
||||||
|
*/
|
||||||
|
getBoundsNoRotate: function(current) {
|
||||||
|
var center = this.getCenter(current);
|
||||||
|
var width = 1.0 / this.getZoom(current);
|
||||||
|
var height = width / this.getAspectRatio();
|
||||||
|
|
||||||
return new $.Rect(
|
return new $.Rect(
|
||||||
center.x - ( width / 2.0 ),
|
center.x - (width / 2.0),
|
||||||
center.y - ( height / 2.0 ),
|
center.y - (height / 2.0),
|
||||||
width,
|
width,
|
||||||
height
|
height
|
||||||
);
|
);
|
||||||
@ -371,8 +394,19 @@ $.Viewport.prototype = {
|
|||||||
* @returns {OpenSeadragon.Rect} The location you are zoomed/panned to,
|
* @returns {OpenSeadragon.Rect} The location you are zoomed/panned to,
|
||||||
* including the space taken by margins, in viewport coordinates.
|
* including the space taken by margins, in viewport coordinates.
|
||||||
*/
|
*/
|
||||||
getBoundsWithMargins: function( current ) {
|
getBoundsWithMargins: function(current) {
|
||||||
var bounds = this.getBounds(current);
|
return this.getBoundsNoRotateWithMargins(current).rotate(
|
||||||
|
-this.getRotation(), this.getCenter(current));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
||||||
|
* @returns {OpenSeadragon.Rect} The location you are zoomed/panned to,
|
||||||
|
* including the space taken by margins, in viewport coordinates.
|
||||||
|
*/
|
||||||
|
getBoundsNoRotateWithMargins: function(current) {
|
||||||
|
var bounds = this.getBoundsNoRotate(current);
|
||||||
var factor = this._containerInnerSize.x * this.getZoom(current);
|
var factor = this._containerInnerSize.x * this.getZoom(current);
|
||||||
bounds.x -= this._margins.left / factor;
|
bounds.x -= this._margins.left / factor;
|
||||||
bounds.y -= this._margins.top / factor;
|
bounds.y -= this._margins.top / factor;
|
||||||
@ -440,6 +474,13 @@ $.Viewport.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// private
|
||||||
|
_applyZoomConstraints: function(zoom) {
|
||||||
|
return Math.max(
|
||||||
|
Math.min(zoom, this.getMaxZoom()),
|
||||||
|
this.getMinZoom());
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
* @private
|
* @private
|
||||||
@ -521,40 +562,44 @@ $.Viewport.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Enforces the minZoom, maxZoom and visibilityRatio constraints by
|
||||||
|
* zooming and panning to the closest acceptable zoom and location.
|
||||||
* @function
|
* @function
|
||||||
|
* @param {Boolean} [immediately=false]
|
||||||
* @return {OpenSeadragon.Viewport} Chainable.
|
* @return {OpenSeadragon.Viewport} Chainable.
|
||||||
* @fires OpenSeadragon.Viewer.event:constrain
|
* @fires OpenSeadragon.Viewer.event:constrain
|
||||||
*/
|
*/
|
||||||
applyConstraints: function( immediately ) {
|
applyConstraints: function(immediately) {
|
||||||
var actualZoom = this.getZoom(),
|
var actualZoom = this.getZoom();
|
||||||
constrainedZoom = Math.max(
|
var constrainedZoom = this._applyZoomConstraints(actualZoom);
|
||||||
Math.min( actualZoom, this.getMaxZoom() ),
|
|
||||||
this.getMinZoom()
|
|
||||||
),
|
|
||||||
bounds,
|
|
||||||
constrainedBounds;
|
|
||||||
|
|
||||||
if ( actualZoom != constrainedZoom ) {
|
if (actualZoom !== constrainedZoom) {
|
||||||
this.zoomTo( constrainedZoom, this.zoomPoint, immediately );
|
this.zoomTo(constrainedZoom, this.zoomPoint, immediately);
|
||||||
}
|
}
|
||||||
|
|
||||||
bounds = this.getBounds();
|
var bounds = this.getBoundsNoRotate();
|
||||||
|
var constrainedBounds = this._applyBoundaryConstraints(
|
||||||
|
bounds, immediately);
|
||||||
|
|
||||||
constrainedBounds = this._applyBoundaryConstraints( bounds, immediately );
|
if (bounds.x !== constrainedBounds.x ||
|
||||||
|
bounds.y !== constrainedBounds.y ||
|
||||||
if ( bounds.x !== constrainedBounds.x || bounds.y !== constrainedBounds.y || immediately ){
|
immediately) {
|
||||||
this.fitBounds( constrainedBounds, immediately );
|
this.fitBounds(
|
||||||
|
constrainedBounds.rotate(-this.getRotation()),
|
||||||
|
immediately);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Equivalent to {@link OpenSeadragon.Viewport#applyConstraints}
|
||||||
* @function
|
* @function
|
||||||
* @param {Boolean} immediately
|
* @param {Boolean} [immediately=false]
|
||||||
|
* @return {OpenSeadragon.Viewport} Chainable.
|
||||||
|
* @fires OpenSeadragon.Viewer.event:constrain
|
||||||
*/
|
*/
|
||||||
ensureVisible: function( immediately ) {
|
ensureVisible: function(immediately) {
|
||||||
return this.applyConstraints( immediately );
|
return this.applyConstraints(immediately);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -564,41 +609,37 @@ $.Viewport.prototype = {
|
|||||||
* @param {Object} options (immediately=false, constraints=false)
|
* @param {Object} options (immediately=false, constraints=false)
|
||||||
* @return {OpenSeadragon.Viewport} Chainable.
|
* @return {OpenSeadragon.Viewport} Chainable.
|
||||||
*/
|
*/
|
||||||
_fitBounds: function( bounds, options ) {
|
_fitBounds: function(bounds, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var immediately = options.immediately || false;
|
var immediately = options.immediately || false;
|
||||||
var constraints = options.constraints || false;
|
var constraints = options.constraints || false;
|
||||||
|
|
||||||
var aspect = this.getAspectRatio();
|
var aspect = this.getAspectRatio();
|
||||||
var center = bounds.getCenter();
|
var center = bounds.getCenter();
|
||||||
|
|
||||||
|
// Compute width and height of bounding box.
|
||||||
var newBounds = new $.Rect(
|
var newBounds = new $.Rect(
|
||||||
bounds.x,
|
bounds.x,
|
||||||
bounds.y,
|
bounds.y,
|
||||||
bounds.width,
|
bounds.width,
|
||||||
bounds.height
|
bounds.height,
|
||||||
);
|
bounds.degrees + this.getRotation())
|
||||||
|
.getBoundingBox();
|
||||||
|
|
||||||
if ( newBounds.getAspectRatio() >= aspect ) {
|
if (newBounds.getAspectRatio() >= aspect) {
|
||||||
newBounds.height = bounds.width / aspect;
|
newBounds.height = newBounds.width / aspect;
|
||||||
newBounds.y = center.y - newBounds.height / 2;
|
|
||||||
} else {
|
} else {
|
||||||
newBounds.width = bounds.height * aspect;
|
newBounds.width = newBounds.height * aspect;
|
||||||
newBounds.x = center.x - newBounds.width / 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.panTo( this.getCenter( true ), true );
|
// Compute x and y from width, height and center position
|
||||||
this.zoomTo( this.getZoom( true ), null, true );
|
newBounds.x = center.x - newBounds.width / 2;
|
||||||
|
newBounds.y = center.y - newBounds.height / 2;
|
||||||
var oldBounds = this.getBounds();
|
var newZoom = 1.0 / newBounds.width;
|
||||||
var oldZoom = this.getZoom();
|
|
||||||
var newZoom = 1.0 / newBounds.width;
|
|
||||||
|
|
||||||
if (constraints) {
|
if (constraints) {
|
||||||
var newBoundsAspectRatio = newBounds.getAspectRatio();
|
var newBoundsAspectRatio = newBounds.getAspectRatio();
|
||||||
var newConstrainedZoom = Math.max(
|
var newConstrainedZoom = this._applyZoomConstraints(newZoom);
|
||||||
Math.min(newZoom, this.getMaxZoom() ),
|
|
||||||
this.getMinZoom()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (newZoom !== newConstrainedZoom) {
|
if (newZoom !== newConstrainedZoom) {
|
||||||
newZoom = newConstrainedZoom;
|
newZoom = newConstrainedZoom;
|
||||||
@ -608,58 +649,70 @@ $.Viewport.prototype = {
|
|||||||
newBounds.y = center.y - newBounds.height / 2;
|
newBounds.y = center.y - newBounds.height / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
newBounds = this._applyBoundaryConstraints( newBounds, immediately );
|
newBounds = this._applyBoundaryConstraints(newBounds, immediately);
|
||||||
center = newBounds.getCenter();
|
center = newBounds.getCenter();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (immediately) {
|
if (immediately) {
|
||||||
this.panTo( center, true );
|
this.panTo(center, true);
|
||||||
return this.zoomTo(newZoom, null, true);
|
return this.zoomTo(newZoom, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.panTo(this.getCenter(true), true);
|
||||||
|
this.zoomTo(this.getZoom(true), null, true);
|
||||||
|
|
||||||
|
var oldBounds = this.getBounds();
|
||||||
|
var oldZoom = this.getZoom();
|
||||||
|
|
||||||
if (Math.abs(newZoom - oldZoom) < 0.00000001 ||
|
if (Math.abs(newZoom - oldZoom) < 0.00000001 ||
|
||||||
Math.abs(newBounds.width - oldBounds.width) < 0.00000001) {
|
Math.abs(newBounds.width - oldBounds.width) < 0.00000001) {
|
||||||
return this.panTo( center, immediately );
|
return this.panTo(center, immediately);
|
||||||
}
|
}
|
||||||
|
|
||||||
var referencePoint = oldBounds.getTopLeft().times(
|
newBounds = newBounds.rotate(-this.getRotation());
|
||||||
this._containerInnerSize.x / oldBounds.width
|
var referencePoint = newBounds.getTopLeft().divide(newBounds.width)
|
||||||
).minus(
|
.minus(oldBounds.getTopLeft().divide(oldBounds.width))
|
||||||
newBounds.getTopLeft().times(
|
.divide(1 / newBounds.width - 1 / oldBounds.width);
|
||||||
this._containerInnerSize.x / newBounds.width
|
|
||||||
)
|
|
||||||
).divide(
|
|
||||||
this._containerInnerSize.x / oldBounds.width -
|
|
||||||
this._containerInnerSize.x / newBounds.width
|
|
||||||
);
|
|
||||||
|
|
||||||
return this.zoomTo( newZoom, referencePoint, immediately );
|
return this.zoomTo(newZoom, referencePoint, immediately);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Makes the viewport zoom and pan so that the specified bounds take
|
||||||
|
* as much space as possible in the viewport.
|
||||||
|
* Note: this method ignores the constraints (minZoom, maxZoom and
|
||||||
|
* visibilityRatio).
|
||||||
|
* Use {@link OpenSeadragon.Viewport#fitBoundsWithConstraints} to enforce
|
||||||
|
* them.
|
||||||
* @function
|
* @function
|
||||||
* @param {OpenSeadragon.Rect} bounds
|
* @param {OpenSeadragon.Rect} bounds
|
||||||
* @param {Boolean} immediately
|
* @param {Boolean} [immediately=false]
|
||||||
* @return {OpenSeadragon.Viewport} Chainable.
|
* @return {OpenSeadragon.Viewport} Chainable.
|
||||||
*/
|
*/
|
||||||
fitBounds: function( bounds, immediately ) {
|
fitBounds: function(bounds, immediately) {
|
||||||
return this._fitBounds( bounds, {
|
return this._fitBounds(bounds, {
|
||||||
immediately: immediately,
|
immediately: immediately,
|
||||||
constraints: false
|
constraints: false
|
||||||
} );
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Makes the viewport zoom and pan so that the specified bounds take
|
||||||
|
* as much space as possible in the viewport while enforcing the constraints
|
||||||
|
* (minZoom, maxZoom and visibilityRatio).
|
||||||
|
* Note: because this method enforces the constraints, part of the
|
||||||
|
* provided bounds may end up outside of the viewport.
|
||||||
|
* Use {@link OpenSeadragon.Viewport#fitBounds} to ignore them.
|
||||||
* @function
|
* @function
|
||||||
* @param {OpenSeadragon.Rect} bounds
|
* @param {OpenSeadragon.Rect} bounds
|
||||||
* @param {Boolean} immediately
|
* @param {Boolean} [immediately=false]
|
||||||
* @return {OpenSeadragon.Viewport} Chainable.
|
* @return {OpenSeadragon.Viewport} Chainable.
|
||||||
*/
|
*/
|
||||||
fitBoundsWithConstraints: function( bounds, immediately ) {
|
fitBoundsWithConstraints: function(bounds, immediately) {
|
||||||
return this._fitBounds( bounds, {
|
return this._fitBounds(bounds, {
|
||||||
immediately: immediately,
|
immediately: immediately,
|
||||||
constraints: true
|
constraints: true
|
||||||
} );
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -754,7 +807,12 @@ $.Viewport.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Zooms to the specified zoom level
|
||||||
* @function
|
* @function
|
||||||
|
* @param {Number} zoom The zoom level to zoom to.
|
||||||
|
* @param {OpenSeadragon.Point} [refPoint] The point which will stay at
|
||||||
|
* the same screen location. Defaults to the viewport center.
|
||||||
|
* @param {Boolean} [immediately=false]
|
||||||
* @return {OpenSeadragon.Viewport} Chainable.
|
* @return {OpenSeadragon.Viewport} Chainable.
|
||||||
* @fires OpenSeadragon.Viewer.event:zoom
|
* @fires OpenSeadragon.Viewer.event:zoom
|
||||||
*/
|
*/
|
||||||
@ -844,7 +902,7 @@ $.Viewport.prototype = {
|
|||||||
* @fires OpenSeadragon.Viewer.event:resize
|
* @fires OpenSeadragon.Viewer.event:resize
|
||||||
*/
|
*/
|
||||||
resize: function( newContainerSize, maintain ) {
|
resize: function( newContainerSize, maintain ) {
|
||||||
var oldBounds = this.getBounds(),
|
var oldBounds = this.getBoundsNoRotate(),
|
||||||
newBounds = oldBounds,
|
newBounds = oldBounds,
|
||||||
widthDeltaFactor;
|
widthDeltaFactor;
|
||||||
|
|
||||||
@ -996,7 +1054,8 @@ $.Viewport.prototype = {
|
|||||||
* @returns {OpenSeadragon.Point}
|
* @returns {OpenSeadragon.Point}
|
||||||
*/
|
*/
|
||||||
pixelFromPointNoRotate: function(point, current) {
|
pixelFromPointNoRotate: function(point, current) {
|
||||||
return this._pixelFromPointNoRotate(point, this.getBounds(current));
|
return this._pixelFromPointNoRotate(
|
||||||
|
point, this.getBoundsNoRotate(current));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1007,7 +1066,7 @@ $.Viewport.prototype = {
|
|||||||
* @returns {OpenSeadragon.Point}
|
* @returns {OpenSeadragon.Point}
|
||||||
*/
|
*/
|
||||||
pixelFromPoint: function(point, current) {
|
pixelFromPoint: function(point, current) {
|
||||||
return this._pixelFromPoint(point, this.getBounds(current));
|
return this._pixelFromPoint(point, this.getBoundsNoRotate(current));
|
||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
@ -1038,7 +1097,7 @@ $.Viewport.prototype = {
|
|||||||
* @returns {OpenSeadragon.Point}
|
* @returns {OpenSeadragon.Point}
|
||||||
*/
|
*/
|
||||||
pointFromPixelNoRotate: function(pixel, current) {
|
pointFromPixelNoRotate: function(pixel, current) {
|
||||||
var bounds = this.getBounds( current );
|
var bounds = this.getBoundsNoRotate(current);
|
||||||
return pixel.minus(
|
return pixel.minus(
|
||||||
new $.Point(this._margins.left, this._margins.top)
|
new $.Point(this._margins.left, this._margins.top)
|
||||||
).divide(
|
).divide(
|
||||||
|
@ -678,45 +678,20 @@
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
asyncTest( 'Viewer: preventDefaultAction', function () {
|
asyncTest('Viewer: preventDefaultAction', function() {
|
||||||
var $canvas = $( viewer.element ).find( '.openseadragon-canvas' ).not( '.navigator .openseadragon-canvas' ),
|
var $canvas = $(viewer.element).find('.openseadragon-canvas')
|
||||||
tracker = viewer.innerTracker,
|
.not('.navigator .openseadragon-canvas');
|
||||||
origClickHandler,
|
var tracker = viewer.innerTracker;
|
||||||
origDragHandler,
|
var epsilon = 0.0000001;
|
||||||
dragCount = 10,
|
|
||||||
originalZoom = 0,
|
|
||||||
originalBounds = null;
|
|
||||||
|
|
||||||
var onOpen = function ( event ) {
|
|
||||||
viewer.removeHandler( 'open', onOpen );
|
|
||||||
|
|
||||||
// Hook viewer events to set preventDefaultAction
|
|
||||||
origClickHandler = tracker.clickHandler;
|
|
||||||
tracker.clickHandler = function ( event ) {
|
|
||||||
event.preventDefaultAction = true;
|
|
||||||
return origClickHandler( event );
|
|
||||||
};
|
|
||||||
origDragHandler = tracker.dragHandler;
|
|
||||||
tracker.dragHandler = function ( event ) {
|
|
||||||
event.preventDefaultAction = true;
|
|
||||||
return origDragHandler( event );
|
|
||||||
};
|
|
||||||
|
|
||||||
originalZoom = viewer.viewport.getZoom();
|
|
||||||
originalBounds = viewer.viewport.getBounds();
|
|
||||||
|
|
||||||
var event = {
|
|
||||||
clientX:1,
|
|
||||||
clientY:1
|
|
||||||
};
|
|
||||||
|
|
||||||
|
function simulateClickAndDrag() {
|
||||||
$canvas.simulate( 'focus', event );
|
$canvas.simulate( 'focus', event );
|
||||||
// Drag to pan
|
// Drag to pan
|
||||||
Util.simulateViewerClickWithDrag( {
|
Util.simulateViewerClickWithDrag( {
|
||||||
viewer: viewer,
|
viewer: viewer,
|
||||||
widthFactor: 0.25,
|
widthFactor: 0.25,
|
||||||
heightFactor: 0.25,
|
heightFactor: 0.25,
|
||||||
dragCount: dragCount,
|
dragCount: 10,
|
||||||
dragDx: 1,
|
dragDx: 1,
|
||||||
dragDy: 1
|
dragDy: 1
|
||||||
} );
|
} );
|
||||||
@ -730,20 +705,57 @@
|
|||||||
dragDy: 0
|
dragDy: 0
|
||||||
} );
|
} );
|
||||||
$canvas.simulate( 'blur', event );
|
$canvas.simulate( 'blur', event );
|
||||||
|
}
|
||||||
|
|
||||||
var zoom = viewer.viewport.getZoom(),
|
var onOpen = function() {
|
||||||
bounds = viewer.viewport.getBounds();
|
viewer.removeHandler('open', onOpen);
|
||||||
|
|
||||||
equal( zoom, originalZoom, "Zoom prevented" );
|
// Hook viewer events to set preventDefaultAction
|
||||||
ok( bounds.x == originalBounds.x && bounds.y == originalBounds.y, 'Pan prevented' );
|
var origClickHandler = tracker.clickHandler;
|
||||||
|
tracker.clickHandler = function(event) {
|
||||||
|
event.preventDefaultAction = true;
|
||||||
|
return origClickHandler(event);
|
||||||
|
};
|
||||||
|
var origDragHandler = tracker.dragHandler;
|
||||||
|
tracker.dragHandler = function(event) {
|
||||||
|
event.preventDefaultAction = true;
|
||||||
|
return origDragHandler(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
var originalZoom = viewer.viewport.getZoom();
|
||||||
|
var originalBounds = viewer.viewport.getBounds();
|
||||||
|
|
||||||
|
simulateClickAndDrag();
|
||||||
|
|
||||||
|
var zoom = viewer.viewport.getZoom();
|
||||||
|
var bounds = viewer.viewport.getBounds();
|
||||||
|
Util.assessNumericValue(zoom, originalZoom, epsilon,
|
||||||
|
"Zoom should be prevented");
|
||||||
|
Util.assertRectangleEquals(bounds, originalBounds, epsilon,
|
||||||
|
'Pan should be prevented');
|
||||||
|
|
||||||
|
tracker.clickHandler = origClickHandler;
|
||||||
|
tracker.dragHandler = origDragHandler;
|
||||||
|
|
||||||
|
simulateClickAndDrag();
|
||||||
|
|
||||||
|
var zoom = viewer.viewport.getZoom();
|
||||||
|
var bounds = viewer.viewport.getBounds();
|
||||||
|
Util.assessNumericValue(zoom, 0.002, epsilon,
|
||||||
|
"Zoom should not be prevented");
|
||||||
|
Util.assertRectangleEquals(
|
||||||
|
bounds,
|
||||||
|
new OpenSeadragon.Rect(-250, -0.25, 500, 0.5),
|
||||||
|
epsilon,
|
||||||
|
'Pan should not be prevented');
|
||||||
|
|
||||||
viewer.close();
|
viewer.close();
|
||||||
start();
|
start();
|
||||||
};
|
};
|
||||||
|
|
||||||
viewer.addHandler( 'open', onOpen );
|
viewer.addHandler('open', onOpen);
|
||||||
viewer.open( '/test/data/testpattern.dzi' );
|
viewer.open('/test/data/testpattern.dzi');
|
||||||
} );
|
});
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
asyncTest( 'EventSource/MouseTracker/Viewer: event.originalEvent event.userData canvas-drag canvas-drag-end canvas-release canvas-click', function () {
|
asyncTest( 'EventSource/MouseTracker/Viewer: event.originalEvent event.userData canvas-drag canvas-drag-end canvas-release canvas-click', function () {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
var VIEWER_ID = "example";
|
var VIEWER_ID = "example";
|
||||||
var PREFIX_URL = "/build/openseadragon/images/";
|
var PREFIX_URL = "/build/openseadragon/images/";
|
||||||
var SPRING_STIFFNESS = 100; // Faster animation = faster tests
|
var SPRING_STIFFNESS = 100; // Faster animation = faster tests
|
||||||
|
var EPSILON = 0.0000000001;
|
||||||
|
|
||||||
module("viewport", {
|
module("viewport", {
|
||||||
setup: function () {
|
setup: function () {
|
||||||
@ -218,7 +219,27 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest('getHomeBoundsWithRotation', function() {
|
asyncTest('getHomeBoundsNoRotate with rotation', function() {
|
||||||
|
function openHandler() {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
viewport.setRotation(-675);
|
||||||
|
Util.assertRectangleEquals(
|
||||||
|
viewport.getHomeBoundsNoRotate(),
|
||||||
|
new OpenSeadragon.Rect(
|
||||||
|
(1 - Math.sqrt(2)) / 2,
|
||||||
|
(1 - Math.sqrt(2)) / 2,
|
||||||
|
Math.sqrt(2),
|
||||||
|
Math.sqrt(2)),
|
||||||
|
0.00000001,
|
||||||
|
"Test getHomeBoundsNoRotate with degrees = -675");
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('getHomeBounds with rotation', function() {
|
||||||
function openHandler() {
|
function openHandler() {
|
||||||
viewer.removeHandler('open', openHandler);
|
viewer.removeHandler('open', openHandler);
|
||||||
var viewport = viewer.viewport;
|
var viewport = viewer.viewport;
|
||||||
@ -226,10 +247,11 @@
|
|||||||
Util.assertRectangleEquals(
|
Util.assertRectangleEquals(
|
||||||
viewport.getHomeBounds(),
|
viewport.getHomeBounds(),
|
||||||
new OpenSeadragon.Rect(
|
new OpenSeadragon.Rect(
|
||||||
(1 - Math.sqrt(2)) / 2,
|
0.5,
|
||||||
(1 - Math.sqrt(2)) / 2,
|
-0.5,
|
||||||
Math.sqrt(2),
|
Math.sqrt(2),
|
||||||
Math.sqrt(2)),
|
Math.sqrt(2),
|
||||||
|
45),
|
||||||
0.00000001,
|
0.00000001,
|
||||||
"Test getHomeBounds with degrees = -675");
|
"Test getHomeBounds with degrees = -675");
|
||||||
start();
|
start();
|
||||||
@ -387,7 +409,7 @@
|
|||||||
viewer.open(DZI_PATH);
|
viewer.open(DZI_PATH);
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest('ensureVisible', function(){
|
asyncTest('ensureVisible', function() {
|
||||||
var openHandler = function(event) {
|
var openHandler = function(event) {
|
||||||
viewer.removeHandler('open', openHandler);
|
viewer.removeHandler('open', openHandler);
|
||||||
var viewport = viewer.viewport;
|
var viewport = viewer.viewport;
|
||||||
@ -405,17 +427,114 @@
|
|||||||
viewer.open(DZI_PATH);
|
viewer.open(DZI_PATH);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
asyncTest('applyConstraints', function() {
|
||||||
|
var openHandler = function() {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
viewport.fitBounds(new OpenSeadragon.Rect(1, 1, 1, 1), true);
|
||||||
|
viewport.visibilityRatio = 0.3;
|
||||||
|
viewport.applyConstraints(true);
|
||||||
|
var bounds = viewport.getBounds();
|
||||||
|
Util.assertRectangleEquals(
|
||||||
|
bounds,
|
||||||
|
new OpenSeadragon.Rect(0.7, 0.7, 1, 1),
|
||||||
|
EPSILON,
|
||||||
|
"Viewport.applyConstraints should move viewport.");
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest('applyConstraints with rotation', function() {
|
||||||
|
var openHandler = function() {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
viewport.setRotation(45);
|
||||||
|
viewport.fitBounds(new OpenSeadragon.Rect(1, 1, 1, 1), true);
|
||||||
|
viewport.applyConstraints(true);
|
||||||
|
var bounds = viewport.getBounds();
|
||||||
|
Util.assertRectangleEquals(
|
||||||
|
bounds,
|
||||||
|
new OpenSeadragon.Rect(1, 0, Math.sqrt(2), Math.sqrt(2), 45),
|
||||||
|
EPSILON,
|
||||||
|
"Viewport.applyConstraints with rotation should move viewport.");
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fit bounds tests
|
||||||
|
var testRectsFitBounds = [
|
||||||
|
new OpenSeadragon.Rect(0, -0.75, 0.5, 1),
|
||||||
|
new OpenSeadragon.Rect(0.5, 0, 0.5, 0.8),
|
||||||
|
new OpenSeadragon.Rect(0.75, 0.75, 0.5, 0.5),
|
||||||
|
new OpenSeadragon.Rect(-0.3, -0.3, 0.5, 0.5),
|
||||||
|
new OpenSeadragon.Rect(0.5, 0.25, Math.sqrt(0.125), Math.sqrt(0.125), 45)
|
||||||
|
];
|
||||||
|
|
||||||
|
var expectedRectsFitBounds = [
|
||||||
|
new OpenSeadragon.Rect(-0.25, -0.75, 1, 1),
|
||||||
|
new OpenSeadragon.Rect(0.35, 0, 0.8, 0.8),
|
||||||
|
new OpenSeadragon.Rect(0.75, 0.75, 0.5, 0.5),
|
||||||
|
new OpenSeadragon.Rect(-0.3, -0.3, 0.5, 0.5),
|
||||||
|
new OpenSeadragon.Rect(0.25, 0.25, 0.5, 0.5)
|
||||||
|
];
|
||||||
|
|
||||||
|
var expectedRectsFitBoundsWithRotation = [
|
||||||
|
new OpenSeadragon.Rect(
|
||||||
|
0.25,
|
||||||
|
-1,
|
||||||
|
Math.sqrt(0.125) + Math.sqrt(0.5),
|
||||||
|
Math.sqrt(0.125) + Math.sqrt(0.5),
|
||||||
|
45),
|
||||||
|
new OpenSeadragon.Rect(
|
||||||
|
0.75,
|
||||||
|
-0.25,
|
||||||
|
Math.sqrt(0.125) + Math.sqrt(8 / 25),
|
||||||
|
Math.sqrt(0.125) + Math.sqrt(8 / 25),
|
||||||
|
45),
|
||||||
|
new OpenSeadragon.Rect(
|
||||||
|
1,
|
||||||
|
0.5,
|
||||||
|
Math.sqrt(0.125) * 2,
|
||||||
|
Math.sqrt(0.125) * 2,
|
||||||
|
45),
|
||||||
|
new OpenSeadragon.Rect(
|
||||||
|
-0.05,
|
||||||
|
-0.55,
|
||||||
|
Math.sqrt(0.125) * 2,
|
||||||
|
Math.sqrt(0.125) * 2,
|
||||||
|
45),
|
||||||
|
new OpenSeadragon.Rect(
|
||||||
|
0.5,
|
||||||
|
0.25,
|
||||||
|
Math.sqrt(0.125),
|
||||||
|
Math.sqrt(0.125),
|
||||||
|
45)
|
||||||
|
];
|
||||||
|
|
||||||
|
var expectedRectsFitBoundsWithConstraints = [
|
||||||
|
new OpenSeadragon.Rect(-0.25, -0.5, 1, 1),
|
||||||
|
new OpenSeadragon.Rect(0.35, 0, 0.8, 0.8),
|
||||||
|
new OpenSeadragon.Rect(0.75, 0.75, 0.5, 0.5),
|
||||||
|
new OpenSeadragon.Rect(-0.25, -0.25, 0.5, 0.5),
|
||||||
|
new OpenSeadragon.Rect(0.25, 0.25, 0.5, 0.5)
|
||||||
|
];
|
||||||
|
|
||||||
asyncTest('fitBounds', function(){
|
asyncTest('fitBounds', function(){
|
||||||
var openHandler = function(event) {
|
var openHandler = function(event) {
|
||||||
viewer.removeHandler('open', openHandler);
|
viewer.removeHandler('open', openHandler);
|
||||||
var viewport = viewer.viewport;
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
for(var i = 0; i < testRects.length; i++){
|
for(var i = 0; i < testRectsFitBounds.length; i++){
|
||||||
var rect = testRects[i].times(viewport.getContainerSize());
|
var rect = testRectsFitBounds[i];
|
||||||
viewport.fitBounds(rect, true);
|
viewport.fitBounds(rect, true);
|
||||||
propEqual(
|
propEqual(
|
||||||
viewport.getBounds(),
|
viewport.getBounds(),
|
||||||
rect,
|
expectedRectsFitBounds[i],
|
||||||
"Fit bounds correctly."
|
"Fit bounds correctly."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -425,19 +544,27 @@
|
|||||||
viewer.open(DZI_PATH);
|
viewer.open(DZI_PATH);
|
||||||
});
|
});
|
||||||
|
|
||||||
var testRectsFitBounds = [
|
asyncTest('fitBounds with viewport rotation', function(){
|
||||||
new OpenSeadragon.Rect(0, -0.75, 0.5, 1),
|
var openHandler = function(event) {
|
||||||
new OpenSeadragon.Rect(0.5, 0, 0.5, 0.8),
|
viewer.removeHandler('open', openHandler);
|
||||||
new OpenSeadragon.Rect(0.75, 0.75, 0.5, 0.5),
|
var viewport = viewer.viewport;
|
||||||
new OpenSeadragon.Rect(-0.3, -0.3, 0.5, 0.5)
|
viewport.setRotation(45);
|
||||||
];
|
|
||||||
|
|
||||||
var expectedRectsFitBounds = [
|
for(var i = 0; i < testRectsFitBounds.length; i++){
|
||||||
new OpenSeadragon.Rect(-0.25, -0.5, 1, 1),
|
var rect = testRectsFitBounds[i];
|
||||||
new OpenSeadragon.Rect(0.35, 0, 0.8, 0.8),
|
viewport.fitBounds(rect, true);
|
||||||
new OpenSeadragon.Rect(0.75, 0.75, 0.5, 0.5),
|
Util.assertRectangleEquals(
|
||||||
new OpenSeadragon.Rect(-0.25, -0.25, 0.5, 0.5)
|
viewport.getBounds(),
|
||||||
];
|
expectedRectsFitBoundsWithRotation[i],
|
||||||
|
EPSILON,
|
||||||
|
"Fit bounds correctly."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
viewer.open(DZI_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
asyncTest('fitBoundsWithConstraints', function(){
|
asyncTest('fitBoundsWithConstraints', function(){
|
||||||
var openHandler = function(event) {
|
var openHandler = function(event) {
|
||||||
@ -450,7 +577,7 @@
|
|||||||
viewport.fitBoundsWithConstraints(rect, true);
|
viewport.fitBoundsWithConstraints(rect, true);
|
||||||
propEqual(
|
propEqual(
|
||||||
viewport.getBounds(),
|
viewport.getBounds(),
|
||||||
expectedRectsFitBounds[i],
|
expectedRectsFitBoundsWithConstraints[i],
|
||||||
"Fit bounds correctly."
|
"Fit bounds correctly."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -491,6 +618,7 @@
|
|||||||
viewer.addHandler('open', openHandler);
|
viewer.addHandler('open', openHandler);
|
||||||
viewer.open(WIDE_PATH);
|
viewer.open(WIDE_PATH);
|
||||||
});
|
});
|
||||||
|
// End fitBounds tests.
|
||||||
|
|
||||||
asyncTest('panBy', function(){
|
asyncTest('panBy', function(){
|
||||||
var openHandler = function(event) {
|
var openHandler = function(event) {
|
||||||
|
Loading…
Reference in New Issue
Block a user