mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-22 05:06:09 +03:00
commit
c3c91ed612
@ -5,7 +5,9 @@ auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8
|
|||||||
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80
|
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80
|
||||||
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap=none
|
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap=none
|
||||||
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=project
|
auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=project
|
||||||
|
auxiliary.org-netbeans-modules-editor-indent.text.javascript.CodeStyle.project.continuationIndentSize=4
|
||||||
auxiliary.org-netbeans-modules-editor-indent.text.javascript.CodeStyle.project.indent-shift-width=4
|
auxiliary.org-netbeans-modules-editor-indent.text.javascript.CodeStyle.project.indent-shift-width=4
|
||||||
|
auxiliary.org-netbeans-modules-editor-indent.text.javascript.CodeStyle.project.spaceBeforeAnonMethodDeclParen=false
|
||||||
auxiliary.org-netbeans-modules-editor-indent.text.x-json.CodeStyle.project.indent-shift-width=2
|
auxiliary.org-netbeans-modules-editor-indent.text.x-json.CodeStyle.project.indent-shift-width=2
|
||||||
auxiliary.org-netbeans-modules-editor-indent.text.x-json.CodeStyle.project.spaces-per-tab=2
|
auxiliary.org-netbeans-modules-editor-indent.text.x-json.CodeStyle.project.spaces-per-tab=2
|
||||||
auxiliary.org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder=src
|
auxiliary.org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder=src
|
||||||
|
246
src/rectangle.js
246
src/rectangle.js
@ -32,46 +32,82 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function( $ ){
|
(function($) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Rect
|
* @class Rect
|
||||||
* @classdesc A Rectangle really represents a 2x2 matrix where each row represents a
|
* @classdesc A Rectangle is described by it top left coordinates (x, y), width,
|
||||||
* 2 dimensional vector component, the first is (x,y) and the second is
|
* height and degrees of rotation around (x, y).
|
||||||
* (width, height). The latter component implies the equation of a simple
|
* Note that the coordinate system used is the one commonly used with images:
|
||||||
* plane.
|
* x increases when going to the right
|
||||||
|
* y increases when going to the bottom
|
||||||
|
* degrees increases clockwise with 0 being the horizontal
|
||||||
|
*
|
||||||
|
* The constructor normalizes the rectangle to always have 0 <= degrees < 90
|
||||||
*
|
*
|
||||||
* @memberof OpenSeadragon
|
* @memberof OpenSeadragon
|
||||||
* @param {Number} x The vector component 'x'.
|
* @param {Number} [x=0] The vector component 'x'.
|
||||||
* @param {Number} y The vector component 'y'.
|
* @param {Number} [y=0] The vector component 'y'.
|
||||||
* @param {Number} width The vector component 'height'.
|
* @param {Number} [width=0] The vector component 'width'.
|
||||||
* @param {Number} height The vector component 'width'.
|
* @param {Number} [height=0] The vector component 'height'.
|
||||||
|
* @param {Number} [degrees=0] Rotation of the rectangle around (x,y) in degrees.
|
||||||
*/
|
*/
|
||||||
$.Rect = function( x, y, width, height ) {
|
$.Rect = function(x, y, width, height, degrees) {
|
||||||
/**
|
/**
|
||||||
* The vector component 'x'.
|
* The vector component 'x'.
|
||||||
* @member {Number} x
|
* @member {Number} x
|
||||||
* @memberof OpenSeadragon.Rect#
|
* @memberof OpenSeadragon.Rect#
|
||||||
*/
|
*/
|
||||||
this.x = typeof ( x ) == "number" ? x : 0;
|
this.x = typeof(x) === "number" ? x : 0;
|
||||||
/**
|
/**
|
||||||
* The vector component 'y'.
|
* The vector component 'y'.
|
||||||
* @member {Number} y
|
* @member {Number} y
|
||||||
* @memberof OpenSeadragon.Rect#
|
* @memberof OpenSeadragon.Rect#
|
||||||
*/
|
*/
|
||||||
this.y = typeof ( y ) == "number" ? y : 0;
|
this.y = typeof(y) === "number" ? y : 0;
|
||||||
/**
|
/**
|
||||||
* The vector component 'width'.
|
* The vector component 'width'.
|
||||||
* @member {Number} width
|
* @member {Number} width
|
||||||
* @memberof OpenSeadragon.Rect#
|
* @memberof OpenSeadragon.Rect#
|
||||||
*/
|
*/
|
||||||
this.width = typeof ( width ) == "number" ? width : 0;
|
this.width = typeof(width) === "number" ? width : 0;
|
||||||
/**
|
/**
|
||||||
* The vector component 'height'.
|
* The vector component 'height'.
|
||||||
* @member {Number} height
|
* @member {Number} height
|
||||||
* @memberof OpenSeadragon.Rect#
|
* @memberof OpenSeadragon.Rect#
|
||||||
*/
|
*/
|
||||||
this.height = typeof ( height ) == "number" ? height : 0;
|
this.height = typeof(height) === "number" ? height : 0;
|
||||||
|
|
||||||
|
this.degrees = typeof(degrees) === "number" ? degrees : 0;
|
||||||
|
|
||||||
|
// Normalizes the rectangle.
|
||||||
|
this.degrees = this.degrees % 360;
|
||||||
|
if (this.degrees < 0) {
|
||||||
|
this.degrees += 360;
|
||||||
|
}
|
||||||
|
var newTopLeft, newWidth;
|
||||||
|
if (this.degrees >= 270) {
|
||||||
|
newTopLeft = this.getTopRight();
|
||||||
|
this.x = newTopLeft.x;
|
||||||
|
this.y = newTopLeft.y;
|
||||||
|
newWidth = this.height;
|
||||||
|
this.height = this.width;
|
||||||
|
this.width = newWidth;
|
||||||
|
this.degrees -= 270;
|
||||||
|
} else if (this.degrees >= 180) {
|
||||||
|
newTopLeft = this.getBottomRight();
|
||||||
|
this.x = newTopLeft.x;
|
||||||
|
this.y = newTopLeft.y;
|
||||||
|
this.degrees -= 180;
|
||||||
|
} else if (this.degrees >= 90) {
|
||||||
|
newTopLeft = this.getBottomLeft();
|
||||||
|
this.x = newTopLeft.x;
|
||||||
|
this.y = newTopLeft.y;
|
||||||
|
newWidth = this.height;
|
||||||
|
this.height = this.width;
|
||||||
|
this.width = newWidth;
|
||||||
|
this.degrees -= 90;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
$.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
||||||
@ -80,7 +116,12 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
|||||||
* @returns {OpenSeadragon.Rect} a duplicate of this Rect
|
* @returns {OpenSeadragon.Rect} a duplicate of this Rect
|
||||||
*/
|
*/
|
||||||
clone: function() {
|
clone: function() {
|
||||||
return new $.Rect(this.x, this.y, this.width, this.height);
|
return new $.Rect(
|
||||||
|
this.x,
|
||||||
|
this.y,
|
||||||
|
this.width,
|
||||||
|
this.height,
|
||||||
|
this.degrees);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,10 +155,8 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
|||||||
* the rectangle.
|
* the rectangle.
|
||||||
*/
|
*/
|
||||||
getBottomRight: function() {
|
getBottomRight: function() {
|
||||||
return new $.Point(
|
return new $.Point(this.x + this.width, this.y + this.height)
|
||||||
this.x + this.width,
|
.rotate(this.degrees, this.getTopLeft());
|
||||||
this.y + this.height
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,10 +167,8 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
|||||||
* the rectangle.
|
* the rectangle.
|
||||||
*/
|
*/
|
||||||
getTopRight: function() {
|
getTopRight: function() {
|
||||||
return new $.Point(
|
return new $.Point(this.x + this.width, this.y)
|
||||||
this.x + this.width,
|
.rotate(this.degrees, this.getTopLeft());
|
||||||
this.y
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -142,10 +179,8 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
|||||||
* the rectangle.
|
* the rectangle.
|
||||||
*/
|
*/
|
||||||
getBottomLeft: function() {
|
getBottomLeft: function() {
|
||||||
return new $.Point(
|
return new $.Point(this.x, this.y + this.height)
|
||||||
this.x,
|
.rotate(this.degrees, this.getTopLeft());
|
||||||
this.y + this.height
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -158,7 +193,7 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
|||||||
return new $.Point(
|
return new $.Point(
|
||||||
this.x + this.width / 2.0,
|
this.x + this.width / 2.0,
|
||||||
this.y + this.height / 2.0
|
this.y + this.height / 2.0
|
||||||
);
|
).rotate(this.degrees, this.getTopLeft());
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,7 +203,7 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
|||||||
* the width and height of the rectangle.
|
* the width and height of the rectangle.
|
||||||
*/
|
*/
|
||||||
getSize: function() {
|
getSize: function() {
|
||||||
return new $.Point( this.width, this.height );
|
return new $.Point(this.width, this.height);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -177,28 +212,30 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
|||||||
* @param {OpenSeadragon.Rect} rectangle The Rectangle to compare to.
|
* @param {OpenSeadragon.Rect} rectangle The Rectangle to compare to.
|
||||||
* @return {Boolean} 'true' if all components are equal, otherwise 'false'.
|
* @return {Boolean} 'true' if all components are equal, otherwise 'false'.
|
||||||
*/
|
*/
|
||||||
equals: function( other ) {
|
equals: function(other) {
|
||||||
return ( other instanceof $.Rect ) &&
|
return (other instanceof $.Rect) &&
|
||||||
( this.x === other.x ) &&
|
this.x === other.x &&
|
||||||
( this.y === other.y ) &&
|
this.y === other.y &&
|
||||||
( this.width === other.width ) &&
|
this.width === other.width &&
|
||||||
( this.height === other.height );
|
this.height === other.height &&
|
||||||
|
this.degrees === other.degrees;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multiply all dimensions in this Rect by a factor and return a new Rect.
|
* Multiply all dimensions (except degrees) in this Rect by a factor and
|
||||||
|
* return a new Rect.
|
||||||
* @function
|
* @function
|
||||||
* @param {Number} factor The factor to multiply vector components.
|
* @param {Number} factor The factor to multiply vector components.
|
||||||
* @returns {OpenSeadragon.Rect} A new rect representing the multiplication
|
* @returns {OpenSeadragon.Rect} A new rect representing the multiplication
|
||||||
* of the vector components by the factor
|
* of the vector components by the factor
|
||||||
*/
|
*/
|
||||||
times: function( factor ) {
|
times: function(factor) {
|
||||||
return new OpenSeadragon.Rect(
|
return new $.Rect(
|
||||||
this.x * factor,
|
this.x * factor,
|
||||||
this.y * factor,
|
this.y * factor,
|
||||||
this.width * factor,
|
this.width * factor,
|
||||||
this.height * factor
|
this.height * factor,
|
||||||
);
|
this.degrees);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -207,83 +244,99 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
|||||||
* @param {OpenSeadragon.Point} delta The translation vector.
|
* @param {OpenSeadragon.Point} delta The translation vector.
|
||||||
* @returns {OpenSeadragon.Rect} A new rect with altered position
|
* @returns {OpenSeadragon.Rect} A new rect with altered position
|
||||||
*/
|
*/
|
||||||
translate: function( delta ) {
|
translate: function(delta) {
|
||||||
return new OpenSeadragon.Rect(
|
return new $.Rect(
|
||||||
this.x + delta.x,
|
this.x + delta.x,
|
||||||
this.y + delta.y,
|
this.y + delta.y,
|
||||||
this.width,
|
this.width,
|
||||||
this.height
|
this.height,
|
||||||
);
|
this.degrees);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the smallest rectangle that will contain this and the given rectangle.
|
* Returns the smallest rectangle that will contain this and the given
|
||||||
|
* rectangle bounding boxes.
|
||||||
* @param {OpenSeadragon.Rect} rect
|
* @param {OpenSeadragon.Rect} rect
|
||||||
* @return {OpenSeadragon.Rect} The new rectangle.
|
* @return {OpenSeadragon.Rect} The new rectangle.
|
||||||
*/
|
*/
|
||||||
// ----------
|
|
||||||
union: function(rect) {
|
union: function(rect) {
|
||||||
var left = Math.min(this.x, rect.x);
|
var thisBoundingBox = this.getBoundingBox();
|
||||||
var top = Math.min(this.y, rect.y);
|
var otherBoundingBox = rect.getBoundingBox();
|
||||||
var right = Math.max(this.x + this.width, rect.x + rect.width);
|
|
||||||
var bottom = Math.max(this.y + this.height, rect.y + rect.height);
|
|
||||||
|
|
||||||
return new OpenSeadragon.Rect(left, top, right - left, bottom - top);
|
var left = Math.min(thisBoundingBox.x, otherBoundingBox.x);
|
||||||
|
var top = Math.min(thisBoundingBox.y, otherBoundingBox.y);
|
||||||
|
var right = Math.max(
|
||||||
|
thisBoundingBox.x + thisBoundingBox.width,
|
||||||
|
otherBoundingBox.x + otherBoundingBox.width);
|
||||||
|
var bottom = Math.max(
|
||||||
|
thisBoundingBox.y + thisBoundingBox.height,
|
||||||
|
otherBoundingBox.y + otherBoundingBox.height);
|
||||||
|
|
||||||
|
return new $.Rect(
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
right - left,
|
||||||
|
bottom - top);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotates a rectangle around a point. Currently only 90, 180, and 270
|
* Rotates a rectangle around a point.
|
||||||
* degrees are supported.
|
|
||||||
* @function
|
* @function
|
||||||
* @param {Number} degrees The angle in degrees to rotate.
|
* @param {Number} degrees The angle in degrees to rotate.
|
||||||
* @param {OpenSeadragon.Point} pivot The point about which to rotate.
|
* @param {OpenSeadragon.Point} pivot The point about which to rotate.
|
||||||
* Defaults to the center of the rectangle.
|
* Defaults to the center of the rectangle.
|
||||||
* @return {OpenSeadragon.Rect}
|
* @return {OpenSeadragon.Rect}
|
||||||
*/
|
*/
|
||||||
rotate: function( degrees, pivot ) {
|
rotate: function(degrees, pivot) {
|
||||||
// TODO support arbitrary rotation
|
degrees = degrees % 360;
|
||||||
var width = this.width,
|
if (degrees === 0) {
|
||||||
height = this.height,
|
return this.clone();
|
||||||
newTopLeft;
|
|
||||||
|
|
||||||
degrees = ( degrees + 360 ) % 360;
|
|
||||||
if (degrees % 90 !== 0) {
|
|
||||||
throw new Error('Currently only 0, 90, 180, and 270 degrees are supported.');
|
|
||||||
}
|
}
|
||||||
|
if (degrees < 0) {
|
||||||
if( degrees === 0 ){
|
degrees += 360;
|
||||||
return new $.Rect(
|
|
||||||
this.x,
|
|
||||||
this.y,
|
|
||||||
this.width,
|
|
||||||
this.height
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pivot = pivot || this.getCenter();
|
pivot = pivot || this.getCenter();
|
||||||
|
var newTopLeft = this.getTopLeft().rotate(degrees, pivot);
|
||||||
|
var newTopRight = this.getTopRight().rotate(degrees, pivot);
|
||||||
|
|
||||||
switch ( degrees ) {
|
var diff = newTopRight.minus(newTopLeft);
|
||||||
case 90:
|
var radians = Math.atan(diff.y / diff.x);
|
||||||
newTopLeft = this.getBottomLeft();
|
if (diff.x < 0) {
|
||||||
width = this.height;
|
radians += Math.PI;
|
||||||
height = this.width;
|
} else if (diff.y < 0) {
|
||||||
break;
|
radians += 2 * Math.PI;
|
||||||
case 180:
|
|
||||||
newTopLeft = this.getBottomRight();
|
|
||||||
break;
|
|
||||||
case 270:
|
|
||||||
newTopLeft = this.getTopRight();
|
|
||||||
width = this.height;
|
|
||||||
height = this.width;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
newTopLeft = this.getTopLeft();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return new $.Rect(
|
||||||
|
newTopLeft.x,
|
||||||
|
newTopLeft.y,
|
||||||
|
this.width,
|
||||||
|
this.height,
|
||||||
|
radians / Math.PI * 180);
|
||||||
|
},
|
||||||
|
|
||||||
newTopLeft = newTopLeft.rotate(degrees, pivot);
|
/**
|
||||||
|
* Retrieves the smallest horizontal (degrees=0) rectangle which contains
|
||||||
return new $.Rect(newTopLeft.x, newTopLeft.y, width, height);
|
* this rectangle.
|
||||||
|
* @returns {OpenSeadrayon.Rect}
|
||||||
|
*/
|
||||||
|
getBoundingBox: function() {
|
||||||
|
if (this.degrees === 0) {
|
||||||
|
return this.clone();
|
||||||
|
}
|
||||||
|
var topLeft = this.getTopLeft();
|
||||||
|
var topRight = this.getTopRight();
|
||||||
|
var bottomLeft = this.getBottomLeft();
|
||||||
|
var bottomRight = this.getBottomRight();
|
||||||
|
var minX = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
|
||||||
|
var maxX = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
|
||||||
|
var minY = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
|
||||||
|
var maxY = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
|
||||||
|
return new $.Rect(
|
||||||
|
minX,
|
||||||
|
minY,
|
||||||
|
maxX - minX,
|
||||||
|
maxY - minY);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -294,13 +347,14 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{
|
|||||||
*/
|
*/
|
||||||
toString: function() {
|
toString: function() {
|
||||||
return "[" +
|
return "[" +
|
||||||
(Math.round(this.x*100) / 100) + "," +
|
(Math.round(this.x * 100) / 100) + "," +
|
||||||
(Math.round(this.y*100) / 100) + "," +
|
(Math.round(this.y * 100) / 100) + "," +
|
||||||
(Math.round(this.width*100) / 100) + "x" +
|
(Math.round(this.width * 100) / 100) + "x" +
|
||||||
(Math.round(this.height*100) / 100) +
|
(Math.round(this.height * 100) / 100) + "," +
|
||||||
"]";
|
(Math.round(this.degrees * 100) / 100) + "°" +
|
||||||
|
"]";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}( OpenSeadragon ));
|
}(OpenSeadragon));
|
||||||
|
@ -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.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");
|
$.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.contentSize = this.homeBounds.getSize().times(contentFactor);
|
||||||
this.contentAspectX = this.contentSize.x / this.contentSize.y;
|
this.contentAspectX = this.contentSize.x / this.contentSize.y;
|
||||||
this.contentAspectY = this.contentSize.y / this.contentSize.x;
|
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
|
* Raised when the viewer's content size or home bounds are reset
|
||||||
* (see {@link OpenSeadragon.Viewport#resetContentSize},
|
* (see {@link OpenSeadragon.Viewport#resetContentSize},
|
||||||
@ -195,7 +195,7 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
|
|||||||
* @property {Number} contentFactor
|
* @property {Number} contentFactor
|
||||||
* @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.contentSize.clone(),
|
||||||
contentFactor: contentFactor,
|
contentFactor: contentFactor,
|
||||||
homeBounds: this.homeBounds.clone()
|
homeBounds: this.homeBounds.clone()
|
||||||
@ -807,13 +807,19 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
|
|||||||
* @function
|
* @function
|
||||||
* @return {OpenSeadragon.Viewport} Chainable.
|
* @return {OpenSeadragon.Viewport} Chainable.
|
||||||
*/
|
*/
|
||||||
setRotation: function( degrees ) {
|
setRotation: function(degrees) {
|
||||||
if( !( this.viewer && this.viewer.drawer.canRotate() ) ) {
|
if (!this.viewer || !this.viewer.drawer.canRotate()) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
degrees = ( degrees + 360 ) % 360;
|
degrees = degrees % 360;
|
||||||
|
if (degrees < 0) {
|
||||||
|
degrees += 360;
|
||||||
|
}
|
||||||
this.degrees = degrees;
|
this.degrees = degrees;
|
||||||
|
this.setHomeBounds(
|
||||||
|
this.viewer.world.getHomeBounds(),
|
||||||
|
this.viewer.world.getContentFactor());
|
||||||
this.viewer.forceRedraw();
|
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 {Number} degrees - The number of degrees the rotation was set to.
|
||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
* @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;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
<script src="/test/modules/tilesource.js"></script>
|
<script src="/test/modules/tilesource.js"></script>
|
||||||
<script src="/test/modules/tilesourcecollection.js"></script>
|
<script src="/test/modules/tilesourcecollection.js"></script>
|
||||||
<script src="/test/modules/spring.js"></script>
|
<script src="/test/modules/spring.js"></script>
|
||||||
|
<script src="/test/modules/rectangle.js"></script>
|
||||||
<!-- The navigator tests are the slowest (for now; hopefully they can be sped up)
|
<!-- The navigator tests are the slowest (for now; hopefully they can be sped up)
|
||||||
so we put them last. -->
|
so we put them last. -->
|
||||||
<script src="/test/modules/navigator.js"></script>
|
<script src="/test/modules/navigator.js"></script>
|
||||||
|
@ -68,6 +68,24 @@
|
|||||||
ok( Util.equalsWithVariance( value1, value2, variance ), message + " Expected:" + value1 + " Found: " + value2 + " Variance: " + variance );
|
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 ) {
|
timeWatcher: function ( time ) {
|
||||||
time = time || 2000;
|
time = time || 2000;
|
||||||
|
221
test/modules/rectangle.js
Normal file
221
test/modules/rectangle.js
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
module('Rectangle', {});
|
||||||
|
|
||||||
|
var precision = 0.000000001;
|
||||||
|
|
||||||
|
test('Constructor', function() {
|
||||||
|
var rect = new OpenSeadragon.Rect(1, 2, 3, 4, 5);
|
||||||
|
strictEqual(rect.x, 1, 'rect.x should be 1');
|
||||||
|
strictEqual(rect.y, 2, 'rect.y should be 2');
|
||||||
|
strictEqual(rect.width, 3, 'rect.width should be 3');
|
||||||
|
strictEqual(rect.height, 4, 'rect.height should be 4');
|
||||||
|
strictEqual(rect.degrees, 5, 'rect.degrees should be 5');
|
||||||
|
|
||||||
|
rect = new OpenSeadragon.Rect();
|
||||||
|
strictEqual(rect.x, 0, 'rect.x should be 0');
|
||||||
|
strictEqual(rect.y, 0, 'rect.y should be 0');
|
||||||
|
strictEqual(rect.width, 0, 'rect.width should be 0');
|
||||||
|
strictEqual(rect.height, 0, 'rect.height should be 0');
|
||||||
|
strictEqual(rect.degrees, 0, 'rect.degrees should be 0');
|
||||||
|
|
||||||
|
rect = new OpenSeadragon.Rect(0, 0, 1, 2, -405);
|
||||||
|
Util.assessNumericValue(Math.sqrt(2) / 2, rect.x, precision,
|
||||||
|
'rect.x should be sqrt(2)/2');
|
||||||
|
Util.assessNumericValue(-Math.sqrt(2) / 2, rect.y, precision,
|
||||||
|
'rect.y should be -sqrt(2)/2');
|
||||||
|
Util.assessNumericValue(2, rect.width, precision,
|
||||||
|
'rect.width should be 2');
|
||||||
|
Util.assessNumericValue(1, rect.height, precision,
|
||||||
|
'rect.height should be 1');
|
||||||
|
strictEqual(45, rect.degrees, 'rect.degrees should be 45');
|
||||||
|
|
||||||
|
rect = new OpenSeadragon.Rect(0, 0, 1, 2, 135);
|
||||||
|
Util.assessNumericValue(-Math.sqrt(2), rect.x, precision,
|
||||||
|
'rect.x should be -sqrt(2)');
|
||||||
|
Util.assessNumericValue(-Math.sqrt(2), rect.y, precision,
|
||||||
|
'rect.y should be -sqrt(2)');
|
||||||
|
Util.assessNumericValue(2, rect.width, precision,
|
||||||
|
'rect.width should be 2');
|
||||||
|
Util.assessNumericValue(1, rect.height, precision,
|
||||||
|
'rect.height should be 1');
|
||||||
|
strictEqual(45, rect.degrees, 'rect.degrees should be 45');
|
||||||
|
|
||||||
|
rect = new OpenSeadragon.Rect(0, 0, 1, 1, 585);
|
||||||
|
Util.assessNumericValue(0, rect.x, precision,
|
||||||
|
'rect.x should be 0');
|
||||||
|
Util.assessNumericValue(-Math.sqrt(2), rect.y, precision,
|
||||||
|
'rect.y should be -sqrt(2)');
|
||||||
|
Util.assessNumericValue(1, rect.width, precision,
|
||||||
|
'rect.width should be 1');
|
||||||
|
Util.assessNumericValue(1, rect.height, precision,
|
||||||
|
'rect.height should be 1');
|
||||||
|
strictEqual(45, rect.degrees, 'rect.degrees should be 45');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getTopLeft', function() {
|
||||||
|
var rect = new OpenSeadragon.Rect(1, 2, 3, 4, 5);
|
||||||
|
var expected = new OpenSeadragon.Point(1, 2);
|
||||||
|
ok(expected.equals(rect.getTopLeft()), "Incorrect top left point.");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getTopRight', function() {
|
||||||
|
var rect = new OpenSeadragon.Rect(0, 0, 1, 3);
|
||||||
|
var expected = new OpenSeadragon.Point(1, 0);
|
||||||
|
ok(expected.equals(rect.getTopRight()), "Incorrect top right point.");
|
||||||
|
|
||||||
|
rect.degrees = 45;
|
||||||
|
expected = new OpenSeadragon.Point(1 / Math.sqrt(2), 1 / Math.sqrt(2));
|
||||||
|
Util.assertPointsEquals(expected, rect.getTopRight(), precision,
|
||||||
|
"Incorrect top right point with rotation.");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getBottomLeft', function() {
|
||||||
|
var rect = new OpenSeadragon.Rect(0, 0, 3, 1);
|
||||||
|
var expected = new OpenSeadragon.Point(0, 1);
|
||||||
|
ok(expected.equals(rect.getBottomLeft()), "Incorrect bottom left point.");
|
||||||
|
|
||||||
|
rect.degrees = 45;
|
||||||
|
expected = new OpenSeadragon.Point(-1 / Math.sqrt(2), 1 / Math.sqrt(2));
|
||||||
|
Util.assertPointsEquals(expected, rect.getBottomLeft(), precision,
|
||||||
|
"Incorrect bottom left point with rotation.");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getBottomRight', function() {
|
||||||
|
var rect = new OpenSeadragon.Rect(0, 0, 1, 1);
|
||||||
|
var expected = new OpenSeadragon.Point(1, 1);
|
||||||
|
ok(expected.equals(rect.getBottomRight()), "Incorrect bottom right point.");
|
||||||
|
|
||||||
|
rect.degrees = 45;
|
||||||
|
expected = new OpenSeadragon.Point(0, Math.sqrt(2));
|
||||||
|
Util.assertPointsEquals(expected, rect.getBottomRight(), precision,
|
||||||
|
"Incorrect bottom right point with 45 rotation.");
|
||||||
|
|
||||||
|
rect.degrees = 90;
|
||||||
|
expected = new OpenSeadragon.Point(-1, 1);
|
||||||
|
Util.assertPointsEquals(expected, rect.getBottomRight(), precision,
|
||||||
|
"Incorrect bottom right point with 90 rotation.");
|
||||||
|
|
||||||
|
rect.degrees = 135;
|
||||||
|
expected = new OpenSeadragon.Point(-Math.sqrt(2), 0);
|
||||||
|
Util.assertPointsEquals(expected, rect.getBottomRight(), precision,
|
||||||
|
"Incorrect bottom right point with 135 rotation.");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getCenter', function() {
|
||||||
|
var rect = new OpenSeadragon.Rect(0, 0, 1, 1);
|
||||||
|
var expected = new OpenSeadragon.Point(0.5, 0.5);
|
||||||
|
ok(expected.equals(rect.getCenter()), "Incorrect center point.");
|
||||||
|
|
||||||
|
rect.degrees = 45;
|
||||||
|
expected = new OpenSeadragon.Point(0, 0.5 * Math.sqrt(2));
|
||||||
|
Util.assertPointsEquals(expected, rect.getCenter(), precision,
|
||||||
|
"Incorrect bottom right point with 45 rotation.");
|
||||||
|
|
||||||
|
rect.degrees = 90;
|
||||||
|
expected = new OpenSeadragon.Point(-0.5, 0.5);
|
||||||
|
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);
|
||||||
|
Util.assertPointsEquals(expected, rect.getCenter(), precision,
|
||||||
|
"Incorrect bottom right point with 135 rotation.");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('times', function() {
|
||||||
|
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);
|
||||||
|
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));
|
||||||
|
Util.assertRectangleEquals(expected, actual, precision,
|
||||||
|
"Incorrect translation.");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('union', function() {
|
||||||
|
var rect1 = new OpenSeadragon.Rect(2, 2, 2, 3);
|
||||||
|
var rect2 = new OpenSeadragon.Rect(0, 1, 1, 1);
|
||||||
|
var expected = new OpenSeadragon.Rect(0, 1, 4, 4);
|
||||||
|
var actual = rect1.union(rect2);
|
||||||
|
Util.assertRectangleEquals(expected, actual, precision,
|
||||||
|
"Incorrect union with horizontal rectangles.");
|
||||||
|
|
||||||
|
rect1 = new OpenSeadragon.Rect(0, -Math.sqrt(2), 2, 2, 45);
|
||||||
|
rect2 = new OpenSeadragon.Rect(1, 0, 2, 2, 0);
|
||||||
|
expected = new OpenSeadragon.Rect(
|
||||||
|
-Math.sqrt(2),
|
||||||
|
-Math.sqrt(2),
|
||||||
|
3 + Math.sqrt(2),
|
||||||
|
2 + Math.sqrt(2));
|
||||||
|
actual = rect1.union(rect2);
|
||||||
|
Util.assertRectangleEquals(expected, actual, precision,
|
||||||
|
"Incorrect union with non horizontal rectangles.");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('rotate', function() {
|
||||||
|
var rect = new OpenSeadragon.Rect(0, 0, 2, 1);
|
||||||
|
|
||||||
|
var expected = new OpenSeadragon.Rect(
|
||||||
|
1 - 1 / (2 * Math.sqrt(2)),
|
||||||
|
0.5 - 3 / (2 * Math.sqrt(2)),
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
45);
|
||||||
|
var actual = rect.rotate(-675);
|
||||||
|
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());
|
||||||
|
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());
|
||||||
|
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());
|
||||||
|
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());
|
||||||
|
Util.assertRectangleEquals(expected, actual, precision,
|
||||||
|
"Incorrect rectangle after rotation of 300deg around topLeft.");
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getBoundingBox', function() {
|
||||||
|
var rect = new OpenSeadragon.Rect(0, 0, 2, 3);
|
||||||
|
|
||||||
|
var bb = rect.getBoundingBox();
|
||||||
|
ok(rect.equals(bb), "Bounding box of horizontal rectangle should be " +
|
||||||
|
"identical to rectangle.");
|
||||||
|
|
||||||
|
rect.degrees = 90;
|
||||||
|
var expected = new OpenSeadragon.Rect(-3, 0, 3, 2);
|
||||||
|
Util.assertRectangleEquals(expected, rect.getBoundingBox(), precision,
|
||||||
|
"Bounding box of rect rotated 90deg.");
|
||||||
|
|
||||||
|
rect.degrees = 180;
|
||||||
|
var expected = new OpenSeadragon.Rect(-2, -3, 2, 3);
|
||||||
|
Util.assertRectangleEquals(expected, rect.getBoundingBox(), precision,
|
||||||
|
"Bounding box of rect rotated 180deg.");
|
||||||
|
|
||||||
|
rect.degrees = 270;
|
||||||
|
var expected = new OpenSeadragon.Rect(0, -2, 3, 2);
|
||||||
|
Util.assertRectangleEquals(expected, rect.getBoundingBox(), precision,
|
||||||
|
"Bounding box of rect rotated 270deg.");
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
@ -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() {
|
asyncTest('getHomeZoom', function() {
|
||||||
reopenViewerHelper({
|
reopenViewerHelper({
|
||||||
property: 'defaultZoomLevel',
|
property: 'defaultZoomLevel',
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
<script src="/test/modules/tilesource.js"></script>
|
<script src="/test/modules/tilesource.js"></script>
|
||||||
<script src="/test/modules/tilesourcecollection.js"></script>
|
<script src="/test/modules/tilesourcecollection.js"></script>
|
||||||
<script src="/test/modules/spring.js"></script>
|
<script src="/test/modules/spring.js"></script>
|
||||||
|
<script src="/test/modules/rectangle.js"></script>
|
||||||
<!-- The navigator tests are the slowest (for now; hopefully they can be sped up)
|
<!-- The navigator tests are the slowest (for now; hopefully they can be sped up)
|
||||||
so we put them last. -->
|
so we put them last. -->
|
||||||
<script src="/test/modules/navigator.js"></script>
|
<script src="/test/modules/navigator.js"></script>
|
||||||
|
Loading…
Reference in New Issue
Block a user