diff --git a/src/rectangle.js b/src/rectangle.js index 4e3746eb..4507eb08 100644 --- a/src/rectangle.js +++ b/src/rectangle.js @@ -178,6 +178,22 @@ $.Rect.prototype = /** @lends OpenSeadragon.Rect.prototype */{ ( this.height === other.height ); }, + /** + * Multiply all dimensions in this Rect by a factor and return a new Rect. + * @function + * @param {Number} factor The factor to multiply vector components. + * @returns {OpenSeadragon.Rect} A new rect representing the multiplication + * of the vector components by the factor + */ + times: function( factor ) { + return new OpenSeadragon.Rect( + this.x * factor, + this.y * factor, + this.width * factor, + this.height * factor + ); + }, + /** * Rotates a rectangle around a point. Currently only 90, 180, and 270 * degrees are supported. diff --git a/test/test.html b/test/test.html index 592847bd..b837d733 100644 --- a/test/test.html +++ b/test/test.html @@ -31,5 +31,6 @@ + diff --git a/test/viewport.js b/test/viewport.js new file mode 100644 index 00000000..2daabc68 --- /dev/null +++ b/test/viewport.js @@ -0,0 +1,285 @@ +/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */ + +(function () { + var viewer; + + module("viewport", { + setup: function () { + var example = $('
').appendTo("#qunit-fixture"); + + testLog.reset(); + + viewer = OpenSeadragon({ + id: 'example', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100 // Faster animation = faster tests + }); + }, + teardown: function () { + if (viewer && viewer.close) { + viewer.close(); + } + + viewer = null; + } + }); + + // helpers and constants + + var ZOOM_FACTOR = 2; // the image will be twice as large as the viewer. + var VIEWER_PADDING = new OpenSeadragon.Point(20, 20); + var DZI_PATH = '/test/data/testpattern.dzi' + + var testZoomLevels = [-1, 0, 0.1, 0.5, 4, 10]; + + var testPoints = [ + new OpenSeadragon.Point(0, 0), + new OpenSeadragon.Point(0.001, 0.001), + new OpenSeadragon.Point(0.25, 0.5), + new OpenSeadragon.Point(0.99, 0.99), + new OpenSeadragon.Point(1, 1) + ]; + + var testRects = [ + new OpenSeadragon.Rect(0, 0, 0, 0), + new OpenSeadragon.Rect(0.001, 0.005, 0.001, 0.003), + new OpenSeadragon.Rect(0.25, 0.25, 0.25, 0.25), + new OpenSeadragon.Rect(0.999, 0.999, 0.999, 0.999), + new OpenSeadragon.Rect(1, 1, 1, 1) + ]; + + // ---------- +/* + asyncTest('template', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + // do stuff here + var orig = ; + var expected = ; + var actual = ; + equal(expected, actual, "what are you testing"); + + start(); + }; + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); +*/ + asyncTest('imageToViewportRectangle', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + var orig, expected, actual; + for (var i = 0; i < testRects.length; i++){ + orig = testRects[i].times(viewer.source.dimensions.x); + expected = new OpenSeadragon.Rect( + orig.x / viewer.source.dimensions.x, + orig.y / viewer.source.dimensions.x, + orig.width / viewer.source.dimensions.x, + orig.height / viewer.source.dimensions.x + ); + actual = viewport.imageToViewportRectangle(orig); + propEqual(actual, expected, "Coordinates converted correctly for " + orig); + } + + start(); + }; + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + + asyncTest('viewportToImageRectangle', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + var orig, expected, actual; + for (var i = 0; i < testRects.length; i++){ + orig = testRects[i].times(viewport.getContainerSize().x); + expected = new OpenSeadragon.Rect( + orig.x * viewer.source.dimensions.x, + orig.y * viewer.source.dimensions.x, + orig.width * viewer.source.dimensions.x, + orig.height * viewer.source.dimensions.x + ); + actual = viewport.viewportToImageRectangle(orig); + propEqual(actual, expected, "Coordinates converted correctly for " + orig); + } + + start(); + }; + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + + asyncTest('viewerElementToImageCoordinates', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + var orig, expected, actual; + for (var i = 0; i < testPoints.length; i++){ + orig = testPoints[i].times(viewport.getContainerSize().x); + expected = orig.times(ZOOM_FACTOR); + actual = viewport.viewerElementToImageCoordinates(orig); + propEqual(actual, expected, "Coordinates converted correctly for " + orig); + } + + start(); + }; + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + + asyncTest('imageToViewerElementCoordinates', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + var orig, expected, actual; + for (var i = 0; i < testPoints.length; i++){ + orig = testPoints[i].times(viewer.source.dimensions.x); + expected = orig.divide(ZOOM_FACTOR); + actual = viewport.imageToViewerElementCoordinates(orig); + propEqual(actual, expected, "Coordinates converted correctly for " + orig); + } + + start(); + }; + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + + asyncTest('windowToImageCoordinates', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + var window_boundary = Math.min(window.innerWidth, window.innerHeight); + var orig, expected, actual; + for (var i = 0; i < testPoints.length; i++){ + orig = testPoints[i].times(window_boundary); + expected = orig.divide(viewport.getContainerSize().x).plus(VIEWER_PADDING); + actual = viewport.windowToViewportCoordinates(orig); + propEqual(actual, expected, "Coordinates converted correctly for " + orig); + } + + start(); + }; + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + + asyncTest('imageToWindowCoordinates', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + var orig, expected, actual; + for (var i = 0; i < testPoints.length; i++){ + orig = testPoints[i].times(viewer.source.dimensions.x); + position = viewer.element.getBoundingClientRect(); + expected = orig.divide(ZOOM_FACTOR).plus( new OpenSeadragon.Point(position.top, position.left) ); + actual = viewport.imageToWindowCoordinates(orig); + propEqual(actual, expected, "Coordinates converted correctly for " + orig); + } + + start(); + }; + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + + asyncTest('windowToViewportCoordinates', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + var window_boundary = Math.min(window.innerWidth, window.innerHeight); + var orig, expected, actual; + for (var i = 0; i < testPoints.length; i++){ + orig = testPoints[i].times(window_boundary); + expected = orig.divide(viewport.getContainerSize().x).plus(VIEWER_PADDING); + actual = viewport.windowToViewportCoordinates(orig); + propEqual(actual, expected, "Coordinates converted correctly for " + orig); + } + + start(); + }; + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + + asyncTest('viewportToWindowCoordinates', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + var orig, expected, actual; + for (var i = 0; i < testPoints.length; i++){ + orig = testPoints[i].times(viewer.source.dimensions.x); + expected = orig.minus(VIEWER_PADDING).times(viewport.getContainerSize().x); + actual = viewport.viewportToWindowCoordinates(orig); + propEqual(actual, expected, "Coordinates converted correctly for " + orig); + } + + start(); + }; + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + + asyncTest('viewportToImageZoom', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + var orig, expected, actual; + for (var i = 0; i < testPoints.length; i++){ + orig = testZoomLevels[i]; + expected = orig / ZOOM_FACTOR; + actual = viewport.viewportToImageZoom(orig); + equal(expected, actual, "Coordinates converted correctly for " + orig); + } + start(); + }; + + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + + asyncTest('imageToViewportZoom', function() { + var openHandler = function(event) { + viewer.removeHandler('open', openHandler); + var viewport = viewer.viewport; + viewport.zoomTo(ZOOM_FACTOR, null, true); + + + var orig, expected, actual; + for (var i = 0; i < testPoints.length; i++){ + orig = testZoomLevels[i]; + expected = orig * ZOOM_FACTOR; + actual = viewport.imageToViewportZoom(orig); + equal(expected, actual, "Coordinates converted correctly for " + orig); + } + start(); + }; + + viewer.addHandler('open', openHandler); + viewer.open(DZI_PATH); + }); + +})();