Merge branch 'master' of github.com:openseadragon/openseadragon

This commit is contained in:
Jon Stroop 2013-09-11 13:24:18 -04:00
commit 8315eece4a
5 changed files with 208 additions and 71 deletions

View File

@ -7,6 +7,7 @@ OPENSEADRAGON CHANGELOG
* Fixed: LegacyTileSource doesn't fail gracefully when no supported file formats are found (#202) * Fixed: LegacyTileSource doesn't fail gracefully when no supported file formats are found (#202)
* Added an optional userData argument to EventHandler.addHandler() which is passed unchanged to the handler method (#203) * Added an optional userData argument to EventHandler.addHandler() which is passed unchanged to the handler method (#203)
* Fixed AJAX error reporting on IE8 (#208) * Fixed AJAX error reporting on IE8 (#208)
* Added viewportToImageRectangle method, and updated imageToViewportRectangle, imageToViewportCoordinates, and viewportToImageCoordinates to be more flexible with params (#212)
0.9.130: 0.9.130:

View File

@ -722,34 +722,65 @@ $.Viewport.prototype = {
}, },
/** /**
* Translates from Seajax viewer coordinate * Translates from OpenSeadragon viewer coordinate system to image coordinate system.
* system to image coordinate system * This method can be called either by passing X,Y coordinates or an
* OpenSeadragon.Point
* @function
* @param {OpenSeadragon.Point} viewerX the point in viewport coordinate system.
* @param {Number} viewerX X coordinate in viewport coordinate system.
* @param {Number} viewerY Y coordinate in viewport coordinate system.
* @return {OpenSeadragon.Point} a point representing the coordinates in the image.
*/ */
viewportToImageCoordinates: function(viewerX, viewerY) { viewportToImageCoordinates: function( viewerX, viewerY ) {
return new $.Point(viewerX * this.contentSize.x, viewerY * this.contentSize.y * this.contentAspectX); if ( arguments.length == 1 ) {
//they passed a point instead of individual components
return this.viewportToImageCoordinates( viewerX.x, viewerX.y );
}
return new $.Point( viewerX * this.contentSize.x, viewerY * this.contentSize.y * this.contentAspectX );
}, },
/** /**
* Translates from image coordinate system to * Translates from image coordinate system to OpenSeadragon viewer coordinate system
* Seajax viewer coordinate system * This method can be called either by passing X,Y coordinates or an
* OpenSeadragon.Point
* @function
* @param {OpenSeadragon.Point} imageX the point in image coordinate system.
* @param {Number} imageX X coordinate in image coordinate system.
* @param {Number} imageY Y coordinate in image coordinate system.
* @return {OpenSeadragon.Point} a point representing the coordinates in the viewport.
*/ */
imageToViewportCoordinates: function( imageX, imageY ) { imageToViewportCoordinates: function( imageX, imageY ) {
return new $.Point( imageX / this.contentSize.x, imageY / this.contentSize.y / this.contentAspectX); if ( arguments.length == 1 ) {
//they passed a point instead of individual components
return this.imageToViewportCoordinates( imageX.x, imageX.y );
}
return new $.Point( imageX / this.contentSize.x, imageY / this.contentSize.y / this.contentAspectX );
}, },
/** /**
* Translates from a rectangle which describes a portion of * Translates from a rectangle which describes a portion of the image in
* the image in pixel coordinates to OpenSeadragon viewport * pixel coordinates to OpenSeadragon viewport rectangle coordinates.
* rectangle coordinates. * This method can be called either by passing X,Y,width,height or an
* OpenSeadragon.Rect
* @function
* @param {OpenSeadragon.Rect} imageX the rectangle in image coordinate system.
* @param {Number} imageX the X coordinate of the top left corner of the rectangle
* in image coordinate system.
* @param {Number} imageY the Y coordinate of the top left corner of the rectangle
* in image coordinate system.
* @param {Number} pixelWidth the width in pixel of the rectangle.
* @param {Number} pixelHeight the height in pixel of the rectangle.
*/ */
imageToViewportRectangle: function( imageX, imageY, pixelWidth, pixelHeight ) { imageToViewportRectangle: function( imageX, imageY, pixelWidth, pixelHeight ) {
var coordA, var coordA,
coordB, coordB,
rect; rect;
if( arguments.length == 1 ){ if( arguments.length == 1 ) {
//they passed a rectangle instead of individual components //they passed a rectangle instead of individual components
rect = imageX; rect = imageX;
return this.imageToViewportRectangle(rect.x, rect.y, rect.width, rect.height); return this.imageToViewportRectangle(
rect.x, rect.y, rect.width, rect.height
);
} }
coordA = this.imageToViewportCoordinates( coordA = this.imageToViewportCoordinates(
imageX, imageY imageX, imageY
@ -763,6 +794,41 @@ $.Viewport.prototype = {
coordB.x, coordB.x,
coordB.y coordB.y
); );
},
/**
* Translates from a rectangle which describes a portion of
* the viewport in point coordinates to image rectangle coordinates.
* This method can be called either by passing X,Y,width,height or an
* OpenSeadragon.Rect
* @function
* @param {OpenSeadragon.Rect} viewerX the rectangle in viewport coordinate system.
* @param {Number} viewerX the X coordinate of the top left corner of the rectangle
* in viewport coordinate system.
* @param {Number} imageY the Y coordinate of the top left corner of the rectangle
* in viewport coordinate system.
* @param {Number} pointWidth the width of the rectangle in viewport coordinate system.
* @param {Number} pointHeight the height of the rectangle in viewport coordinate system.
*/
viewportToImageRectangle: function( viewerX, viewerY, pointWidth, pointHeight ) {
var coordA,
coordB,
rect;
if ( arguments.length == 1 ) {
//they passed a rectangle instead of individual components
rect = viewerX;
return this.viewportToImageRectangle(
rect.x, rect.y, rect.width, rect.height
);
}
coordA = this.viewportToImageCoordinates( viewerX, viewerY );
coordB = this.viewportToImageCoordinates( pointWidth, pointHeight );
return new $.Rect(
coordA.x,
coordA.y,
coordB.x,
coordB.y
);
} }
}; };

View File

@ -160,8 +160,15 @@
}; };
viewer.addHandler('animationfinish', clickHandler); viewer.addHandler('animationfinish', clickHandler);
Util.simulateViewerClick(viewer, 0.25, 0.25); Util.simulateViewerClickWithDrag( {
}); viewer: viewer,
widthFactor: 0.25,
heightFactor: 0.25,
dragCount: 0,
dragDx: 0,
dragDy: 0
} );
} );
viewer.open('/test/data/testpattern.dzi'); viewer.open('/test/data/testpattern.dzi');
}); });

