mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 22:56:11 +03:00
Fix Overlays.getBounds with rotation.
This commit is contained in:
parent
0685d8a3a4
commit
bd62d56a37
@ -131,7 +131,6 @@
|
|||||||
|
|
||||||
/** @lends OpenSeadragon.Overlay.prototype */
|
/** @lends OpenSeadragon.Overlay.prototype */
|
||||||
$.Overlay.prototype = {
|
$.Overlay.prototype = {
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_init: function(options) {
|
_init: function(options) {
|
||||||
this.location = options.location;
|
this.location = options.location;
|
||||||
@ -157,7 +156,6 @@
|
|||||||
this.placement = $.Placement.TOP_LEFT;
|
this.placement = $.Placement.TOP_LEFT;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal function to adjust the position of an overlay
|
* Internal function to adjust the position of an overlay
|
||||||
* depending on it size and placement.
|
* depending on it size and placement.
|
||||||
@ -181,7 +179,6 @@
|
|||||||
position.y -= size.y;
|
position.y -= size.y;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*/
|
*/
|
||||||
@ -225,7 +222,6 @@
|
|||||||
style[transformProp] = "";
|
style[transformProp] = "";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
* @param {Element} container
|
* @param {Element} container
|
||||||
@ -283,7 +279,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_getOverlayPositionAndSize: function(viewport) {
|
_getOverlayPositionAndSize: function(viewport) {
|
||||||
var position = viewport.pixelFromPoint(this.location, true);
|
var position = viewport.pixelFromPoint(this.location, true);
|
||||||
@ -312,7 +307,6 @@
|
|||||||
rotate: rotate
|
rotate: rotate
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_getSizeInPixels: function(viewport) {
|
_getSizeInPixels: function(viewport) {
|
||||||
var width = this.size.x;
|
var width = this.size.x;
|
||||||
@ -339,26 +333,29 @@
|
|||||||
}
|
}
|
||||||
return new $.Point(width, height);
|
return new $.Point(width, height);
|
||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_getBoundingBox: function(rect, degrees) {
|
_getBoundingBox: function(rect, degrees) {
|
||||||
var refPoint = new $.Point(rect.x, rect.y);
|
var refPoint = this._getPlacementPoint(rect);
|
||||||
|
return rect.rotate(degrees, refPoint).getBoundingBox();
|
||||||
|
},
|
||||||
|
// private
|
||||||
|
_getPlacementPoint: function(rect) {
|
||||||
|
var result = new $.Point(rect.x, rect.y);
|
||||||
var properties = $.Placement.properties[this.placement];
|
var properties = $.Placement.properties[this.placement];
|
||||||
if (properties) {
|
if (properties) {
|
||||||
if (properties.isHorizontallyCentered) {
|
if (properties.isHorizontallyCentered) {
|
||||||
refPoint.x += rect.width / 2;
|
result.x += rect.width / 2;
|
||||||
} else if (properties.isRight) {
|
} else if (properties.isRight) {
|
||||||
refPoint.x += rect.width;
|
result.x += rect.width;
|
||||||
}
|
}
|
||||||
if (properties.isVerticallyCentered) {
|
if (properties.isVerticallyCentered) {
|
||||||
refPoint.y += rect.height / 2;
|
result.y += rect.height / 2;
|
||||||
} else if (properties.isBottom) {
|
} else if (properties.isBottom) {
|
||||||
refPoint.y += rect.height;
|
result.y += rect.height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rect.rotate(degrees, refPoint).getBoundingBox();
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_getTransformOrigin: function() {
|
_getTransformOrigin: function() {
|
||||||
var result = "";
|
var result = "";
|
||||||
@ -378,7 +375,6 @@
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the overlay settings.
|
* Changes the overlay settings.
|
||||||
* @function
|
* @function
|
||||||
@ -403,7 +399,6 @@
|
|||||||
rotationMode: options.rotationMode || this.rotationMode
|
rotationMode: options.rotationMode || this.rotationMode
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current bounds of the overlay in viewport coordinates
|
* Returns the current bounds of the overlay in viewport coordinates
|
||||||
* @function
|
* @function
|
||||||
@ -411,11 +406,11 @@
|
|||||||
* @returns {OpenSeadragon.Rect} overlay bounds
|
* @returns {OpenSeadragon.Rect} overlay bounds
|
||||||
*/
|
*/
|
||||||
getBounds: function(viewport) {
|
getBounds: function(viewport) {
|
||||||
|
$.console.assert(!viewport, 'Calling Overlay.getBounds withouth ' +
|
||||||
|
'specifying a viewport is deprecated.');
|
||||||
var width = this.width;
|
var width = this.width;
|
||||||
var height = this.height;
|
var height = this.height;
|
||||||
if (width === null || height === null) {
|
if (width === null || height === null) {
|
||||||
$.console.assert(!viewport, 'The viewport must be specified to' +
|
|
||||||
' get the bounds of a not entirely scaling overlay');
|
|
||||||
var size = viewport.deltaPointsFromPixelsNoRotate(this.size, true);
|
var size = viewport.deltaPointsFromPixelsNoRotate(this.size, true);
|
||||||
if (width === null) {
|
if (width === null) {
|
||||||
width = size.x;
|
width = size.x;
|
||||||
@ -426,7 +421,23 @@
|
|||||||
}
|
}
|
||||||
var location = this.location.clone();
|
var location = this.location.clone();
|
||||||
this.adjust(location, new $.Point(width, height));
|
this.adjust(location, new $.Point(width, height));
|
||||||
return new $.Rect(location.x, location.y, width, height);
|
return this._adjustBoundsForRotation(
|
||||||
|
viewport, new $.Rect(location.x, location.y, width, height));
|
||||||
|
},
|
||||||
|
|
||||||
|
_adjustBoundsForRotation: function(viewport, bounds) {
|
||||||
|
if (!viewport ||
|
||||||
|
viewport.degrees === 0 ||
|
||||||
|
this.rotationMode === $.OverlayRotationMode.EXACT) {
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
// If overlay not fully scalable, BOUNDING_BOX falls back to EXACT
|
||||||
|
if (this.rotationMode === $.OverlayRotationMode.BOUNDING_BOX &&
|
||||||
|
(this.width === null || this.height === null)) {
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
return bounds.rotate(-viewport.degrees,
|
||||||
|
this._getPlacementPoint(bounds));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -658,6 +658,7 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
asyncTest('Overlay.getBounds', function() {
|
asyncTest('Overlay.getBounds', function() {
|
||||||
viewer = OpenSeadragon({
|
viewer = OpenSeadragon({
|
||||||
id: 'example-overlays',
|
id: 'example-overlays',
|
||||||
@ -710,7 +711,7 @@
|
|||||||
viewer._drawOverlays();
|
viewer._drawOverlays();
|
||||||
|
|
||||||
var actualBounds = viewer.getOverlayById("fully-scaled-overlay")
|
var actualBounds = viewer.getOverlayById("fully-scaled-overlay")
|
||||||
.getBounds();
|
.getBounds(viewer.viewport);
|
||||||
var expectedBounds = new OpenSeadragon.Rect(0, 0, 1, 1);
|
var expectedBounds = new OpenSeadragon.Rect(0, 0, 1, 1);
|
||||||
ok(expectedBounds.equals(actualBounds),
|
ok(expectedBounds.equals(actualBounds),
|
||||||
"The fully scaled overlay should have bounds " +
|
"The fully scaled overlay should have bounds " +
|
||||||
@ -745,4 +746,240 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
asyncTest('Fully scaled overlay rotation mode NO_ROTATION', function() {
|
||||||
|
viewer = OpenSeadragon({
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: '/test/data/testpattern.dzi',
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
degrees: 45,
|
||||||
|
overlays: [{
|
||||||
|
id: "fully-scaled-overlay",
|
||||||
|
x: 1,
|
||||||
|
y: 1,
|
||||||
|
width: 1,
|
||||||
|
height: 1,
|
||||||
|
placement: OpenSeadragon.Placement.BOTTOM_RIGHT,
|
||||||
|
rotationMode: OpenSeadragon.OverlayRotationMode.NO_ROTATION
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.addOnceHandler('open', function() {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
var $overlay = $("#fully-scaled-overlay");
|
||||||
|
var expectedSize = viewport.deltaPixelsFromPointsNoRotate(
|
||||||
|
new OpenSeadragon.Point(1, 1));
|
||||||
|
var expectedPosition = viewport.viewportToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point(1, 1))
|
||||||
|
.minus(expectedSize);
|
||||||
|
var actualPosition = $overlay.position();
|
||||||
|
Util.assessNumericValue(actualPosition.left, expectedPosition.x, epsilon,
|
||||||
|
"Scaled overlay position.x should adjust to rotation.");
|
||||||
|
Util.assessNumericValue(actualPosition.top, expectedPosition.y, epsilon,
|
||||||
|
"Scaled overlay position.y should adjust to rotation.");
|
||||||
|
|
||||||
|
var actualWidth = $overlay.width();
|
||||||
|
var actualHeight = $overlay.height();
|
||||||
|
Util.assessNumericValue(actualWidth, expectedSize.x, epsilon,
|
||||||
|
"Scaled overlay width should not adjust to rotation.");
|
||||||
|
Util.assessNumericValue(actualHeight, expectedSize.y, epsilon,
|
||||||
|
"Scaled overlay height should not adjust to rotation.");
|
||||||
|
|
||||||
|
var actualBounds = viewer.getOverlayById("fully-scaled-overlay")
|
||||||
|
.getBounds(viewport);
|
||||||
|
var expectedBounds = new OpenSeadragon.Rect(0, 0, 1, 1)
|
||||||
|
.rotate(-45, new OpenSeadragon.Point(1, 1));
|
||||||
|
ok(expectedBounds.equals(actualBounds),
|
||||||
|
"The fully scaled overlay should have bounds " +
|
||||||
|
expectedBounds.toString() + " but found " + actualBounds);
|
||||||
|
|
||||||
|
start();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
asyncTest('Horizontally scaled overlay rotation mode NO_ROTATION', function() {
|
||||||
|
viewer = OpenSeadragon({
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: '/test/data/testpattern.dzi',
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
degrees: 45,
|
||||||
|
overlays: [{
|
||||||
|
id: "horizontally-scaled-overlay",
|
||||||
|
x: 0.5,
|
||||||
|
y: 0.5,
|
||||||
|
width: 1,
|
||||||
|
placement: OpenSeadragon.Placement.CENTER,
|
||||||
|
rotationMode: OpenSeadragon.OverlayRotationMode.NO_ROTATION
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.addOnceHandler('open', function() {
|
||||||
|
var $overlay = $("#horizontally-scaled-overlay");
|
||||||
|
var notScaledWidth = 100;
|
||||||
|
var notScaledHeight = 100;
|
||||||
|
$overlay.get(0).style.height = notScaledHeight + "px";
|
||||||
|
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
var notScaledSize = viewport.deltaPointsFromPixelsNoRotate(
|
||||||
|
new OpenSeadragon.Point(notScaledWidth, notScaledHeight));
|
||||||
|
|
||||||
|
// Force refresh to takes new dimensions into account.
|
||||||
|
viewer._drawOverlays();
|
||||||
|
|
||||||
|
var expectedWidth = viewport.deltaPixelsFromPointsNoRotate(
|
||||||
|
new OpenSeadragon.Point(1, 1)).x;
|
||||||
|
var expectedPosition = viewport.viewportToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point(0.5, 0.5))
|
||||||
|
.minus(new OpenSeadragon.Point(expectedWidth / 2, notScaledHeight / 2));
|
||||||
|
var actualPosition = $overlay.position();
|
||||||
|
Util.assessNumericValue(actualPosition.left, expectedPosition.x, epsilon,
|
||||||
|
"Horizontally scaled overlay position.x should adjust to rotation.");
|
||||||
|
Util.assessNumericValue(actualPosition.top, expectedPosition.y, epsilon,
|
||||||
|
"Horizontally scaled overlay position.y should adjust to rotation.");
|
||||||
|
|
||||||
|
var actualWidth = $overlay.width();
|
||||||
|
var actualHeight = $overlay.height();
|
||||||
|
Util.assessNumericValue(actualWidth, expectedWidth, epsilon,
|
||||||
|
"Horizontally scaled overlay width should not adjust to rotation.");
|
||||||
|
Util.assessNumericValue(actualHeight, notScaledHeight, epsilon,
|
||||||
|
"Horizontally scaled overlay height should not adjust to rotation.");
|
||||||
|
|
||||||
|
var actualBounds = viewer.getOverlayById("horizontally-scaled-overlay")
|
||||||
|
.getBounds(viewport);
|
||||||
|
var expectedBounds = new OpenSeadragon.Rect(
|
||||||
|
0, 0.5 - notScaledSize.y / 2, 1, notScaledSize.y)
|
||||||
|
.rotate(-45, new OpenSeadragon.Point(0.5, 0.5));
|
||||||
|
ok(expectedBounds.equals(actualBounds),
|
||||||
|
"The horizontally scaled overlay should have bounds " +
|
||||||
|
expectedBounds.toString() + " but found " + actualBounds);
|
||||||
|
|
||||||
|
start();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
asyncTest('Vertically scaled overlay rotation mode NO_ROTATION', function() {
|
||||||
|
viewer = OpenSeadragon({
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: '/test/data/testpattern.dzi',
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
degrees: 45,
|
||||||
|
overlays: [{
|
||||||
|
id: "vertically-scaled-overlay",
|
||||||
|
x: 0,
|
||||||
|
y: 0.5,
|
||||||
|
height: 1,
|
||||||
|
placement: OpenSeadragon.Placement.LEFT,
|
||||||
|
rotationMode: OpenSeadragon.OverlayRotationMode.NO_ROTATION
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.addOnceHandler('open', function() {
|
||||||
|
var $overlay = $("#vertically-scaled-overlay");
|
||||||
|
var notScaledWidth = 100;
|
||||||
|
var notScaledHeight = 100;
|
||||||
|
$overlay.get(0).style.width = notScaledWidth + "px";
|
||||||
|
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
var notScaledSize = viewport.deltaPointsFromPixelsNoRotate(
|
||||||
|
new OpenSeadragon.Point(notScaledWidth, notScaledHeight));
|
||||||
|
|
||||||
|
// Force refresh to takes new dimensions into account.
|
||||||
|
viewer._drawOverlays();
|
||||||
|
|
||||||
|
var expectedHeight = viewport.deltaPixelsFromPointsNoRotate(
|
||||||
|
new OpenSeadragon.Point(1, 1)).y;
|
||||||
|
var expectedPosition = viewport.viewportToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point(0, 0.5))
|
||||||
|
.minus(new OpenSeadragon.Point(0, expectedHeight / 2));
|
||||||
|
var actualPosition = $overlay.position();
|
||||||
|
Util.assessNumericValue(actualPosition.left, expectedPosition.x, epsilon,
|
||||||
|
"Vertically scaled overlay position.x should adjust to rotation.");
|
||||||
|
Util.assessNumericValue(actualPosition.top, expectedPosition.y, epsilon,
|
||||||
|
"Vertically scaled overlay position.y should adjust to rotation.");
|
||||||
|
|
||||||
|
var actualWidth = $overlay.width();
|
||||||
|
var actualHeight = $overlay.height();
|
||||||
|
Util.assessNumericValue(actualWidth, notScaledWidth, epsilon,
|
||||||
|
"Vertically scaled overlay width should not adjust to rotation.");
|
||||||
|
Util.assessNumericValue(actualHeight, expectedHeight, epsilon,
|
||||||
|
"Vertically scaled overlay height should not adjust to rotation.");
|
||||||
|
|
||||||
|
var actualBounds = viewer.getOverlayById("vertically-scaled-overlay")
|
||||||
|
.getBounds(viewport);
|
||||||
|
var expectedBounds = new OpenSeadragon.Rect(
|
||||||
|
0, 0, notScaledSize.x, 1)
|
||||||
|
.rotate(-45, new OpenSeadragon.Point(0, 0.5));
|
||||||
|
ok(expectedBounds.equals(actualBounds),
|
||||||
|
"The vertically scaled overlay should have bounds " +
|
||||||
|
expectedBounds.toString() + " but found " + actualBounds);
|
||||||
|
|
||||||
|
start();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
asyncTest('Not scaled overlay rotation mode NO_ROTATION', function() {
|
||||||
|
viewer = OpenSeadragon({
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: '/test/data/testpattern.dzi',
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
degrees: 45,
|
||||||
|
overlays: [{
|
||||||
|
id: "not-scaled-overlay",
|
||||||
|
x: 1,
|
||||||
|
y: 0,
|
||||||
|
placement: OpenSeadragon.Placement.TOP_RIGHT,
|
||||||
|
rotationMode: OpenSeadragon.OverlayRotationMode.NO_ROTATION
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.addOnceHandler('open', function() {
|
||||||
|
var $overlay = $("#not-scaled-overlay");
|
||||||
|
var notScaledWidth = 100;
|
||||||
|
var notScaledHeight = 100;
|
||||||
|
$overlay.get(0).style.width = notScaledWidth + "px";
|
||||||
|
$overlay.get(0).style.height = notScaledHeight + "px";
|
||||||
|
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
var notScaledSize = viewport.deltaPointsFromPixelsNoRotate(
|
||||||
|
new OpenSeadragon.Point(notScaledWidth, notScaledHeight));
|
||||||
|
|
||||||
|
// Force refresh to takes new dimensions into account.
|
||||||
|
viewer._drawOverlays();
|
||||||
|
|
||||||
|
var expectedPosition = viewport.viewportToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point(1, 0))
|
||||||
|
.minus(new OpenSeadragon.Point(notScaledWidth, 0));
|
||||||
|
var actualPosition = $overlay.position();
|
||||||
|
Util.assessNumericValue(actualPosition.left, expectedPosition.x, epsilon,
|
||||||
|
"Not scaled overlay position.x should adjust to rotation.");
|
||||||
|
Util.assessNumericValue(actualPosition.top, expectedPosition.y, epsilon,
|
||||||
|
"Not scaled overlay position.y should adjust to rotation.");
|
||||||
|
|
||||||
|
var actualWidth = $overlay.width();
|
||||||
|
var actualHeight = $overlay.height();
|
||||||
|
Util.assessNumericValue(actualWidth, notScaledWidth, epsilon,
|
||||||
|
"Not scaled overlay width should not adjust to rotation.");
|
||||||
|
Util.assessNumericValue(actualHeight, notScaledHeight, epsilon,
|
||||||
|
"Not scaled overlay height should not adjust to rotation.");
|
||||||
|
|
||||||
|
var actualBounds = viewer.getOverlayById("not-scaled-overlay")
|
||||||
|
.getBounds(viewport);
|
||||||
|
var expectedBounds = new OpenSeadragon.Rect(
|
||||||
|
1 - notScaledSize.x, 0, notScaledSize.x, notScaledSize.y)
|
||||||
|
.rotate(-45, new OpenSeadragon.Point(1, 0));
|
||||||
|
ok(expectedBounds.equals(actualBounds),
|
||||||
|
"Not scaled overlay should have bounds " +
|
||||||
|
expectedBounds.toString() + " but found " + actualBounds);
|
||||||
|
|
||||||
|
start();
|
||||||
|
});
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user