Fix applyConstraints. Fix #833.

This commit is contained in:
Antoine Vandecreme 2016-02-15 17:09:31 -05:00
parent eaab4fb4c5
commit 0725645344
3 changed files with 81 additions and 81 deletions

View File

@ -134,6 +134,7 @@ $.Viewport = function( options ) {
this._oldCenterY = this.centerSpringY.current.value; this._oldCenterY = this.centerSpringY.current.value;
this._oldZoom = this.zoomSpring.current.value; this._oldZoom = this.zoomSpring.current.value;
//TODO: is it useful?
if (this.contentSize) { if (this.contentSize) {
this.resetContentSize(this.contentSize); this.resetContentSize(this.contentSize);
} else { } else {
@ -182,9 +183,13 @@ $.Viewport.prototype = {
$.console.assert(bounds.width > 0, "[Viewport._setContentBounds] bounds.width must be greater than 0"); $.console.assert(bounds.width > 0, "[Viewport._setContentBounds] bounds.width must be greater than 0");
$.console.assert(bounds.height > 0, "[Viewport._setContentBounds] bounds.height must be greater than 0"); $.console.assert(bounds.height > 0, "[Viewport._setContentBounds] bounds.height must be greater than 0");
this._worldContentBounds = bounds.clone();
this._worldContentSize = this._worldContentBounds.getSize().times(
contentFactor);
this._contentBounds = bounds.rotate(this.degrees).getBoundingBox(); this._contentBounds = bounds.rotate(this.degrees).getBoundingBox();
this.contentSize = this._contentBounds.getSize().times(contentFactor); this._contentSize = this._contentBounds.getSize().times(contentFactor);
this._contentAspectRatio = this.contentSize.x / this.contentSize.y; this._contentAspectRatio = this._contentSize.x / this._contentSize.y;
if (this.viewer) { if (this.viewer) {
/** /**
@ -203,9 +208,9 @@ $.Viewport.prototype = {
* @property {?Object} userData - Arbitrary subscriber-defined object. * @property {?Object} userData - Arbitrary subscriber-defined object.
*/ */
this.viewer.raiseEvent('reset-size', { this.viewer.raiseEvent('reset-size', {
contentSize: this.contentSize.clone(), contentSize: this._worldContentSize.clone(),
contentFactor: contentFactor, contentFactor: contentFactor,
homeBounds: this._contentBounds.clone(), homeBounds: this._worldContentBounds.clone(),
contentBounds: this._contentBounds.clone() contentBounds: this._contentBounds.clone()
}); });
} }
@ -292,7 +297,7 @@ $.Viewport.prototype = {
getMaxZoom: function() { getMaxZoom: function() {
var zoom = this.maxZoomLevel; var zoom = this.maxZoomLevel;
if (!zoom) { if (!zoom) {
zoom = this.contentSize.x * this.maxZoomPixelRatio / this._containerInnerSize.x; zoom = this._contentSize.x * this.maxZoomPixelRatio / this._containerInnerSize.x;
zoom /= this._contentBounds.width; zoom /= this._contentBounds.width;
} }
@ -446,65 +451,61 @@ $.Viewport.prototype = {
* @param {Boolean} immediately * @param {Boolean} immediately
* @return {OpenSeadragon.Rect} constrained bounds. * @return {OpenSeadragon.Rect} constrained bounds.
*/ */
_applyBoundaryConstraints: function( bounds, immediately ) { _applyBoundaryConstraints: function(bounds, immediately) {
var dx = 0, var newBounds = new $.Rect(
dy = 0,
newBounds = new $.Rect(
bounds.x, bounds.x,
bounds.y, bounds.y,
bounds.width, bounds.width,
bounds.height bounds.height);
);
var horizontalThreshold = this.visibilityRatio * newBounds.width; var horizontalThreshold = this.visibilityRatio * newBounds.width;
var verticalThreshold = this.visibilityRatio * newBounds.height; var verticalThreshold = this.visibilityRatio * newBounds.height;
if ( this.wrapHorizontal ) { if (this.wrapHorizontal) {
//do nothing //do nothing
} else { } else {
var dx = 0;
var thresholdLeft = newBounds.x + (newBounds.width - horizontalThreshold); var thresholdLeft = newBounds.x + (newBounds.width - horizontalThreshold);
if (this._contentBounds.x > thresholdLeft) { if (this._worldContentBounds.x > thresholdLeft) {
dx = this._contentBounds.x - thresholdLeft; dx = this._worldContentBounds.x - thresholdLeft;
} }
var homeRight = this._contentBounds.x + this._contentBounds.width; var contentRight = this._worldContentBounds.x + this._worldContentBounds.width;
var thresholdRight = newBounds.x + horizontalThreshold; var thresholdRight = newBounds.x + horizontalThreshold;
if (homeRight < thresholdRight) { if (contentRight < thresholdRight) {
var newDx = homeRight - thresholdRight; var newDx = contentRight - thresholdRight;
if (dx) { if (dx) {
dx = (dx + newDx) / 2; dx = (dx + newDx) / 2;
} else { } else {
dx = newDx; dx = newDx;
} }
} }
newBounds.x += dx;
} }
if ( this.wrapVertical ) { if (this.wrapVertical) {
//do nothing //do nothing
} else { } else {
var dy = 0;
var thresholdTop = newBounds.y + (newBounds.height - verticalThreshold); var thresholdTop = newBounds.y + (newBounds.height - verticalThreshold);
if (this._contentBounds.y > thresholdTop) { if (this._worldContentBounds.y > thresholdTop) {
dy = this._contentBounds.y - thresholdTop; dy = this._worldContentBounds.y - thresholdTop;
} }
var homeBottom = this._contentBounds.y + this._contentBounds.height; var contentBottom = this._worldContentBounds.y + this._worldContentBounds.height;
var thresholdBottom = newBounds.y + verticalThreshold; var thresholdBottom = newBounds.y + verticalThreshold;
if (homeBottom < thresholdBottom) { if (contentBottom < thresholdBottom) {
var newDy = homeBottom - thresholdBottom; var newDy = contentBottom - thresholdBottom;
if (dy) { if (dy) {
dy = (dy + newDy) / 2; dy = (dy + newDy) / 2;
} else { } else {
dy = newDy; dy = newDy;
} }
} }
}
if ( dx || dy ) {
newBounds.x += dx;
newBounds.y += dy; newBounds.y += dy;
} }
if( this.viewer ){ if (this.viewer) {
/** /**
* Raised when the viewport constraints are applied (see {@link OpenSeadragon.Viewport#applyConstraints}). * Raised when the viewport constraints are applied (see {@link OpenSeadragon.Viewport#applyConstraints}).
* *
@ -572,20 +573,14 @@ $.Viewport.prototype = {
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();
center = bounds.getCenter(), var center = bounds.getCenter();
newBounds = new $.Rect( var newBounds = new $.Rect(
bounds.x, bounds.x,
bounds.y, bounds.y,
bounds.width, bounds.width,
bounds.height bounds.height
), );
oldBounds,
oldZoom,
newZoom,
referencePoint,
newBoundsAspectRatio,
newConstrainedZoom;
if ( newBounds.getAspectRatio() >= aspect ) { if ( newBounds.getAspectRatio() >= aspect ) {
newBounds.height = bounds.width / aspect; newBounds.height = bounds.width / aspect;
@ -595,19 +590,16 @@ $.Viewport.prototype = {
newBounds.x = center.x - newBounds.width / 2; newBounds.x = center.x - newBounds.width / 2;
} }
if ( constraints ) {
newBoundsAspectRatio = newBounds.getAspectRatio();
}
this.panTo( this.getCenter( true ), true ); this.panTo( this.getCenter( true ), true );
this.zoomTo( this.getZoom( true ), null, true ); this.zoomTo( this.getZoom( true ), null, true );
oldBounds = this.getBounds(); var oldBounds = this.getBounds();
oldZoom = this.getZoom(); var oldZoom = this.getZoom();
newZoom = 1.0 / newBounds.width; var newZoom = 1.0 / newBounds.width;
if ( constraints ) { if (constraints) {
newConstrainedZoom = Math.max( var newBoundsAspectRatio = newBounds.getAspectRatio();
var newConstrainedZoom = Math.max(
Math.min(newZoom, this.getMaxZoom() ), Math.min(newZoom, this.getMaxZoom() ),
this.getMinZoom() this.getMinZoom()
); );
@ -634,7 +626,7 @@ $.Viewport.prototype = {
return this.panTo( center, immediately ); return this.panTo( center, immediately );
} }
referencePoint = oldBounds.getTopLeft().times( var referencePoint = oldBounds.getTopLeft().times(
this._containerInnerSize.x / oldBounds.width this._containerInnerSize.x / oldBounds.width
).minus( ).minus(
newBounds.getTopLeft().times( newBounds.getTopLeft().times(
@ -679,11 +671,13 @@ $.Viewport.prototype = {
* @param {Boolean} immediately * @param {Boolean} immediately
* @return {OpenSeadragon.Viewport} Chainable. * @return {OpenSeadragon.Viewport} Chainable.
*/ */
fitVertically: function( immediately ) { fitVertically: function(immediately) {
var box = new $.Rect(this._contentBounds.x + (this._contentBounds.width / 2), this._contentBounds.y, var box = new $.Rect(
0, this._contentBounds.height); this._contentBounds.x + (this._contentBounds.width / 2),
this._contentBounds.y,
return this.fitBounds( box, immediately ); 0,
this._contentBounds.height);
return this.fitBounds(box, immediately);
}, },
/** /**
@ -691,11 +685,13 @@ $.Viewport.prototype = {
* @param {Boolean} immediately * @param {Boolean} immediately
* @return {OpenSeadragon.Viewport} Chainable. * @return {OpenSeadragon.Viewport} Chainable.
*/ */
fitHorizontally: function( immediately ) { fitHorizontally: function(immediately) {
var box = new $.Rect(this._contentBounds.x, this._contentBounds.y + (this._contentBounds.height / 2), var box = new $.Rect(
this._contentBounds.width, 0); this._contentBounds.x,
this._contentBounds.y + (this._contentBounds.height / 2),
return this.fitBounds( box, immediately ); this._contentBounds.width,
0);
return this.fitBounds(box, immediately);
}, },
@ -1072,10 +1068,10 @@ $.Viewport.prototype = {
// private // private
_viewportToImageDelta: function( viewerX, viewerY ) { _viewportToImageDelta: function( viewerX, viewerY ) {
var scale = this._contentBounds.width; var scale = this._worldContentBounds.width;
return new $.Point( return new $.Point(
viewerX * this.contentSize.x / scale, viewerX * this._worldContentSize.x / scale,
viewerY * this.contentSize.x / scale); viewerY * this._worldContentSize.x / scale);
}, },
/** /**
@ -1099,15 +1095,17 @@ $.Viewport.prototype = {
$.console.error('[Viewport.viewportToImageCoordinates] is not accurate with multi-image; use TiledImage.viewportToImageCoordinates instead.'); $.console.error('[Viewport.viewportToImageCoordinates] is not accurate with multi-image; use TiledImage.viewportToImageCoordinates instead.');
} }
return this._viewportToImageDelta(viewerX - this._contentBounds.x, viewerY - this._contentBounds.y); return this._viewportToImageDelta(
viewerX - this._worldContentBounds.x,
viewerY - this._worldContentBounds.y);
}, },
// private // private
_imageToViewportDelta: function( imageX, imageY ) { _imageToViewportDelta: function( imageX, imageY ) {
var scale = this._contentBounds.width; var scale = this._worldContentBounds.width;
return new $.Point( return new $.Point(
imageX / this.contentSize.x * scale, imageX / this._worldContentSize.x * scale,
imageY / this.contentSize.x * scale); imageY / this._worldContentSize.x * scale);
}, },
/** /**
@ -1132,8 +1130,8 @@ $.Viewport.prototype = {
} }
var point = this._imageToViewportDelta(imageX, imageY); var point = this._imageToViewportDelta(imageX, imageY);
point.x += this._contentBounds.x; point.x += this._worldContentBounds.x;
point.y += this._contentBounds.y; point.y += this._worldContentBounds.y;
return point; return point;
}, },
@ -1309,9 +1307,9 @@ $.Viewport.prototype = {
$.console.error('[Viewport.viewportToImageZoom] is not accurate with multi-image.'); $.console.error('[Viewport.viewportToImageZoom] is not accurate with multi-image.');
} }
var imageWidth = this.contentSize.x; var imageWidth = this._worldContentSize.x;
var containerWidth = this._containerInnerSize.x; var containerWidth = this._containerInnerSize.x;
var scale = this._contentBounds.width; var scale = this._worldContentBounds.width;
var viewportToImageZoomRatio = (containerWidth / imageWidth) * scale; var viewportToImageZoomRatio = (containerWidth / imageWidth) * scale;
return viewportZoom * viewportToImageZoomRatio; return viewportZoom * viewportToImageZoomRatio;
}, },
@ -1333,9 +1331,9 @@ $.Viewport.prototype = {
$.console.error('[Viewport.imageToViewportZoom] is not accurate with multi-image.'); $.console.error('[Viewport.imageToViewportZoom] is not accurate with multi-image.');
} }
var imageWidth = this.contentSize.x; var imageWidth = this._worldContentSize.x;
var containerWidth = this._containerInnerSize.x; var containerWidth = this._containerInnerSize.x;
var scale = this._contentBounds.width; var scale = this._worldContentBounds.width;
var viewportToImageZoomRatio = (imageWidth / containerWidth) / scale; var viewportToImageZoomRatio = (imageWidth / containerWidth) / scale;
return imageZoom * viewportToImageZoomRatio; return imageZoom * viewportToImageZoomRatio;
} }

View File

@ -78,9 +78,11 @@
if (navigator === null) { if (navigator === null) {
navigator = $(".navigator"); navigator = $(".navigator");
navigatorScaleFactor = Math.min(navigator.width() / viewer.viewport.contentSize.x, navigator.height() / viewer.viewport.contentSize.y); navigatorScaleFactor = Math.min(
displayRegionWidth = viewer.viewport.contentSize.x * navigatorScaleFactor; navigator.width() / viewer.viewport._contentSize.x,
displayRegionHeight = viewer.viewport.contentSize.y * navigatorScaleFactor; navigator.height() / viewer.viewport._contentSize.y);
displayRegionWidth = viewer.viewport._contentSize.x * navigatorScaleFactor;
displayRegionHeight = viewer.viewport._contentSize.y * navigatorScaleFactor;
contentStartFromLeft = (navigator.width() - displayRegionWidth) / 2; contentStartFromLeft = (navigator.width() - displayRegionWidth) / 2;
contentStartFromTop = (navigator.height() - displayRegionHeight) / 2; contentStartFromTop = (navigator.height() - displayRegionHeight) / 2;
} }
@ -91,8 +93,8 @@
regionBoundsInPoints = new OpenSeadragon.Rect(expectedDisplayRegionXLocation, expectedDisplayRegionYLocation, expectedDisplayRegionWidth, expectedDisplayRegionHeight); regionBoundsInPoints = new OpenSeadragon.Rect(expectedDisplayRegionXLocation, expectedDisplayRegionYLocation, expectedDisplayRegionWidth, expectedDisplayRegionHeight);
if (debug) { if (debug) {
console.log('Image width: ' + viewer.viewport.contentSize.x + '\n' + console.log('Image width: ' + viewer.viewport._contentSize.x + '\n' +
'Image height: ' + viewer.viewport.contentSize.y + '\n' + 'Image height: ' + viewer.viewport._contentSize.y + '\n' +
'navigator.width(): ' + navigator.width() + '\n' + 'navigator.width(): ' + navigator.width() + '\n' +
'navigator.height(): ' + navigator.height() + '\n' + 'navigator.height(): ' + navigator.height() + '\n' +
'navigatorScaleFactor: ' + navigatorScaleFactor + '\n' + 'navigatorScaleFactor: ' + navigatorScaleFactor + '\n' +

View File

@ -305,7 +305,7 @@
var rect = testRects[i].times(viewport.getContainerSize()); var rect = testRects[i].times(viewport.getContainerSize());
viewport.resetContentSize(rect.getSize()); viewport.resetContentSize(rect.getSize());
propEqual( propEqual(
viewport.contentSize, viewport._contentSize,
rect.getSize(), rect.getSize(),
"Reset content size correctly." "Reset content size correctly."
); );