View File

@ -5,12 +5,12 @@
module( 'Events', { module( 'Events', {
setup: function () { setup: function () {
var example = $( '<div id="example"></div>' ).appendTo( "#qunit-fixture" ); var example = $( '<div id="eventsexample"></div>' ).appendTo( "#qunit-fixture" );
testLog.reset(); testLog.reset();
viewer = OpenSeadragon( { viewer = OpenSeadragon( {
id: 'example', id: 'eventsexample',
prefixUrl: '/build/openseadragon/images/', prefixUrl: '/build/openseadragon/images/',
springStiffness: 100 // Faster animation = faster tests springStiffness: 100 // Faster animation = faster tests
} ); } );
@ -42,8 +42,8 @@
// ---------- // ----------
asyncTest( 'addHandler with userData', function () { asyncTest( 'addHandler with userData', function () {
var userData = { item1: 'Test user data', item2: Math.random() }; var userData = { item1: 'Test user data', item2: Math.random() },
var originalUserData = { item1: userData.item1, item2: userData.item2 }; originalUserData = { item1: userData.item1, item2: userData.item2 };
var openHandler = function ( eventSender, eventData ) { var openHandler = function ( eventSender, eventData ) {
viewer.removeHandler( 'open', openHandler ); viewer.removeHandler( 'open', openHandler );
@ -60,4 +60,50 @@
viewer.open( '/test/data/testpattern.dzi' ); viewer.open( '/test/data/testpattern.dzi' );
} ); } );
// ----------
asyncTest( 'canvas-drag canvas-release canvas-click', function () {
var dragCount = 10,
dragMovesHandled = 0,
releasesHandled = 0,
releasesExpected = 1;
var openHandler = function ( eventSender, eventData ) {
viewer.removeHandler( 'open', openHandler );
viewer.addHandler( 'canvas-drag', canvasDragHandler );
viewer.addHandler( 'canvas-release', canvasReleaseHandler );
viewer.addHandler( 'canvas-click', canvasClickHandler );
Util.simulateViewerClickWithDrag( {
viewer: viewer,
widthFactor: 0.25,
heightFactor: 0.25,
dragCount: dragCount,
dragDx: 1,
dragDy: 1
} );
};
var canvasDragHandler = function ( eventSender, eventData ) {
dragMovesHandled++;
};
var canvasReleaseHandler = function ( eventSender, eventData ) {
releasesHandled++;
};
var canvasClickHandler = function ( eventSender, eventData ) {
viewer.removeHandler( 'canvas-drag', canvasDragHandler );
viewer.removeHandler( 'canvas-release', canvasReleaseHandler );
viewer.removeHandler( 'canvas-click', canvasClickHandler );
equal( dragMovesHandled, dragCount, "'canvas-drag' event count matches 'mousemove' event count (" + dragCount + ")" );
equal( releasesHandled, releasesExpected, "'canvas-release' event count matches expected (" + releasesExpected + ")" );
viewer.close();
start();
};
viewer.addHandler( 'open', openHandler );
viewer.open( '/test/data/testpattern.dzi' );
} );
} )(); } )();

View File

@ -1,67 +1,84 @@
/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util */ /* global module, asyncTest, $, ok, equal, notEqual, start, test, Util */
(function() { (function () {
// ---------- // ----------
window.Util = { window.Util = {
// ---------- // ----------
simulateViewerClick: function(viewer, widthFactor, heightFactor) { simulateViewerClickWithDrag: function ( args ) {
if (widthFactor === undefined) { // args = { viewer, widthFactor, heightFactor, dragCount, dragDx, dragDy }
widthFactor = 0.5;
if ( args.hasOwnProperty( 'dragCount' ) ) {
args.dragDx = args.dragDx || 1;
args.dragDy = args.dragDy || 1;
}
else {
args.dragCount = 0;
}
if ( args.widthFactor === undefined ) {
args.widthFactor = 0.5;
} }
//TODO Redefine to be the middle by default //TODO Redefine to be the middle by default
if (heightFactor === undefined) { if ( args.heightFactor === undefined ) {
heightFactor = 0.5; args.heightFactor = 0.5;
} }
widthFactor = Math.min(1, Math.max(0, widthFactor)); args.widthFactor = Math.min( 1, Math.max( 0, args.widthFactor ) );
//TODO Fix this. The max height should be 1/AR //TODO Fix this. The max height should be 1/AR
heightFactor = Math.min(1, Math.max(0, heightFactor)); args.heightFactor = Math.min( 1, Math.max( 0, args.heightFactor ) );
var $canvas = $(viewer.element).find('.openseadragon-canvas').not('.navigator .openseadragon-canvas'); var $canvas = $( args.viewer.element ).find( '.openseadragon-canvas' ).not( '.navigator .openseadragon-canvas' );
var offset = $canvas.offset(); var offset = $canvas.offset();
var event = { var event = {
clientX: offset.left + Math.floor($canvas.width() * widthFactor), clientX: offset.left + Math.floor( $canvas.width() * args.widthFactor ),
clientY: offset.top + Math.floor($canvas.height() * heightFactor) clientY: offset.top + Math.floor( $canvas.height() * args.heightFactor )
}; };
$canvas $canvas
.simulate('mouseover', event) .simulate( 'mouseover', event )
.simulate('mousedown', event) .simulate( 'mousedown', event );
.simulate('mouseup', event); for ( var i = 0; i < args.dragCount; i++ ) {
event.clientX += args.dragDx;
event.clientY += args.dragDy;
$canvas
.simulate( "mousemove", event );
}
$canvas
.simulate( 'mouseup', event );
}, },
initializeTestDOM: function () { initializeTestDOM: function () {
$("#qunit-fixture") $( "#qunit-fixture" )
.append('<div><div id="example"></div><div id="exampleNavigator"></div></div>') .append( '<div><div id="example"></div><div id="exampleNavigator"></div></div>' )
.append('<div id="wideexample"></div>') .append( '<div id="wideexample"></div>' )
.append('<div id="tallexample"></div>'); .append( '<div id="tallexample"></div>' );
}, },
equalsWithVariance: function (value1, value2, variance) { equalsWithVariance: function ( value1, value2, variance ) {
return Math.abs(value1 - value2) <= variance; return Math.abs( value1 - value2 ) <= variance;
}, },
assessNumericValue: function (value1, value2, variance, message) { assessNumericValue: function ( value1, value2, variance, message ) {
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 );
}, },
timeWatcher: function(time) { timeWatcher: function ( time ) {
time = time || 2000; time = time || 2000;
var finished = false; var finished = false;
setTimeout(function() { setTimeout( function () {
if (!finished) { if ( !finished ) {
finished = true; finished = true;
ok(false, 'finishes in ' + time + 'ms'); ok( false, 'finishes in ' + time + 'ms' );
start(); start();
} }
}, time); }, time );
return { return {
done: function() { done: function () {
if (!finished) { if ( !finished ) {
finished = true; finished = true;
start(); start();
} }
@ -72,42 +89,42 @@
}; };
/* /*
Test console log capture Test console log capture
1. Only the OpenSeadragon.console logger is touched 1. Only the OpenSeadragon.console logger is touched
2. All log messages are stored in window.testLog in arrays keyed on the logger name (e.g. log, 2. All log messages are stored in window.testLog in arrays keyed on the logger name (e.g. log,
warning, error, etc.) as JSON-serialized strings to simplify comparisons warning, error, etc.) as JSON-serialized strings to simplify comparisons
3. The captured log arrays have a custom contains() method for ease of testing 3. The captured log arrays have a custom contains() method for ease of testing
4. testLog.reset() will clear all of the message arrays, intended for use in test setup routines 4. testLog.reset() will clear all of the message arrays, intended for use in test setup routines
*/ */
var testConsole = window.testConsole = {}, var testConsole = window.testConsole = {},
testLog = window.testLog = { testLog = window.testLog = {
log: [], log: [],
debug: [], debug: [],
info: [], info: [],
warn: [], warn: [],
error: [], error: [],
reset: function () { reset: function () {
for (var i in testLog) { for ( var i in testLog ) {
if (testLog.hasOwnProperty(i) && 'length' in testLog[i] && 'push' in testLog[i]) { if ( testLog.hasOwnProperty( i ) && 'length' in testLog[i] && 'push' in testLog[i] ) {
testLog[i].length = 0; testLog[i].length = 0;
} }
} }
} }
}; };
for (var i in testLog) { for ( var i in testLog ) {
if (testLog.hasOwnProperty(i) && testLog[i].push) { if ( testLog.hasOwnProperty( i ) && testLog[i].push ) {
testConsole[i] = (function (arr) { testConsole[i] = ( function ( arr ) {
return function () { return function () {
var args = Array.prototype.slice.call(arguments, 0); // Coerce to true Array var args = Array.prototype.slice.call( arguments, 0 ); // Coerce to true Array
arr.push(JSON.stringify(args)); // Store as JSON to avoid tedious array-equality tests arr.push( JSON.stringify( args ) ); // Store as JSON to avoid tedious array-equality tests
}; };
})(testLog[i]); } )( testLog[i] );
testLog[i].contains = function (needle) { testLog[i].contains = function ( needle ) {
for (var i = 0; i < this.length; i++) { for ( var i = 0; i < this.length; i++ ) {
if (this[i] == needle) { if ( this[i] == needle ) {
return true; return true;
} }
} }
@ -117,5 +134,5 @@
} }
OpenSeadragon.console = testConsole; OpenSeadragon.console = testConsole;
})(); } )();