diff --git a/src/viewport.js b/src/viewport.js index e5c4f51a..da2ce761 100644 --- a/src/viewport.js +++ b/src/viewport.js @@ -664,15 +664,15 @@ $.Viewport.prototype = { var oldBounds = this.getBounds(); var oldZoom = this.getZoom(); - if (Math.abs(newZoom - oldZoom) < 0.00000001 || - Math.abs(newBounds.width - oldBounds.width) < 0.00000001) { + if (oldZoom === 0 || Math.abs(newZoom / oldZoom - 1) < 0.00000001) { + this.zoomTo(newZoom, true); return this.panTo(center, immediately); } newBounds = newBounds.rotate(-this.getRotation()); - var referencePoint = newBounds.getTopLeft().divide(newBounds.width) - .minus(oldBounds.getTopLeft().divide(oldBounds.width)) - .divide(1 / newBounds.width - 1 / oldBounds.width); + var referencePoint = newBounds.getTopLeft().times(newZoom) + .minus(oldBounds.getTopLeft().times(oldZoom)) + .divide(newZoom - oldZoom); return this.zoomTo(newZoom, referencePoint, immediately); }, diff --git a/test/modules/viewport.js b/test/modules/viewport.js index c3618be9..f39473cf 100644 --- a/test/modules/viewport.js +++ b/test/modules/viewport.js @@ -587,6 +587,44 @@ viewer.open(DZI_PATH); }); + asyncTest('fitBounds with almost same zoom', function() { + var openHandler = function() { + var viewport = viewer.viewport; + var rect1 = new OpenSeadragon.Rect(0, 0, 1, 1); + viewport.fitBounds(rect1, true); + Util.assertRectangleEquals(rect1, viewport.getBounds(), 1e-6, + 'Bounds should be ' + rect1); + + // Zoom and pan + var rect2 = new OpenSeadragon.Rect(1, 1, 1 + 1e-8, 1 + 1e-8); + viewport.fitBounds(rect2); + Util.assertRectangleEquals(rect2, viewport.getBounds(), 1e-6, + 'Bounds should be ' + rect2); + start(); + }; + viewer.addOnceHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + + asyncTest('fitBounds with big rectangle', function() { + var openHandler = function() { + var viewport = viewer.viewport; + var rect1 = new OpenSeadragon.Rect(0, 0, 1e9, 1e9); + viewport.fitBounds(rect1, true); + Util.assertRectangleEquals(rect1, viewport.getBounds(), 1e-6, + 'Bounds should be ' + rect1); + + // Zoom and pan + var rect2 = new OpenSeadragon.Rect(1, 1, 2e9, 2e9); + viewport.fitBounds(rect2); + Util.assertRectangleEquals(rect2, viewport.getBounds(), 1e-6, + 'Bounds should be ' + rect2); + start(); + }; + viewer.addOnceHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + asyncTest('fitHorizontally', function(){ var openHandler = function(event) { viewer.removeHandler('open', openHandler);