From 1d04ceadffc7213634e513f9fe4a4cf2dbc20547 Mon Sep 17 00:00:00 2001 From: Antoine Vandecreme Date: Sat, 5 Dec 2015 19:18:56 -0500 Subject: [PATCH] Fix home bounds with rotation. Fix #567 and #463 --- src/viewport.js | 23 +++++++++------- test/helpers/test.js | 18 ++++++++++++ test/modules/rectangle.js | 58 +++++++++++++++------------------------ test/modules/viewport.js | 20 ++++++++++++++ 4 files changed, 73 insertions(+), 46 deletions(-) diff --git a/src/viewport.js b/src/viewport.js index c619198d..b69ccbcb 100644 --- a/src/viewport.js +++ b/src/viewport.js @@ -175,12 +175,12 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{ $.console.assert(bounds.width > 0, "[Viewport.setHomeBounds] bounds.width must be greater than 0"); $.console.assert(bounds.height > 0, "[Viewport.setHomeBounds] bounds.height must be greater than 0"); - this.homeBounds = bounds.clone(); + this.homeBounds = bounds.clone().rotate(this.degrees).getBoundingBox(); this.contentSize = this.homeBounds.getSize().times(contentFactor); this.contentAspectX = this.contentSize.x / this.contentSize.y; this.contentAspectY = this.contentSize.y / this.contentSize.x; - if( this.viewer ){ + if (this.viewer) { /** * Raised when the viewer's content size or home bounds are reset * (see {@link OpenSeadragon.Viewport#resetContentSize}, @@ -195,7 +195,7 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{ * @property {Number} contentFactor * @property {?Object} userData - Arbitrary subscriber-defined object. */ - this.viewer.raiseEvent( 'reset-size', { + this.viewer.raiseEvent('reset-size', { contentSize: this.contentSize.clone(), contentFactor: contentFactor, homeBounds: this.homeBounds.clone() @@ -807,13 +807,19 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{ * @function * @return {OpenSeadragon.Viewport} Chainable. */ - setRotation: function( degrees ) { - if( !( this.viewer && this.viewer.drawer.canRotate() ) ) { + setRotation: function(degrees) { + if (!this.viewer || !this.viewer.drawer.canRotate()) { return this; } - degrees = ( degrees + 360 ) % 360; + degrees = degrees % 360; + if (degrees < 0) { + degrees += 360; + } this.degrees = degrees; + this.setHomeBounds( + this.viewer.world.getHomeBounds(), + this.viewer.world.getContentFactor()); this.viewer.forceRedraw(); /** @@ -826,10 +832,7 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{ * @property {Number} degrees - The number of degrees the rotation was set to. * @property {?Object} userData - Arbitrary subscriber-defined object. */ - if (this.viewer !== null) - { - this.viewer.raiseEvent('rotate', {"degrees": degrees}); - } + this.viewer.raiseEvent('rotate', {"degrees": degrees}); return this; }, diff --git a/test/helpers/test.js b/test/helpers/test.js index 54a28412..3dbb5468 100644 --- a/test/helpers/test.js +++ b/test/helpers/test.js @@ -68,6 +68,24 @@ ok( Util.equalsWithVariance( value1, value2, variance ), message + " Expected:" + value1 + " Found: " + value2 + " Variance: " + variance ); }, + // ---------- + assertPointsEquals: function (pointA, pointB, precision, message) { + Util.assessNumericValue(pointA.x, pointB.x, precision, message + " x: "); + Util.assessNumericValue(pointA.y, pointB.y, precision, message + " y: "); + }, + + // ---------- + assertRectangleEquals: function (rectA, rectB, precision, message) { + Util.assessNumericValue(rectA.x, rectB.x, precision, message + " x: "); + Util.assessNumericValue(rectA.y, rectB.y, precision, message + " y: "); + Util.assessNumericValue(rectA.width, rectB.width, precision, + message + " width: "); + Util.assessNumericValue(rectA.height, rectB.height, precision, + message + " height: "); + Util.assessNumericValue(rectA.degrees, rectB.degrees, precision, + message + " degrees: "); + }, + // ---------- timeWatcher: function ( time ) { time = time || 2000; diff --git a/test/modules/rectangle.js b/test/modules/rectangle.js index 437f20b4..7e905f58 100644 --- a/test/modules/rectangle.js +++ b/test/modules/rectangle.js @@ -6,22 +6,6 @@ var precision = 0.000000001; - function assertPointsEquals(pointA, pointB, message) { - Util.assessNumericValue(pointA.x, pointB.x, precision, message + " x: "); - Util.assessNumericValue(pointA.y, pointB.y, precision, message + " y: "); - } - - function assertRectangleEquals(rectA, rectB, message) { - Util.assessNumericValue(rectA.x, rectB.x, precision, message + " x: "); - Util.assessNumericValue(rectA.y, rectB.y, precision, message + " y: "); - Util.assessNumericValue(rectA.width, rectB.width, precision, - message + " width: "); - Util.assessNumericValue(rectA.height, rectB.height, precision, - message + " height: "); - Util.assessNumericValue(rectA.degrees, rectB.degrees, precision, - message + " degrees: "); - } - test('Constructor', function() { var rect = new OpenSeadragon.Rect(1, 2, 3, 4, 5); strictEqual(rect.x, 1, 'rect.x should be 1'); @@ -84,7 +68,7 @@ rect.degrees = 45; expected = new OpenSeadragon.Point(1 / Math.sqrt(2), 1 / Math.sqrt(2)); - assertPointsEquals(expected, rect.getTopRight(), + Util.assertPointsEquals(expected, rect.getTopRight(), precision, "Incorrect top right point with rotation."); }); @@ -95,7 +79,7 @@ rect.degrees = 45; expected = new OpenSeadragon.Point(-1 / Math.sqrt(2), 1 / Math.sqrt(2)); - assertPointsEquals(expected, rect.getBottomLeft(), + Util.assertPointsEquals(expected, rect.getBottomLeft(), precision, "Incorrect bottom left point with rotation."); }); @@ -106,17 +90,17 @@ rect.degrees = 45; expected = new OpenSeadragon.Point(0, Math.sqrt(2)); - assertPointsEquals(expected, rect.getBottomRight(), + Util.assertPointsEquals(expected, rect.getBottomRight(), precision, "Incorrect bottom right point with 45 rotation."); rect.degrees = 90; expected = new OpenSeadragon.Point(-1, 1); - assertPointsEquals(expected, rect.getBottomRight(), + Util.assertPointsEquals(expected, rect.getBottomRight(), precision, "Incorrect bottom right point with 90 rotation."); rect.degrees = 135; expected = new OpenSeadragon.Point(-Math.sqrt(2), 0); - assertPointsEquals(expected, rect.getBottomRight(), + Util.assertPointsEquals(expected, rect.getBottomRight(), precision, "Incorrect bottom right point with 135 rotation."); }); @@ -127,17 +111,17 @@ rect.degrees = 45; expected = new OpenSeadragon.Point(0, 0.5 * Math.sqrt(2)); - assertPointsEquals(expected, rect.getCenter(), + Util.assertPointsEquals(expected, rect.getCenter(), precision, "Incorrect bottom right point with 45 rotation."); rect.degrees = 90; expected = new OpenSeadragon.Point(-0.5, 0.5); - assertPointsEquals(expected, rect.getCenter(), + Util.assertPointsEquals(expected, rect.getCenter(), precision, "Incorrect bottom right point with 90 rotation."); rect.degrees = 135; expected = new OpenSeadragon.Point(-0.5 * Math.sqrt(2), 0); - assertPointsEquals(expected, rect.getCenter(), + Util.assertPointsEquals(expected, rect.getCenter(), precision, "Incorrect bottom right point with 135 rotation."); }); @@ -145,14 +129,16 @@ var rect = new OpenSeadragon.Rect(1, 2, 3, 4, 45); var expected = new OpenSeadragon.Rect(2, 4, 6, 8, 45); var actual = rect.times(2); - assertRectangleEquals(expected, actual, "Incorrect x2 rectangles."); + Util.assertRectangleEquals(expected, actual, precision, + "Incorrect x2 rectangles."); }); test('translate', function() { var rect = new OpenSeadragon.Rect(1, 2, 3, 4, 45); var expected = new OpenSeadragon.Rect(2, 4, 3, 4, 45); var actual = rect.translate(new OpenSeadragon.Point(1, 2)); - assertRectangleEquals(expected, actual, "Incorrect translation."); + Util.assertRectangleEquals(expected, actual, precision, + "Incorrect translation."); }); test('union', function() { @@ -160,7 +146,7 @@ var rect2 = new OpenSeadragon.Rect(0, 1, 1, 1); var expected = new OpenSeadragon.Rect(0, 1, 4, 4); var actual = rect1.union(rect2); - assertRectangleEquals(expected, actual, + Util.assertRectangleEquals(expected, actual, precision, "Incorrect union with horizontal rectangles."); rect1 = new OpenSeadragon.Rect(0, -Math.sqrt(2), 2, 2, 45); @@ -171,7 +157,7 @@ 3 + Math.sqrt(2), 2 + Math.sqrt(2)); actual = rect1.union(rect2); - assertRectangleEquals(expected, actual, + Util.assertRectangleEquals(expected, actual, precision, "Incorrect union with non horizontal rectangles."); }); @@ -185,27 +171,27 @@ 1, 45); var actual = rect.rotate(-675); - assertRectangleEquals(expected, actual, + Util.assertRectangleEquals(expected, actual, precision, "Incorrect rectangle after rotation of -675deg around center."); expected = new OpenSeadragon.Rect(0, 0, 2, 1, 33); actual = rect.rotate(33, rect.getTopLeft()); - assertRectangleEquals(expected, actual, + Util.assertRectangleEquals(expected, actual, precision, "Incorrect rectangle after rotation of 33deg around topLeft."); expected = new OpenSeadragon.Rect(0, 0, 2, 1, 101); actual = rect.rotate(101, rect.getTopLeft()); - assertRectangleEquals(expected, actual, + Util.assertRectangleEquals(expected, actual, precision, "Incorrect rectangle after rotation of 187deg around topLeft."); expected = new OpenSeadragon.Rect(0, 0, 2, 1, 187); actual = rect.rotate(187, rect.getTopLeft()); - assertRectangleEquals(expected, actual, + Util.assertRectangleEquals(expected, actual, precision, "Incorrect rectangle after rotation of 187deg around topLeft."); expected = new OpenSeadragon.Rect(0, 0, 2, 1, 300); actual = rect.rotate(300, rect.getTopLeft()); - assertRectangleEquals(expected, actual, + Util.assertRectangleEquals(expected, actual, precision, "Incorrect rectangle after rotation of 300deg around topLeft."); }); @@ -218,17 +204,17 @@ rect.degrees = 90; var expected = new OpenSeadragon.Rect(-3, 0, 3, 2); - assertRectangleEquals(expected, rect.getBoundingBox(), + Util.assertRectangleEquals(expected, rect.getBoundingBox(), precision, "Bounding box of rect rotated 90deg."); rect.degrees = 180; var expected = new OpenSeadragon.Rect(-2, -3, 2, 3); - assertRectangleEquals(expected, rect.getBoundingBox(), + Util.assertRectangleEquals(expected, rect.getBoundingBox(), precision, "Bounding box of rect rotated 180deg."); rect.degrees = 270; var expected = new OpenSeadragon.Rect(0, -2, 3, 2); - assertRectangleEquals(expected, rect.getBoundingBox(), + Util.assertRectangleEquals(expected, rect.getBoundingBox(), precision, "Bounding box of rect rotated 270deg."); }); diff --git a/test/modules/viewport.js b/test/modules/viewport.js index f480a6cd..ff485395 100644 --- a/test/modules/viewport.js +++ b/test/modules/viewport.js @@ -218,6 +218,26 @@ }); }); + asyncTest('getHomeBoundsWithRotation', function() { + function openHandler() { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.setRotation(-675); + Util.assertRectangleEquals( + viewport.getHomeBounds(), + new OpenSeadragon.Rect( + (1 - Math.sqrt(2)) / 2, + (1 - Math.sqrt(2)) / 2, + Math.sqrt(2), + Math.sqrt(2)), + 0.00000001, + "Test getHomeBounds with degrees = -675"); + start(); + } + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + asyncTest('getHomeZoom', function() { reopenViewerHelper({ property: 'defaultZoomLevel',