diff --git a/src/tiledimage.js b/src/tiledimage.js
index 0100e3cd..363df7c6 100644
--- a/src/tiledimage.js
+++ b/src/tiledimage.js
@@ -406,6 +406,83 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
);
},
+ /**
+ * Convert pixel coordinates relative to the viewer element to image
+ * coordinates.
+ * @param {OpenSeadragon.Point} pixel
+ * @returns {OpenSeadragon.Point}
+ */
+ viewerElementToImageCoordinates: function( pixel ) {
+ var point = this.viewport.pointFromPixel( pixel, true );
+ return this.viewportToImageCoordinates( point );
+ },
+
+ /**
+ * Convert pixel coordinates relative to the image to
+ * viewer element coordinates.
+ * @param {OpenSeadragon.Point} pixel
+ * @returns {OpenSeadragon.Point}
+ */
+ imageToViewerElementCoordinates: function( pixel ) {
+ var point = this.imageToViewportCoordinates( pixel );
+ return this.viewport.pixelFromPoint( point, true );
+ },
+
+ /**
+ * Convert pixel coordinates relative to the window to image coordinates.
+ * @param {OpenSeadragon.Point} pixel
+ * @returns {OpenSeadragon.Point}
+ */
+ windowToImageCoordinates: function( pixel ) {
+ var viewerCoordinates = pixel.minus(
+ OpenSeadragon.getElementPosition( this.viewer.element ));
+ return this.viewerElementToImageCoordinates( viewerCoordinates );
+ },
+
+ /**
+ * Convert image coordinates to pixel coordinates relative to the window.
+ * @param {OpenSeadragon.Point} pixel
+ * @returns {OpenSeadragon.Point}
+ */
+ imageToWindowCoordinates: function( pixel ) {
+ var viewerCoordinates = this.imageToViewerElementCoordinates( pixel );
+ return viewerCoordinates.plus(
+ OpenSeadragon.getElementPosition( this.viewer.element ));
+ },
+
+ /**
+ * Convert a viewport zoom to an image zoom.
+ * Image zoom: ratio of the original image size to displayed image size.
+ * 1 means original image size, 0.5 half size...
+ * Viewport zoom: ratio of the displayed image's width to viewport's width.
+ * 1 means identical width, 2 means image's width is twice the viewport's width...
+ * @function
+ * @param {Number} viewportZoom The viewport zoom
+ * @returns {Number} imageZoom The image zoom
+ */
+ viewportToImageZoom: function( viewportZoom ) {
+ var ratio = this._scaleSpring.current.value *
+ this.viewport._containerInnerSize.x / this.source.dimensions.x;
+ return ratio * viewportZoom ;
+ },
+
+ /**
+ * Convert an image zoom to a viewport zoom.
+ * Image zoom: ratio of the original image size to displayed image size.
+ * 1 means original image size, 0.5 half size...
+ * Viewport zoom: ratio of the displayed image's width to viewport's width.
+ * 1 means identical width, 2 means image's width is twice the viewport's width...
+ * Note: not accurate with multi-image.
+ * @function
+ * @param {Number} imageZoom The image zoom
+ * @returns {Number} viewportZoom The viewport zoom
+ */
+ imageToViewportZoom: function( imageZoom ) {
+ var ratio = this._scaleSpring.current.value *
+ this.viewport._containerInnerSize.x / this.source.dimensions.x;
+ return imageZoom / ratio;
+ },
+
/**
* Sets the TiledImage's position in the world.
* @param {OpenSeadragon.Point} position - The new position, in viewport coordinates.
diff --git a/test/demo/coordinates.html b/test/demo/coordinates.html
index c240120a..188e87ee 100644
--- a/test/demo/coordinates.html
+++ b/test/demo/coordinates.html
@@ -1,21 +1,21 @@
- OpenSeadragon Basic Demo
+ OpenSeadragon Coordinates Demo
- Simple demo page to show a default OpenSeadragon viewer.
+ Simple demo page to show OpenSeadragon coordinates system.
@@ -24,16 +24,26 @@
|
Window (pixel) |
Container (pixel) |
- Image (pixel) |
+ Image 1 - top left (pixel) |
+ Image 2 - bottom right (pixel) |
Viewport (point) |
Cursor position |
|
|
- |
+ |
+ |
|
+
+ Zoom |
+ - |
+ - |
+ |
+ |
+ |
+
diff --git a/test/modules/units.js b/test/modules/units.js
index b1d10d5c..eada67b8 100644
--- a/test/modules/units.js
+++ b/test/modules/units.js
@@ -1,6 +1,6 @@
/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */
-(function() {
+(function () {
var viewer;
module('Units', {
@@ -10,8 +10,8 @@
testLog.reset();
viewer = OpenSeadragon({
- id: 'unitsexample',
- prefixUrl: '/build/openseadragon/images/',
+ id: 'unitsexample',
+ prefixUrl: '/build/openseadragon/images/',
springStiffness: 100 // Faster animation = faster tests
});
},
@@ -30,38 +30,57 @@
Util.assessNumericValue(a.y, b.y, 0.00000001, message);
}
- // ----------
- asyncTest('Coordinates conversions', function() {
+ // Check that f^-1 ( f(x) ) = x
+ function checkPoint(context) {
+ var viewport = viewer.viewport;
- function checkPoint(context) {
- var viewport = viewer.viewport;
-
- var point = new OpenSeadragon.Point(15, 12);
- var result = viewport.viewerElementToImageCoordinates(
+ var point = new OpenSeadragon.Point(15, 12);
+ var result = viewport.viewerElementToImageCoordinates(
viewport.imageToViewerElementCoordinates(point));
- pointEqual(result, point, 'viewerElement and image ' + context);
+ pointEqual(result, point, 'viewerElement and image ' + context);
- var result = viewport.windowToImageCoordinates(
+ result = viewport.windowToImageCoordinates(
viewport.imageToWindowCoordinates(point));
- pointEqual(result, point, 'window and image ' + context);
+ pointEqual(result, point, 'window and image ' + context);
- var result = viewport.viewerElementToViewportCoordinates(
+ result = viewport.viewerElementToViewportCoordinates(
viewport.viewportToViewerElementCoordinates(point));
- pointEqual(result, point, 'viewerElement and viewport ' + context);
+ pointEqual(result, point, 'viewerElement and viewport ' + context);
- var result = viewport.windowToViewportCoordinates(
+ result = viewport.windowToViewportCoordinates(
viewport.viewportToWindowCoordinates(point));
- pointEqual(result, point, 'window and viewport ' + context);
+ pointEqual(result, point, 'window and viewport ' + context);
+
+ for (var i = 0; i < viewer.world.getItemCount(); i++) {
+ var tiledImage = viewer.world.getItemAt(i);
+ result = tiledImage.viewportToImageCoordinates(
+ tiledImage.imageToViewportCoordinates(point));
+ pointEqual(result, point, 'viewport and tiled image ' + i + context);
+
+ result = tiledImage.viewerElementToImageCoordinates(
+ tiledImage.imageToViewerElementCoordinates(point));
+ pointEqual(result, point, 'viewerElement and tiled image ' + i + context);
+
+ result = tiledImage.windowToImageCoordinates(
+ tiledImage.imageToWindowCoordinates(point));
+ pointEqual(result, point, 'window and tiled image ' + i + context);
}
+ }
+
+ // ----------
+ asyncTest('Single image coordinates conversions', function () {
viewer.addHandler("open", function () {
var viewport = viewer.viewport;
+ var tiledImage = viewer.world.getItemAt(0);
var point0_0 = new OpenSeadragon.Point(0, 0);
var point = viewport.viewerElementToViewportCoordinates(point0_0);
pointEqual(point, point0_0, 'When opening, viewer coordinate 0,0 is also point 0,0');
- var pixel = viewport.viewerElementToImageCoordinates(point0_0);
- pointEqual(pixel, point0_0, 'When opening, viewer coordinate 0,0 is also pixel 0,0');
+ var viewportPixel = viewport.viewerElementToImageCoordinates(point0_0);
+ pointEqual(viewportPixel, point0_0, 'When opening, viewer coordinate 0,0 is also viewport pixel 0,0');
+ var imagePixel = tiledImage.viewerElementToImageCoordinates(point0_0);
+ pointEqual(imagePixel, point0_0, 'When opening, viewer coordinate 0,0 is also image pixel 0,0');
var viewerWidth = $(viewer.element).width();
var imageWidth = viewer.source.dimensions.x;
@@ -69,15 +88,17 @@
var viewerTopRight = new OpenSeadragon.Point(viewerWidth, 0);
var imageTopRight = new OpenSeadragon.Point(imageWidth, 0);
- var point = viewport.viewerElementToViewportCoordinates(viewerTopRight);
+ point = viewport.viewerElementToViewportCoordinates(viewerTopRight);
pointEqual(point, point1_0, 'Viewer top right has viewport coordinates 1,0.');
- var pixel = viewport.viewerElementToImageCoordinates(viewerTopRight);
- pointEqual(pixel, imageTopRight, 'Viewer top right has viewport coordinates imageWidth,0.');
+ viewportPixel = viewport.viewerElementToImageCoordinates(viewerTopRight);
+ pointEqual(viewportPixel, imageTopRight, 'Viewer top right has viewport pixel coordinates imageWidth,0.');
+ imagePixel = tiledImage.viewerElementToImageCoordinates(viewerTopRight);
+ pointEqual(imagePixel, imageTopRight, 'Viewer top right has image pixel coordinates imageWidth,0.');
- checkPoint('after opening');
+ checkPoint(' after opening');
viewer.addHandler('animation-finish', function animationHandler() {
viewer.removeHandler('animation-finish', animationHandler);
- checkPoint('after zoom and pan');
+ checkPoint(' after zoom and pan');
start();
});
viewer.viewport.zoomTo(0.8).panTo(new OpenSeadragon.Point(0.1, 0.2));
@@ -85,19 +106,80 @@
viewer.open('/test/data/testpattern.dzi');
});
+
+ // ---------
+ asyncTest('Multiple images coordinates conversion', function () {
+
+ viewer.addHandler("open", function () {
+ var viewport = viewer.viewport;
+ var tiledImage1 = viewer.world.getItemAt(0);
+ var tiledImage2 = viewer.world.getItemAt(1);
+ var imageWidth = viewer.source.dimensions.x;
+ var imageHeight = viewer.source.dimensions.y;
+
+ var point0_0 = new OpenSeadragon.Point(0, 0);
+ var point = viewport.viewerElementToViewportCoordinates(point0_0);
+ pointEqual(point, point0_0, 'When opening, viewer coordinate 0,0 is also point 0,0');
+ var image1Pixel = tiledImage1.viewerElementToImageCoordinates(point0_0);
+ pointEqual(image1Pixel, point0_0, 'When opening, viewer coordinate 0,0 is also image 1 pixel 0,0');
+ var image2Pixel = tiledImage2.viewerElementToImageCoordinates(point0_0);
+ pointEqual(image2Pixel,
+ new OpenSeadragon.Point(-2 * imageWidth, -2 * imageHeight),
+ 'When opening, viewer coordinates 0,0 is also image 2 pixel -2*imageWidth, -2*imageHeight');
+
+ var viewerWidth = $(viewer.element).width();
+ var viewerHeight = $(viewer.element).height();
+ var viewerBottomRight = new OpenSeadragon.Point(viewerWidth, viewerHeight);
+
+ point = viewport.viewerElementToViewportCoordinates(viewerBottomRight);
+ pointEqual(point, new OpenSeadragon.Point(1.5, 1.5),
+ 'Viewer bottom right has viewport coordinates 1.5,1.5.');
+ image1Pixel = tiledImage1.viewerElementToImageCoordinates(viewerBottomRight);
+ pointEqual(image1Pixel,
+ new OpenSeadragon.Point(imageWidth * 1.5, imageHeight * 1.5),
+ 'Viewer bottom right has image 1 pixel coordinates imageWidth * 1.5, imageHeight * 1.5');
+ image2Pixel = tiledImage2.viewerElementToImageCoordinates(viewerBottomRight);
+ pointEqual(image2Pixel,
+ new OpenSeadragon.Point(imageWidth, imageHeight),
+ 'Viewer bottom right has image 2 pixel coordinates imageWidth,imageHeight.');
+
+
+ checkPoint(' after opening');
+ viewer.addHandler('animation-finish', function animationHandler() {
+ viewer.removeHandler('animation-finish', animationHandler);
+ checkPoint(' after zoom and pan');
+ start();
+ });
+ viewer.viewport.zoomTo(0.8).panTo(new OpenSeadragon.Point(0.1, 0.2));
+
+ start();
+ });
+
+ viewer.open([{
+ tileSource: "/test/data/testpattern.dzi"
+ }, {
+ tileSource: "/test/data/testpattern.dzi",
+ x: 1,
+ y: 1,
+ width: 0.5
+ }
+ ]);
+ });
+
+
// ----------
- asyncTest('ZoomRatio', function() {
+ asyncTest('ZoomRatio 1 image', function () {
viewer.addHandler("open", function () {
var viewport = viewer.viewport;
- var imageWidth = 1000;
+ var imageWidth = viewer.source.dimensions.x;
function getCurrentImageWidth() {
return viewport.viewportToViewerElementCoordinates(
- new OpenSeadragon.Point(1, 0)).minus(
+ new OpenSeadragon.Point(1, 0)).minus(
viewport.viewportToViewerElementCoordinates(
- new OpenSeadragon.Point(0, 0))).x;
+ new OpenSeadragon.Point(0, 0))).x;
}
function checkZoom() {
@@ -105,7 +187,7 @@
var expectedImageZoom = currentImageWidth / imageWidth;
var expectedViewportZoom = viewport.getZoom(true);
var actualImageZoom = viewport.viewportToImageZoom(
- expectedViewportZoom);
+ expectedViewportZoom);
equal(actualImageZoom, expectedImageZoom);
var actualViewportZoom = viewport.imageToViewportZoom(actualImageZoom);
@@ -114,7 +196,7 @@
checkZoom();
- var zoomHandler = function() {
+ var zoomHandler = function () {
viewer.removeHandler('animation-finish', zoomHandler);
checkZoom();
start();
@@ -127,5 +209,61 @@
viewer.open('/test/data/testpattern.dzi');
});
+ // ----------
+ asyncTest('ZoomRatio 2 images', function () {
+ viewer.addHandler("open", function () {
+
+ var viewport = viewer.viewport;
+
+ var imageWidth = viewer.source.dimensions.x;
+ var image1 = viewer.world.getItemAt(0);
+ var image2 = viewer.world.getItemAt(1);
+
+ function getCurrentImageWidth(image) {
+ var bounds = image.getBounds();
+ return viewport.viewportToViewerElementCoordinates(
+ bounds.getTopRight()).minus(
+ viewport.viewportToViewerElementCoordinates(
+ bounds.getTopLeft())).x;
+ }
+
+ function checkZoom(image) {
+ var currentImageWidth = getCurrentImageWidth(image);
+ var expectedImageZoom = currentImageWidth / imageWidth;
+ var expectedViewportZoom = viewport.getZoom(true);
+ var actualImageZoom = image.viewportToImageZoom(
+ expectedViewportZoom);
+ Util.assessNumericValue(actualImageZoom, expectedImageZoom,
+ 0.00000001);
+
+ var actualViewportImage1Zoom = image.imageToViewportZoom(actualImageZoom);
+ Util.assessNumericValue(
+ actualViewportImage1Zoom, expectedViewportZoom, 0.00000001);
+ }
+
+ checkZoom(image1);
+ checkZoom(image2);
+
+ var zoomHandler = function () {
+ viewer.removeHandler('animation-finish', zoomHandler);
+ checkZoom(image1);
+ checkZoom(image2);
+ start();
+ };
+
+ viewer.addHandler('animation-finish', zoomHandler);
+ viewport.zoomTo(2);
+ });
+
+ viewer.open([{
+ tileSource: "/test/data/testpattern.dzi"
+ }, {
+ tileSource: "/test/data/testpattern.dzi",
+ x: 1,
+ y: 1,
+ width: 0.5
+ }
+ ]);
+ });
})();