Merge from master

This commit is contained in:
Antoine Vandecreme 2014-03-18 13:17:43 -04:00
commit c9df575347
17 changed files with 234 additions and 7 deletions

View File

@ -12,6 +12,9 @@ OPENSEADRAGON CHANGELOG
* Added 'ABSOLUTE' as a navigatorPosition option, along with corresponding navigatorTop, navigatorLeft options. Allows the navigator minimap to be placed anywhere in the viewer (#310)
* Enhanced the navigatorTop, navigatorLeft, navigatorHeight, and navigatorWidth options to allow a number for pixel units or a string for other element units (%, em, etc.) (#310)
* Additional enhancements for IIIF support (#315)
* Fixed: Setting degrees in Viewer constructor has no effect (#336)
* Added pre-draw event for tiles to allow applications to alter the image (#348)
* Added optional Rotate Left/Right buttons to standard controls (#341)
1.0.0:

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
images/rotateleft_hover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
images/rotateleft_rest.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
images/rotateright_rest.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1017,6 +1017,25 @@ function drawTiles( drawer, lastDrawn ){
tileSource,
collectionTileSource;
// We need a callback to give image manipulation a chance to happen
var drawingHandler = function(args) {
if (drawer.viewer) {
/**
* This event is fired just before the tile is drawn giving the application a chance to alter the image.
*
* NOTE: This event is only fired when the drawer is using a <canvas>.
*
* @event tile-drawing
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {OpenSeadragon.Tile} tile
* @property {?Object} userData - 'context', 'tile' and 'rendered'.
*/
drawer.viewer.raiseEvent('tile-drawing', args);
}
};
for ( i = lastDrawn.length - 1; i >= 0; i-- ) {
tile = lastDrawn[ i ];
@ -1088,10 +1107,10 @@ function drawTiles( drawer, lastDrawn ){
// specifically, don't save,rotate,restore every time we draw a tile
if( drawer.viewport.degrees !== 0 ) {
offsetForRotation( tile, drawer.canvas, drawer.context, drawer.viewport.degrees );
tile.drawCanvas( drawer.context );
tile.drawCanvas( drawer.context, drawingHandler );
restoreRotationChanges( tile, drawer.canvas, drawer.context );
} else {
tile.drawCanvas( drawer.context );
tile.drawCanvas( drawer.context, drawingHandler );
}
} else {
tile.drawHTML( drawer.canvas );

View File

@ -358,6 +358,11 @@
* image and if the 'next' button will wrap to the first image when viewing
* the last image.
*
* @property {Boolean} [showRotationControl=false]
* If true then the rotate left/right controls will be displayed as part of the
* standard controls. This is also subject to the browser support for rotate
* (e.g. viewer.drawer.canRotate()).
*
* @property {Boolean} [showSequenceControl=true]
* If the viewer has been configured with a sequence of tile sources, then
* provide buttons for navigating forward and backward through the images.
@ -815,6 +820,18 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
HOVER: 'fullpage_hover.png',
DOWN: 'fullpage_pressed.png'
},
rotateleft: {
REST: 'rotateleft_rest.png',
GROUP: 'rotateleft_grouphover.png',
HOVER: 'rotateleft_hover.png',
DOWN: 'rotateleft_pressed.png'
},
rotateright: {
REST: 'rotateright_rest.png',
GROUP: 'rotateright_grouphover.png',
HOVER: 'rotateright_hover.png',
DOWN: 'rotateright_pressed.png'
},
previous: {
REST: 'previous_rest.png',
GROUP: 'previous_grouphover.png',
@ -829,6 +846,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
}
},
navPrevNextWrap: false,
showRotationControl: false,
//DEVELOPER SETTINGS
debugMode: false,

View File

@ -55,7 +55,9 @@ var I18N = {
ZoomIn: "Zoom in",
ZoomOut: "Zoom out",
NextPage: "Next page",
PreviousPage: "Previous page"
PreviousPage: "Previous page",
RotateLeft: "Rotate left",
RotateRight: "Rotate right"
}
};

View File

@ -231,8 +231,10 @@ $.Tile.prototype = /** @lends OpenSeadragon.Tile.prototype */{
* Renders the tile in a canvas-based context.
* @function
* @param {Canvas} context
* @param {Function} method for firing the drawing event. drawingHandler({context, tile, rendered})
* where <code>rendered</code> is the context with the pre-drawn image.
*/
drawCanvas: function( context ) {
drawCanvas: function( context, drawingHandler ) {
var position = this.position,
size = this.size,
@ -280,6 +282,9 @@ $.Tile.prototype = /** @lends OpenSeadragon.Tile.prototype */{
rendered = TILE_CACHE[ this.url ];
// This gives the application a chance to make image manipulation changes as we are rendering the image
drawingHandler({context: context, tile: this, rendered: rendered});
//rendered.save();
context.drawImage(
rendered.canvas,

View File

@ -1150,6 +1150,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
doSingleZoomOutHandler = $.delegate( this, doSingleZoomOut ),
onHomeHandler = $.delegate( this, onHome ),
onFullScreenHandler = $.delegate( this, onFullScreen ),
onRotateLeftHandler = $.delegate( this, onRotateLeft ),
onRotateRightHandler = $.delegate( this, onRotateRight ),
onFocusHandler = $.delegate( this, onFocus ),
onBlurHandler = $.delegate( this, onBlur ),
navImages = this.navImages,
@ -1229,6 +1231,37 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
onBlur: onBlurHandler
}));
if (this.showRotationControl) {
buttons.push( this.rotateLeft = new $.Button({
element: this.rotateLeftButton ? $.getElement( this.rotateLeftButton ) : null,
clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold,
tooltip: $.getString( "Tooltips.RotateLeft" ),
srcRest: resolveUrl( this.prefixUrl, navImages.rotateleft.REST ),
srcGroup: resolveUrl( this.prefixUrl, navImages.rotateleft.GROUP ),
srcHover: resolveUrl( this.prefixUrl, navImages.rotateleft.HOVER ),
srcDown: resolveUrl( this.prefixUrl, navImages.rotateleft.DOWN ),
onRelease: onRotateLeftHandler,
onFocus: onFocusHandler,
onBlur: onBlurHandler
}));
buttons.push( this.rotateRight = new $.Button({
element: this.rotateRightButton ? $.getElement( this.rotateRightButton ) : null,
clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold,
tooltip: $.getString( "Tooltips.RotateRight" ),
srcRest: resolveUrl( this.prefixUrl, navImages.rotateright.REST ),
srcGroup: resolveUrl( this.prefixUrl, navImages.rotateright.GROUP ),
srcHover: resolveUrl( this.prefixUrl, navImages.rotateright.HOVER ),
srcDown: resolveUrl( this.prefixUrl, navImages.rotateright.DOWN ),
onRelease: onRotateRightHandler,
onFocus: onFocusHandler,
onBlur: onBlurHandler
}));
}
if( useGroup ){
this.buttons = new $.ButtonGroup({
buttons: buttons,
@ -1550,7 +1583,8 @@ function _getSafeElemSize (oElement) {
* @private
*/
function openTileSource( viewer, source ) {
var _this = viewer;
var i,
_this = viewer;
if ( _this.source ) {
_this.close( );
@ -1578,7 +1612,8 @@ function openTileSource( viewer, source ) {
showNavigator: false,
minZoomImageRatio: 1,
maxZoomPixelRatio: 1,
viewer: _this //,
viewer: _this,
degrees: _this.degrees //,
//TODO: figure out how to support these in a way that makes sense
//minZoomLevel: this.minZoomLevel,
//maxZoomLevel: this.maxZoomLevel
@ -1600,7 +1635,8 @@ function openTileSource( viewer, source ) {
defaultZoomLevel: _this.defaultZoomLevel,
minZoomLevel: _this.minZoomLevel,
maxZoomLevel: _this.maxZoomLevel,
viewer: _this
viewer: _this,
degrees: _this.degrees
});
}
@ -1629,6 +1665,21 @@ function openTileSource( viewer, source ) {
debugGridColor: _this.debugGridColor
});
// Now that we have a drawer, see if it supports rotate. If not we need to remove the rotate buttons
if (!_this.drawer.canRotate()) {
// Disable/remove the rotate left/right buttons since they aren't supported
if (_this.rotateLeft) {
i = _this.buttons.buttons.indexOf(_this.rotateLeft);
_this.buttons.buttons.splice(i, 1);
_this.buttons.element.removeChild(_this.rotateLeft.element);
}
if (_this.rotateRight) {
i = _this.buttons.buttons.indexOf(_this.rotateRight);
_this.buttons.buttons.splice(i, 1);
_this.buttons.element.removeChild(_this.rotateRight.element);
}
}
//Instantiate a navigator if configured
if ( _this.showNavigator && !_this.collectionMode ){
// Note: By passing the fully parsed source, the navigator doesn't
@ -2335,6 +2386,38 @@ function onFullScreen() {
}
}
/**
* Note: The current rotation feature is limited to 90 degree turns.
*/
function onRotateLeft() {
if ( this.viewport ) {
var currRotation = this.viewport.getRotation();
if (currRotation === 0) {
currRotation = 270;
}
else {
currRotation -= 90;
}
this.viewport.setRotation(currRotation);
}
}
/**
* Note: The current rotation feature is limited to 90 degree turns.
*/
function onRotateRight() {
if ( this.viewport ) {
var currRotation = this.viewport.getRotation();
if (currRotation === 270) {
currRotation = 0;
}
else {
currRotation += 90;
}
this.viewport.setRotation(currRotation);
}
}
function onPrevious(){
var previous = THIS[ this.hash ].sequence - 1;

View File

@ -280,4 +280,23 @@
viewer.open( '/test/data/testpattern.dzi' );
} );
// ----------
asyncTest( 'tile-drawing event', function () {
var tileDrawing = function ( event ) {
viewer.removeHandler( 'tile-drawing', tileDrawing );
ok( event, 'Event handler should be invoked' );
if ( event ) {
// Make sure we have the expected elements set
ok(event.context, "Context should be set");
ok(event.tile, "Tile should be set");
ok(event.rendered, "Rendered should be set");
}
viewer.close();
start();
};
viewer.addHandler( 'tile-drawing', tileDrawing );
viewer.open( '/test/data/testpattern.dzi' );
} );
} )();

77
test/rotate.js Normal file
View File

@ -0,0 +1,77 @@
/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */
(function () {
var viewer;
module('Basic', {
setup: function () {
var example = $('<div id="rotateTests"></div>').appendTo("#qunit-fixture");
testLog.reset();
},
teardown: function () {
if (viewer && viewer.close) {
viewer.close();
}
viewer = null;
}
});
asyncTest('RotateControlOff', function () {
var openHandler = function (event) {
viewer.removeHandler('open', openHandler);
ok(true, 'Open event was sent');
ok(viewer.drawer, 'Drawer exists');
ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true');
ok(!viewer.showRotationControl, 'showRotationControl should be off');
ok(!viewer.rotateLeft, "rotateLeft button should be null");
ok(!viewer.rotateRight, "rotateRight button should be null");
start();
};
viewer = OpenSeadragon({
id: 'rotateTests',
prefixUrl: '/build/openseadragon/images/',
springStiffness: 100, // Faster animation = faster tests
showRotationControl: false
});
viewer.addHandler('open', openHandler);
viewer.open('/test/data/testpattern.dzi');
});
asyncTest('RotateControlOn', function () {
var openHandler = function (event) {
viewer.removeHandler('open', openHandler);
ok(true, 'Open event was sent');
ok(viewer.drawer, 'Drawer exists');
ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true');
ok(viewer.showRotationControl, 'showRotationControl should be true');
ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateLeft), "rotateLeft should be found");
ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateRight), "rotateRight should be found");
// Now simulate the left/right button clicks.
// TODO: re-factor simulateViewerClickWithDrag so it'll accept any element, and use that.
ok(viewer.viewport.degrees === 0, "Image should start at 0 degrees rotation");
viewer.rotateLeft.onRelease();
ok(viewer.viewport.degrees === 270, "Image should be 270 degrees rotation (left)");
viewer.rotateRight.onRelease();
ok(viewer.viewport.degrees === 0, "Image should be 270 degrees rotation (right)");
start();
};
viewer = OpenSeadragon({
id: 'rotateTests',
prefixUrl: '/build/openseadragon/images/',
springStiffness: 100, // Faster animation = faster tests
showRotationControl: true
});
viewer.addHandler('open', openHandler);
viewer.open('/test/data/testpattern.dzi');
});
})();

View File

@ -28,5 +28,6 @@
<script src="/test/events.js"></script>
<script src="/test/units.js"></script>
<script src="/test/overlays.js"></script>
<script src="/test/rotate.js"></script>
</body>
</html>