Merge branch 'master' into layers

Conflicts:
	src/drawer.js
	src/viewer.js
	test/test.html
This commit is contained in:
Antoine Vandecreme 2014-03-19 16:24:48 -04:00
commit ba10c392a1
115 changed files with 1775 additions and 616 deletions

View File

@ -1,7 +1,26 @@
OPENSEADRAGON CHANGELOG
=======================
1.0.0: (in progress)
1.0.1: (in progress)
* DEPRECATION: overlay functions have been moved from Drawer to Viewer (#331)
* Improved overlay functions (#331)
* Fixed: Nav button highlight states aren't quite aligned on Firefox (#303)
* Added ControlAnchor options for default controls (#304)
* Enabled basic cross-domain tile loading without tainting canvas (works in Chrome and Firefox) (#308)
* Added a ControlAnchor.ABSOLUTE enumeration. Enables absolute positioning of control elements in the viewer (#310)
* Added a 'navigator-scroll' event to Navigator. Fired when mousewheel/pinch events occur in the navigator (#310)
* Added a navigatorMaintainSizeRatio option. If set to true, the navigator minimap resizes when the viewer element is resized (#310)
* 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:
NOTE: This version has a number of breaking changes to the API, mostly in event handling. See below.
* BREAKING CHANGE: All EventSource and MouseTracker event handler method signatures changed to 'handlerMethod(event)' where event == { eventSource, userData, ... } (#251) (Also fixes #23, #224, #239)
* The new eventSource property in the event object replaces the old eventSource parameter that was passed to handler methods.

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

@ -129,11 +129,9 @@ $.Button = function( options ) {
this.imgGroup = $.makeTransparentImage( this.srcGroup );
this.imgHover = $.makeTransparentImage( this.srcHover );
this.imgDown = $.makeTransparentImage( this.srcDown );
this.imgDiv = $.makeNeutralElement( "div" );
this.element.appendChild( this.imgRest );
this.element.appendChild( this.imgGroup );
this.element.appendChild( this.imgHover );
this.element.appendChild( this.imgDown );
this.imgDiv.style.position = "relative";
this.imgGroup.style.position =
this.imgHover.style.position =
@ -160,6 +158,12 @@ $.Button = function( options ) {
this.imgDown.style.top =
"";
}
this.imgDiv.appendChild( this.imgRest );
this.imgDiv.appendChild( this.imgGroup );
this.imgDiv.appendChild( this.imgHover );
this.imgDiv.appendChild( this.imgDown );
this.element.appendChild( this.imgDiv );
}

View File

@ -46,13 +46,15 @@
* @property {Number} TOP_RIGHT
* @property {Number} BOTTOM_LEFT
* @property {Number} BOTTOM_RIGHT
* @property {Number} ABSOLUTE
*/
$.ControlAnchor = {
NONE: 0,
TOP_LEFT: 1,
TOP_RIGHT: 2,
BOTTOM_RIGHT: 3,
BOTTOM_LEFT: 4
BOTTOM_LEFT: 4,
ABSOLUTE: 5
};
/**
@ -110,14 +112,30 @@ $.Control = function ( element, options, container ) {
* @member {Element} wrapper
* @memberof OpenSeadragon.Control#
*/
this.wrapper = $.makeNeutralElement( "span" );
this.wrapper.style.display = "inline-block";
this.wrapper.appendChild( this.element );
if ( this.anchor == $.ControlAnchor.ABSOLUTE ) {
this.wrapper = $.makeNeutralElement( "div" );
this.wrapper.style.position = "absolute";
this.wrapper.style.top = typeof ( options.top ) == "number" ? ( options.top + 'px' ) : options.top;
this.wrapper.style.left = typeof ( options.left ) == "number" ? (options.left + 'px' ) : options.left;
this.wrapper.style.height = typeof ( options.height ) == "number" ? ( options.height + 'px' ) : options.height;
this.wrapper.style.width = typeof ( options.width ) == "number" ? ( options.width + 'px' ) : options.width;
this.wrapper.style.margin = "0px";
this.wrapper.style.padding = "0px";
if ( this.anchor == $.ControlAnchor.NONE ) {
// IE6 fix
this.wrapper.style.width = this.wrapper.style.height = "100%";
this.element.style.position = "relative";
this.element.style.top = "0px";
this.element.style.left = "0px";
this.element.style.height = "100%";
this.element.style.width = "100%";
} else {
this.wrapper = $.makeNeutralElement( "span" );
this.wrapper.style.display = "inline-block";
if ( this.anchor == $.ControlAnchor.NONE ) {
// IE6 fix
this.wrapper.style.width = this.wrapper.style.height = "100%";
}
}
this.wrapper.appendChild( this.element );
if (options.attachToViewer ) {
if ( this.anchor == $.ControlAnchor.TOP_RIGHT ||
@ -161,7 +179,7 @@ $.Control.prototype = /** @lends OpenSeadragon.Control.prototype */{
*/
setVisible: function( visible ) {
this.wrapper.style.display = visible ?
"inline-block" :
( this.anchor == $.ControlAnchor.ABSOLUTE ? 'block' : 'inline-block' ) :
"none";
},

View File

@ -126,6 +126,11 @@
element.style.paddingLeft = "0px";
element.style.paddingTop = "0px";
break;
case $.ControlAnchor.ABSOLUTE:
div = this.container;
element.style.margin = "0px";
element.style.padding = "0px";
break;
default:
case $.ControlAnchor.NONE:
div = this.container;

View File

@ -87,8 +87,7 @@ $.Drawer = function( options ) {
//internal state / configurable settings
overlays: [], // An unordered list of Overlays added.
collectionOverlays: {},
collectionOverlays: {}, // For collection mode. Here an overlay is actually a viewer.
//configurable settings
opacity: $.DEFAULT_SETTINGS.opacity,
@ -150,18 +149,6 @@ $.Drawer = function( options ) {
this.container.style.textAlign = "left";
this.container.appendChild( this.canvas );
//create the correct type of overlay by convention if the overlays
//are not already OpenSeadragon.Overlays
for( i = 0; i < this.overlays.length; i++ ){
if( $.isPlainObject( this.overlays[ i ] ) ){
this.overlays[ i ] = addOverlayFromConfiguration( this, this.overlays[ i ]);
} else if ( $.isFunction( this.overlays[ i ] ) ){
//TODO
}
}
//this.profiler = new $.Profiler();
};
@ -179,57 +166,15 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
* @param {OpenSeadragon.OverlayPlacement} placement - The position of the
* viewport which the location coordinates will be treated as relative
* to.
* @param {function} onDraw - If supplied the callback is called when the overlay
* @param {function} onDraw - If supplied the callback is called when the overlay
* needs to be drawn. It it the responsibility of the callback to do any drawing/positioning.
* It is passed position, size and element.
* @fires OpenSeadragon.Viewer.event:add-overlay
* @deprecated - use {@link OpenSeadragon.Viewer#addOverlay} instead.
*/
addOverlay: function( element, location, placement, onDraw ) {
var options;
if( $.isPlainObject( element ) ){
options = element;
} else {
options = {
element: element,
location: location,
placement: placement,
onDraw: onDraw
};
}
element = $.getElement(options.element);
if ( getOverlayIndex( this.overlays, element ) >= 0 ) {
// they're trying to add a duplicate overlay
return;
}
this.overlays.push( new $.Overlay({
element: element,
location: options.location,
placement: options.placement,
onDraw: options.onDraw
}) );
this.updateAgain = true;
if( this.viewer ){
/**
* Raised when an overlay is added to the viewer (see {@link OpenSeadragon.Drawer#addOverlay}).
*
* @event add-overlay
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {Element} element - The overlay element.
* @property {OpenSeadragon.Point|OpenSeadragon.Rect} location
* @property {OpenSeadragon.OverlayPlacement} placement
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.viewer.raiseEvent( 'add-overlay', {
element: element,
location: options.location,
placement: options.placement
});
}
$.console.error("drawer.addOverlay is deprecated. Use viewer.addOverlay instead.");
this.viewer.addOverlay( element, location, placement, onDraw );
return this;
},
@ -244,36 +189,11 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
* to.
* @return {OpenSeadragon.Drawer} Chainable.
* @fires OpenSeadragon.Viewer.event:update-overlay
* @deprecated - use {@link OpenSeadragon.Viewer#updateOverlay} instead.
*/
updateOverlay: function( element, location, placement ) {
var i;
element = $.getElement( element );
i = getOverlayIndex( this.overlays, element );
if ( i >= 0 ) {
this.overlays[ i ].update( location, placement );
this.updateAgain = true;
}
if( this.viewer ){
/**
* Raised when an overlay's location or placement changes (see {@link OpenSeadragon.Drawer#updateOverlay}).
*
* @event update-overlay
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {Element} element
* @property {OpenSeadragon.Point|OpenSeadragon.Rect} location
* @property {OpenSeadragon.OverlayPlacement} placement
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.viewer.raiseEvent( 'update-overlay', {
element: element,
location: location,
placement: placement
});
}
$.console.error("drawer.updateOverlay is deprecated. Use viewer.updateOverlay instead.");
this.viewer.updateOverlay( element, location, placement );
return this;
},
@ -285,33 +205,11 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
* element id which represent the ovelay content to be removed.
* @return {OpenSeadragon.Drawer} Chainable.
* @fires OpenSeadragon.Viewer.event:remove-overlay
* @deprecated - use {@link OpenSeadragon.Viewer#removeOverlay} instead.
*/
removeOverlay: function( element ) {
var i;
element = $.getElement( element );
i = getOverlayIndex( this.overlays, element );
if ( i >= 0 ) {
this.overlays[ i ].destroy();
this.overlays.splice( i, 1 );
this.updateAgain = true;
}
if( this.viewer ){
/**
* Raised when an overlay is removed from the viewer (see {@link OpenSeadragon.Drawer#removeOverlay}).
*
* @event remove-overlay
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {Element} element - The overlay element.
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.viewer.raiseEvent( 'remove-overlay', {
element: element
});
}
$.console.error("drawer.removeOverlay is deprecated. Use viewer.removeOverlay instead.");
this.viewer.updateOverlay( element );
return this;
},
@ -321,24 +219,11 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
* @method
* @return {OpenSeadragon.Drawer} Chainable.
* @fires OpenSeadragon.Viewer.event:clear-overlay
* @deprecated - use {@link OpenSeadragon.Viewer#clearOverlays} instead.
*/
clearOverlays: function() {
while ( this.overlays.length > 0 ) {
this.overlays.pop().destroy();
this.updateAgain = true;
}
if( this.viewer ){
/**
* Raised when all overlays are removed from the viewer (see {@link OpenSeadragon.Drawer#clearOverlays}).
*
* @event clear-overlay
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.viewer.raiseEvent( 'clear-overlay', {} );
}
$.console.error("drawer.clearOverlays is deprecated. Use viewer.clearOverlays instead.");
this.viewer.clearOverlays();
return this;
},
@ -362,7 +247,6 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
getOpacity: function() {
return this.opacity;
},
/**
* Returns whether the Drawer is scheduled for an update at the
* soonest possible opportunity.
@ -441,6 +325,7 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
this.downloading++;
image = new Image();
image.crossOrigin = 'Anonymous';
complete = function( imagesrc, resultingImage ){
_this.downloading--;
@ -488,61 +373,6 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
}
};
/**
* @private
* @inner
*/
function addOverlayFromConfiguration( drawer, overlay ){
var element = null,
rect = ( overlay.height && overlay.width ) ? new $.Rect(
overlay.x || overlay.px,
overlay.y || overlay.py,
overlay.width,
overlay.height
) : new $.Point(
overlay.x || overlay.px,
overlay.y || overlay.py
),
id = overlay.id ?
overlay.id :
"openseadragon-overlay-"+Math.floor(Math.random()*10000000);
element = $.getElement(overlay.id);
if( !element ){
element = document.createElement("a");
element.href = "#/overlay/"+id;
}
element.id = id;
$.addClass( element, overlay.className ?
overlay.className :
"openseadragon-overlay"
);
if(overlay.px !== undefined){
//if they specified 'px' so it's in pixel coordinates so
//we need to translate to viewport coordinates
rect = drawer.viewport.imageToViewportRectangle( rect );
}
if( overlay.placement ){
return new $.Overlay({
element: element,
location: drawer.viewport.pointFromPixel(rect),
placement: $.OverlayPlacement[overlay.placement.toUpperCase()],
onDraw: overlay.onDraw
});
}else{
return new $.Overlay({
element: element,
location: rect,
onDraw: overlay.onDraw
});
}
}
/**
* @private
* @inner
@ -716,7 +546,6 @@ function updateViewport( drawer ) {
//TODO
drawTiles( drawer, drawer.lastDrawn );
drawOverlays( drawer.viewport, drawer.overlays, drawer.container );
//TODO
if ( best ) {
@ -1163,23 +992,6 @@ function resetCoverage( coverage, level ) {
coverage[ level ] = {};
}
/**
* @private
* @inner
* Determines the 'z-index' of the given overlay. Overlays are ordered in
* a z-index based on the order they are added to the Drawer.
*/
function getOverlayIndex( overlays, element ) {
var i;
for ( i = overlays.length - 1; i >= 0; i-- ) {
if ( overlays[ i ].element == element ) {
return i;
}
}
return -1;
}
/**
* @private
* @inner
@ -1217,28 +1029,6 @@ function finishLoadingImage( image, callback, successful, jobid ){
}
function drawOverlays( viewport, overlays, container ){
var i,
length = overlays.length;
for ( i = 0; i < length; i++ ) {
drawOverlay( viewport, overlays[ i ], container );
}
}
function drawOverlay( viewport, overlay, container ){
overlay.position = viewport.pixelFromPoint(
overlay.bounds.getTopLeft(),
true
);
overlay.size = viewport.deltaPixelsFromPoints(
overlay.bounds.getSize(),
true
);
overlay.drawHTML( container, viewport );
}
function drawTiles( drawer, lastDrawn ){
var i,
tile,
@ -1249,6 +1039,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 ];
@ -1299,7 +1108,7 @@ function drawTiles( drawer, lastDrawn ){
')';
}
drawer.addOverlay(
drawer.viewer.addOverlay(
viewer.element,
tile.bounds
);
@ -1320,10 +1129,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

@ -45,20 +45,49 @@
*/
$.IIIF1_1TileSource = function( options ){
$.extend( true, this, options );
if( !(this.height && this.width && this['@id'] ) ){
throw new Error('IIIF required parameters not provided.');
if ( !( this.height && this.width && this['@id'] ) ){
throw new Error( 'IIIF required parameters not provided.' );
}
if ( !(this.tile_width && this.tile_height) ) {
// use the short dimension if there aren't tile sizes provided.
options.tileSize = Math.min(this.height, this.width);
} else {
if ( ( this.profile &&
this.profile == "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0" ) ){
// what if not reporting a profile?
throw new Error( 'IIIF Image API 1.1 compliance level 1 or greater is required.' );
}
if ( this.tile_width ) {
options.tileSize = this.tile_width;
} else if ( this.tile_height ) {
options.tileSize = this.tile_height;
} else {
// use the largest of tileOptions that is smaller than the short
// dimension
var shortDim = Math.min( this.height, this.width ),
tileOptions = [256,512,1024],
smallerTiles = [];
for ( var c = 0; c < tileOptions.length; c++ ) {
if ( tileOptions[c] <= shortDim ) {
smallerTiles.push( tileOptions[c] );
}
}
if ( smallerTiles.length > 0 ) {
options.tileSize = Math.max.apply( null, smallerTiles );
} else {
// If we're smaller than 256, just use the short side.
options.tileSize = shortDim;
}
this.tile_width = options.tileSize; // So that 'full' gets used for
this.tile_height = options.tileSize; // the region below
}
if (! options.maxLevel ) {
if ( !options.maxLevel ) {
var mf = -1;
var scfs = this.scale_factors || this.scale_factor;
if ( scfs instanceof Array ) {
@ -67,7 +96,7 @@ $.IIIF1_1TileSource = function( options ){
if ( !isNaN( cf ) && cf > mf ) { mf = cf; }
}
}
if ( mf < 0 ) { options.maxLevel = Number(Math.ceil(Math.log(Math.max(this.width, this.height), 2))); }
if ( mf < 0 ) { options.maxLevel = Number( Math.ceil( Math.log( Math.max( this.width, this.height ), 2 ) ) ); }
else { options.maxLevel = mf; }
}
@ -82,33 +111,29 @@ $.extend( $.IIIF1_1TileSource.prototype, $.TileSource.prototype, /** @lends Open
* @param {Object|Array} data
* @param {String} optional - url
*/
supports: function( data, url ){
return data.profile && (
"http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0" == data.profile ||
"http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1" == data.profile ||
"http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2" == data.profile ||
"http://library.stanford.edu/iiif/image-api/1.1/compliance.html" == data.profile
);
supports: function( data, url ) {
return ( data['@context'] &&
data['@context'] == "http://library.stanford.edu/iiif/image-api/1.1/context.json" );
},
/**
*
* @function
* @param {Object} data - the raw configuration
* @example <caption>IIIF 1.1 Info Looks like this (XML syntax is no more)</caption>
* {
* "@context" : "http://library.stanford.edu/iiif/image-api/1.1/context.json",
* "@id" : "http://iiif.example.com/prefix/1E34750D-38DB-4825-A38A-B60A345E591C",
* "width" : 6000,
* "height" : 4000,
* "scale_factors" : [ 1, 2, 4 ],
* "tile_width" : 1024,
* "tile_height" : 1024,
* "formats" : [ "jpg", "png" ],
* "qualities" : [ "native", "grey" ],
* "profile" : "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0"
* }
*/
// IIIF 1.1 Info Looks like this (XML syntax is no more):
// {
// "@context" : "http://library.stanford.edu/iiif/image-api/1.1/context.json",
// "@id" : "http://iiif.example.com/prefix/1E34750D-38DB-4825-A38A-B60A345E591C",
// "width" : 6000,
// "height" : 4000,
// "scale_factors" : [ 1, 2, 4 ],
// "tile_width" : 1024,
// "tile_height" : 1024,
// "formats" : [ "jpg", "png" ],
// "qualities" : [ "native", "grey" ]
// "profile" : "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level0"
// }
configure: function( data ){
return data;
},
@ -124,6 +149,7 @@ $.extend( $.IIIF1_1TileSource.prototype, $.TileSource.prototype, /** @lends Open
getTileUrl: function( level, x, y ){
//# constants
var IIIF_ROTATION = '0',
IIIF_QUALITY = 'native.jpg',
@ -131,32 +157,34 @@ $.extend( $.IIIF1_1TileSource.prototype, $.TileSource.prototype, /** @lends Open
scale = Math.pow( 0.5, this.maxLevel - level ),
//# image dimensions at this level
level_width = Math.ceil( this.width * scale ),
level_height = Math.ceil( this.height * scale ),
levelWidth = Math.ceil( this.width * scale ),
levelHeight = Math.ceil( this.height * scale ),
//## iiif region
iiif_tile_size_width = Math.ceil( this.tileSize / scale ),
iiif_tile_size_height = Math.ceil( this.tileSize / scale ),
iiif_region,
iiif_tile_x,
iiif_tile_y,
iiif_tile_w,
iiif_tile_h,
iiif_size,
iiifTileSizeWidth = Math.ceil( this.tileSize / scale ),
iiifTileSizeHeight = Math.ceil( this.tileSize / scale ),
iiifRegion,
iiifTileX,
iiifTileY,
iiifTileW,
iiifTileH,
iiifSize,
uri;
if ( level_width < this.tile_width && level_height < this.tile_height ){
iiif_size = level_width + "," + level_height;
iiif_region = 'full';
if ( levelWidth < this.tile_width && levelHeight < this.tile_height ){
iiifSize = levelWidth + ",";
iiifRegion = 'full';
} else {
iiif_tile_x = x * iiif_tile_size_width;
iiif_tile_y = y * iiif_tile_size_height;
iiif_tile_w = Math.min( iiif_tile_size_width, this.width - iiif_tile_x );
iiif_tile_h = Math.min( iiif_tile_size_height, this.height - iiif_tile_y );
iiif_size = Math.ceil(iiif_tile_w * scale) + "," + Math.ceil(iiif_tile_h * scale);
iiif_region = [ iiif_tile_x, iiif_tile_y, iiif_tile_w, iiif_tile_h ].join(',');
iiifTileX = x * iiifTileSizeWidth;
iiifTileY = y * iiifTileSizeHeight;
iiifTileW = Math.min( iiifTileSizeWidth, this.width - iiifTileX );
iiifTileH = Math.min( iiifTileSizeHeight, this.height - iiifTileY );
iiifSize = Math.ceil( iiifTileW * scale ) + ",";
iiifRegion = [ iiifTileX, iiifTileY, iiifTileW, iiifTileH ].join( ',' );
}
uri = [ this['@id'], iiif_region, iiif_size, IIIF_ROTATION, IIIF_QUALITY ].join('/');
uri = [ this['@id'], iiifRegion, iiifSize, IIIF_ROTATION, IIIF_QUALITY ].join( '/' );
return uri;
}
});

View File

@ -114,7 +114,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
* @param {Object|XMLDocument} data - the raw configuration
* @param {String} url - the url the data was retreived from if any.
* @return {Object} options - A dictionary of keyword arguments sufficient
* to configure this tile source via it's constructor.
* to configure this tile source via its constructor.
*/
configure: function( data, url ){
var service,

View File

@ -50,7 +50,8 @@
$.Navigator = function( options ){
var viewer = options.viewer,
viewerSize = $.getElementSize( viewer.element),
viewerSize,
navigatorSize,
unneededElement;
//We may need to create a new element and id if they did not
@ -73,6 +74,12 @@ $.Navigator = function( options ){
options.controlOptions.anchor = $.ControlAnchor.TOP_RIGHT;
} else if( 'TOP_LEFT' == options.position ){
options.controlOptions.anchor = $.ControlAnchor.TOP_LEFT;
} else if( 'ABSOLUTE' == options.position ){
options.controlOptions.anchor = $.ControlAnchor.ABSOLUTE;
options.controlOptions.top = options.top;
options.controlOptions.left = options.left;
options.controlOptions.height = options.height;
options.controlOptions.width = options.width;
}
}
@ -99,12 +106,12 @@ $.Navigator = function( options ){
showSequenceControl: false,
immediateRender: true,
blendTime: 0,
animationTime: 0
animationTime: 0,
autoResize: options.autoResize
});
options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio;
this.viewerSizeInPoints = viewer.viewport.deltaPointsFromPixels(viewerSize);
this.borderWidth = 2;
//At some browser magnification levels the display regions lines up correctly, but at some there appears to
//be a one pixel gap.
@ -112,14 +119,16 @@ $.Navigator = function( options ){
this.totalBorderWidths = new $.Point(this.borderWidth*2, this.borderWidth*2).minus(this.fudge);
(function( style, borderWidth ){
style.margin = '0px';
style.border = borderWidth + 'px solid #555';
style.padding = '0px';
style.background = '#000';
style.opacity = 0.8;
style.overflow = 'hidden';
}( this.element.style, this.borderWidth));
if ( options.controlOptions.anchor != $.ControlAnchor.NONE ) {
(function( style, borderWidth ){
style.margin = '0px';
style.border = borderWidth + 'px solid #555';
style.padding = '0px';
style.background = '#000';
style.opacity = 0.8;
style.overflow = 'hidden';
}( this.element.style, this.borderWidth));
}
this.displayRegion = $.makeNeutralElement( "div" );
this.displayRegion.id = this.element.id + '-displayregion';
@ -152,15 +161,11 @@ $.Navigator = function( options ){
this.element.innerTracker = new $.MouseTracker({
element: this.element,
dragHandler: $.delegate( this, onCanvasDrag ),
clickHandler: $.delegate( this, onCanvasClick ),
releaseHandler: $.delegate( this, onCanvasRelease ),
scrollHandler: function(){
//dont scroll the page up and down if the user is scrolling
//in the navigator
return false;
}
element: this.element,
dragHandler: $.delegate( this, onCanvasDrag ),
clickHandler: $.delegate( this, onCanvasClick ),
releaseHandler: $.delegate( this, onCanvasRelease ),
scrollHandler: $.delegate( this, onCanvasScroll )
}).setTracking( true );
/*this.displayRegion.outerTracker = new $.MouseTracker({
@ -178,14 +183,22 @@ $.Navigator = function( options ){
options.controlOptions
);
if( options.width && options.height ){
this.element.style.width = options.width + 'px';
this.element.style.height = options.height + 'px';
} else {
this.element.style.width = ( viewerSize.x * options.sizeRatio ) + 'px';
this.element.style.height = ( viewerSize.y * options.sizeRatio ) + 'px';
if ( options.controlOptions.anchor != $.ControlAnchor.ABSOLUTE && options.controlOptions.anchor != $.ControlAnchor.NONE ) {
if ( options.width && options.height ) {
this.element.style.height = typeof ( options.height ) == "number" ? ( options.height + 'px' ) : options.height;
this.element.style.width = typeof ( options.width ) == "number" ? ( options.width + 'px' ) : options.width;
} else {
viewerSize = $.getElementSize( viewer.element );
this.element.style.height = ( viewerSize.y * options.sizeRatio ) + 'px';
this.element.style.width = ( viewerSize.x * options.sizeRatio ) + 'px';
this.oldViewerSize = viewerSize;
}
navigatorSize = $.getElementSize( this.element );
this.elementArea = navigatorSize.x * navigatorSize.y;
}
this.oldContainerSize = new $.Point( 0, 0 );
$.Viewer.apply( this, [ options ] );
this.element.getElementsByTagName('form')[0].appendChild( this.displayRegion );
@ -199,18 +212,71 @@ $.Navigator = function( options ){
$.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /** @lends OpenSeadragon.Navigator.prototype */{
/**
* Used to notify the navigator when its size has changed.
* Especially useful when {@link OpenSeadragon.Options}.navigatorAutoResize is set to false and the navigator is resizable.
* @function
*/
update: function( viewport ){
updateSize: function () {
if ( this.viewport ) {
var containerSize = new $.Point(
(this.container.clientWidth === 0 ? 1 : this.container.clientWidth),
(this.container.clientHeight === 0 ? 1 : this.container.clientHeight)
);
if ( !containerSize.equals( this.oldContainerSize ) ) {
var oldBounds = this.viewport.getBounds();
var oldCenter = this.viewport.getCenter();
this.viewport.resize( containerSize, true );
var imageHeight = 1 / this.source.aspectRatio;
var newWidth = oldBounds.width <= 1 ? oldBounds.width : 1;
var newHeight = oldBounds.height <= imageHeight ?
oldBounds.height : imageHeight;
var newBounds = new $.Rect(
oldCenter.x - ( newWidth / 2.0 ),
oldCenter.y - ( newHeight / 2.0 ),
newWidth,
newHeight
);
this.viewport.fitBounds( newBounds, true );
this.oldContainerSize = containerSize;
this.drawer.update();
}
}
},
var bounds,
/**
* Used to update the navigator minimap's viewport rectangle when a change in the viewer's viewport occurs.
* @function
* @param {OpenSeadragon.Viewport} The viewport this navigator is tracking.
*/
update: function( viewport ) {
var viewerSize,
newWidth,
newHeight,
bounds,
topleft,
bottomright;
if( viewport && this.viewport ){
viewerSize = $.getElementSize( this.viewer.element );
if ( !viewerSize.equals( this.oldViewerSize ) ) {
this.oldViewerSize = viewerSize;
if ( this.maintainSizeRatio ) {
newWidth = viewerSize.x * this.sizeRatio;
newHeight = viewerSize.y * this.sizeRatio;
}
else {
newWidth = Math.sqrt(this.elementArea * (viewerSize.x / viewerSize.y));
newHeight = this.elementArea / newWidth;
}
this.element.style.width = newWidth + 'px';
this.element.style.height = newHeight + 'px';
this.updateSize();
}
if( viewport && this.viewport ) {
bounds = viewport.getBounds( true );
topleft = this.viewport.pixelFromPoint( bounds.getTopLeft());
bottomright = this.viewport.pixelFromPoint( bounds.getBottomRight()).minus(this.totalBorderWidths);
topleft = this.viewport.pixelFromPoint( bounds.getTopLeft(), false );
bottomright = this.viewport.pixelFromPoint( bounds.getBottomRight(), false ).minus( this.totalBorderWidths );
//update style for navigator-box
(function(style) {
@ -229,7 +295,8 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
},
open: function( source ){
open: function( source ) {
this.updateSize();
var containerSize = this.viewer.viewport.containerSize.times( this.sizeRatio );
if( source.tileSize > containerSize.x ||
source.tileSize > containerSize.y ){
@ -256,21 +323,7 @@ function onCanvasClick( event ) {
dimensions;
if (! this.drag) {
if ( this.viewer.viewport ) {
viewerPosition = this.viewport.deltaPointsFromPixels( event.position );
dimensions = this.viewer.viewport.getBounds().getSize();
newBounds = new $.Rect(
viewerPosition.x - dimensions.x/2,
viewerPosition.y - dimensions.y/2,
dimensions.x,
dimensions.y
);
if (this.viewer.source.aspectRatio > this.viewer.viewport.getAspectRatio()) {
newBounds.y = newBounds.y - ((this.viewerSizeInPoints.y - (1/this.viewer.source.aspectRatio)) /2 );
}
else {
newBounds.x = newBounds.x - ((this.viewerSizeInPoints.x -1) /2 );
}
this.viewer.viewport.fitBounds(newBounds);
this.viewer.viewport.panTo( this.viewport.pointFromPixel( event.position ) );
this.viewer.viewport.applyConstraints();
}
}
@ -320,16 +373,30 @@ function onCanvasRelease( event ) {
* @function
*/
function onCanvasScroll( event ) {
var factor;
if ( this.viewer.viewport ) {
factor = Math.pow( this.zoomPerScroll, event.scroll );
this.viewer.viewport.zoomBy(
factor,
this.viewport.getCenter()
);
this.viewer.viewport.applyConstraints();
}
//cancels event
/**
* Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#navigator} element (mouse wheel, touch pinch, etc.).
*
* @event navigator-scroll
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
* @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.
* @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element.
* @property {Number} scroll - The scroll delta for the event.
* @property {Boolean} shift - True if the shift key was pressed during this event.
* @property {Object} originalEvent - The original DOM event.
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.viewer.raiseEvent( 'navigator-scroll', {
tracker: event.eventSource,
position: event.position,
scroll: event.scroll,
shift: event.shift,
originalEvent: event.originalEvent
});
//dont scroll the page up and down if the user is scrolling
//in the navigator
return false;
}

View File

@ -102,11 +102,11 @@
*/
/**
* The root namespace for OpenSeadragon. All utility methods
* and classes are defined on or below this namespace.
*
* @namespace OpenSeadragon
*
* @classdesc The root namespace for OpenSeadragon. All utility methods
* and classes are defined on or below this namespace.
*
*/
@ -136,6 +136,28 @@
* is an Array of objects, it is used to create a
* {@link OpenSeadragon.LegacyTileSource}.
*
* @property {Array} overlays Array of objects defining permanent overlays of
* the viewer. The overlays added via this option and later removed with
* {@link OpenSeadragon.Viewer#removeOverlay} will be added back when a new
* image is opened.
* To add overlays which can be definitively removed, one must use
* {@link OpenSeadragon.Viewer#addOverlay}
* If displaying a sequence of images, the overlays can be associated
* with a specific page by passing the overlays array to the page's
* tile source configuration.
* Expected properties:
* * x, y, (or px, py for pixel coordinates) to define the location.
* * width, height in point if using x,y or in pixels if using px,py. If width
* and height are specified, the overlay size is adjusted when zooming,
* otherwise the size stays the size of the content (or the size defined by CSS).
* * className to associate a class to the overlay
* * id to set the overlay element. If an element with this id already exists,
* it is reused, otherwise it is created. If not specified, a new element is
* created.
* * placement a string to define the relative position to the viewport.
* Only used if no width and height are specified. Default: 'TOP_LEFT'.
* See {@link OpenSeadragon.OverlayPlacement} for possible values.
*
* @property {String} [xmlPath=null]
* <strong>DEPRECATED</strong>. A relative path to load a DZI file from the server.
* Prefer the newer Options.tileSources.
@ -270,24 +292,45 @@
* @property {Boolean} [showNavigationControl=true]
* Set to false to prevent the appearance of the default navigation controls.
*
* @property {OpenSeadragon.ControlAnchor} [navigationControlAnchor=TOP_LEFT]
* Placement of the default navigation controls.
*
* @property {Boolean} [showNavigator=false]
* Set to true to make the navigator minimap appear.
*
* @property {Boolean} [navigatorId=navigator-GENERATED DATE]
* Set the ID of a div to hold the navigator minimap. If one is not specified,
* one will be generated and placed on top of the main image
* The ID of a div to hold the navigator minimap.
* If an ID is specified, the navigatorPosition, navigatorSizeRatio, navigatorMaintainSizeRatio, and navigatorTop|Left|Height|Width options will be ignored.
* If an ID is not specified, a div element will be generated and placed on top of the main image.
*
* @property {Number} [navigatorHeight=null]
* TODO: Implement this. Currently not used.
*
* @property {Number} [navigatorWidth=null]
* TODO: Implement this. Currently not used.
*
* @property {Number} [navigatorPosition=null]
* TODO: Implement this. Currently not used.
* @property {String} [navigatorPosition='TOP_RIGHT']
* Valid values are 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', 'BOTTOM_RIGHT', or 'ABSOLUTE'.<br>
* If 'ABSOLUTE' is specified, then navigatorTop|Left|Height|Width determines the size and position of the navigator minimap in the viewer, and navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.<br>
* For 'TOP_LEFT', 'TOP_RIGHT', 'BOTTOM_LEFT', and 'BOTTOM_RIGHT', the navigatorSizeRatio or navigatorHeight|Width values determine the size of the navigator minimap.
*
* @property {Number} [navigatorSizeRatio=0.2]
* Ratio of navigator size to viewer size.
* Ratio of navigator size to viewer size. Ignored if navigatorHeight|Width are specified.
*
* @property {Boolean} [navigatorMaintainSizeRatio=false]
* If true, the navigator minimap is resized (using navigatorSizeRatio) when the viewer size changes.
*
* @property {Number|String} [navigatorTop=null]
* Specifies the location of the navigator minimap (see navigatorPosition).
*
* @property {Number|String} [navigatorLeft=null]
* Specifies the location of the navigator minimap (see navigatorPosition).
*
* @property {Number|String} [navigatorHeight=null]
* Specifies the size of the navigator minimap (see navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.
*
* @property {Number|String} [navigatorWidth=null]
* Specifies the size of the navigator minimap (see navigatorPosition).
* If specified, navigatorSizeRatio and navigatorMaintainSizeRatio are ignored.
*
* @property {Boolean} [navigatorAutoResize=true]
* Set to false to prevent polling for navigator size changes. Useful for providing custom resize behavior.
* Setting to false can also improve performance when the navigator is configured to a fixed size.
*
* @property {Number} [controlsFadeDelay=2000]
* The number of milliseconds to wait once the user has stopped interacting
@ -321,10 +364,18 @@
* 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.
*
* @property {OpenSeadragon.ControlAnchor} [sequenceControlAnchor=TOP_LEFT]
* Placement of the default sequence controls.
*
* @property {Number} [initialPage=0]
* If the viewer has been configured with a sequence of tile sources, display this page initially.
*
@ -703,20 +754,26 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
autoResize: true,
//DEFAULT CONTROL SETTINGS
showSequenceControl: true, //SEQUENCE
preserveViewport: false, //SEQUENCE
showNavigationControl: true, //ZOOM/HOME/FULL/SEQUENCE
controlsFadeDelay: 2000, //ZOOM/HOME/FULL/SEQUENCE
controlsFadeLength: 1500, //ZOOM/HOME/FULL/SEQUENCE
mouseNavEnabled: true, //GENERAL MOUSE INTERACTIVITY
showSequenceControl: true, //SEQUENCE
sequenceControlAnchor: null, //SEQUENCE
preserveViewport: false, //SEQUENCE
showNavigationControl: true, //ZOOM/HOME/FULL/SEQUENCE
navigationControlAnchor: null, //ZOOM/HOME/FULL
controlsFadeDelay: 2000, //ZOOM/HOME/FULL/SEQUENCE
controlsFadeLength: 1500, //ZOOM/HOME/FULL/SEQUENCE
mouseNavEnabled: true, //GENERAL MOUSE INTERACTIVITY
//VIEWPORT NAVIGATOR SETTINGS
showNavigator: false,
navigatorId: null,
navigatorHeight: null,
navigatorWidth: null,
navigatorPosition: null,
navigatorSizeRatio: 0.2,
showNavigator: false,
navigatorId: null,
navigatorPosition: null,
navigatorSizeRatio: 0.2,
navigatorMaintainSizeRatio: false,
navigatorTop: null,
navigatorLeft: null,
navigatorHeight: null,
navigatorWidth: null,
navigatorAutoResize: true,
// INITIAL ROTATION
degrees: 0,
@ -775,6 +832,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',
@ -789,6 +858,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
}
},
navPrevNextWrap: false,
showRotationControl: false,
//DEVELOPER SETTINGS
debugMode: false,

View File

@ -35,7 +35,8 @@
(function( $ ){
/**
* An enumeration of positions that an overlay may be assigned relative to the viewport.
* An enumeration of positions that an overlay may be assigned relative to
* the viewport.
* @member OverlayPlacement
* @memberof OpenSeadragon
* @static
@ -69,8 +70,14 @@
* @memberof OpenSeadragon
* @param {Object} options
* @param {Element} options.element
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} options.location
* @param {OpenSeadragon.OverlayPlacement} options.placement - Only used if location is an {@link OpenSeadragon.Point}.
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} options.location - The
* location of the overlay on the image. If a {@link OpenSeadragon.Point}
* is specified, the overlay will keep a constant size independently of the
* zoom. If a {@link OpenSeadragon.Rect} is specified, the overlay size will
* be adjusted when the zoom changes.
* @param {OpenSeadragon.OverlayPlacement} [options.placement=OpenSeadragon.OverlayPlacement.TOP_LEFT]
* Relative position to the viewport.
* Only used if location is a {@link OpenSeadragon.Point}.
* @param {OpenSeadragon.Overlay.OnDrawCallback} options.onDraw
*/
$.Overlay = function( element, location, placement ) {
@ -86,9 +93,9 @@
*/
var options;
if( $.isPlainObject( element ) ){
if ( $.isPlainObject( element ) ) {
options = element;
} else{
} else {
options = {
element: element,
location: location,
@ -174,7 +181,7 @@
element.parentNode.removeChild( element );
//this should allow us to preserve overlays when required between
//pages
if( element.prevElementParent ){
if ( element.prevElementParent ) {
style.display = 'none';
//element.prevElementParent.insertBefore(
// element,
@ -209,9 +216,15 @@
viewport.viewer.drawer.canvas.width / 2,
viewport.viewer.drawer.canvas.height / 2
),
degrees = viewport.degrees,
position,
size,
degrees = viewport.degrees,
position = viewport.pixelFromPoint(
this.bounds.getTopLeft(),
true
),
size = viewport.deltaPixelsFromPoints(
this.bounds.getSize(),
true
),
overlayCenter;
if ( element.parentNode != container ) {
@ -225,8 +238,8 @@
this.size = $.getElementSize( element );
}
position = this.position;
size = this.size;
this.position = position;
this.size = size;
this.adjust( position, size );

View File

@ -76,10 +76,10 @@ $.Point.prototype = /** @lends OpenSeadragon.Point.prototype */{
},
/**
* Add another Point to this point and return a new Point.
* Substract another Point to this point and return a new Point.
* @function
* @param {OpenSeadragon.Point} point The point to add vector components.
* @returns {OpenSeadragon.Point} A new point representing the sum of the
* @param {OpenSeadragon.Point} point The point to substract vector components.
* @returns {OpenSeadragon.Point} A new point representing the substraction of the
* vector components
*/
minus: function( point ) {
@ -90,11 +90,11 @@ $.Point.prototype = /** @lends OpenSeadragon.Point.prototype */{
},
/**
* Add another Point to this point and return a new Point.
* Multiply this point by a factor and return a new Point.
* @function
* @param {OpenSeadragon.Point} point The point to add vector components.
* @returns {OpenSeadragon.Point} A new point representing the sum of the
* vector components
* @param {Number} factor The factor to multiply vector components.
* @returns {OpenSeadragon.Point} A new point representing the multiplication
* of the vector components by the factor
*/
times: function( factor ) {
return new $.Point(
@ -104,11 +104,11 @@ $.Point.prototype = /** @lends OpenSeadragon.Point.prototype */{
},
/**
* Add another Point to this point and return a new Point.
* Divide this point by a factor and return a new Point.
* @function
* @param {OpenSeadragon.Point} point The point to add vector components.
* @returns {OpenSeadragon.Point} A new point representing the sum of the
* vector components
* @param {Number} factor The factor to divide vector components.
* @returns {OpenSeadragon.Point} A new point representing the division of the
* vector components by the factor
*/
divide: function( factor ) {
return new $.Point(
@ -118,10 +118,9 @@ $.Point.prototype = /** @lends OpenSeadragon.Point.prototype */{
},
/**
* Add another Point to this point and return a new Point.
* Compute the opposite of this point and return a new Point.
* @function
* @param {OpenSeadragon.Point} point The point to add vector components.
* @returns {OpenSeadragon.Point} A new point representing the sum of the
* @returns {OpenSeadragon.Point} A new point representing the opposite of the
* vector components
*/
negate: function() {
@ -129,11 +128,10 @@ $.Point.prototype = /** @lends OpenSeadragon.Point.prototype */{
},
/**
* Add another Point to this point and return a new Point.
* Compute the distance between this point and another point.
* @function
* @param {OpenSeadragon.Point} point The point to add vector components.
* @returns {OpenSeadragon.Point} A new point representing the sum of the
* vector components
* @param {OpenSeadragon.Point} point The point to compute the distance with.
* @returns {Number} The distance between the 2 points
*/
distanceTo: function( point ) {
return Math.sqrt(
@ -143,22 +141,21 @@ $.Point.prototype = /** @lends OpenSeadragon.Point.prototype */{
},
/**
* Add another Point to this point and return a new Point.
* Apply a function to each coordinate of this point and return a new point.
* @function
* @param {OpenSeadragon.Point} point The point to add vector components.
* @returns {OpenSeadragon.Point} A new point representing the sum of the
* vector components
* @param {function} func The function to apply to each coordinate.
* @returns {OpenSeadragon.Point} A new point with the coordinates computed
* by the specified function
*/
apply: function( func ) {
return new $.Point( func( this.x ), func( this.y ) );
},
/**
* Add another Point to this point and return a new Point.
* Check if this point is equal to another one.
* @function
* @param {OpenSeadragon.Point} point The point to add vector components.
* @returns {OpenSeadragon.Point} A new point representing the sum of the
* vector components
* @param {OpenSeadragon.Point} point The point to compare this point with.
* @returns {Boolean} true if they are equal, false otherwise.
*/
equals: function( point ) {
return (
@ -186,11 +183,10 @@ $.Point.prototype = /** @lends OpenSeadragon.Point.prototype */{
},
/**
* Add another Point to this point and return a new Point.
* Convert this point to a string in the format (x,y) where x and y are
* rounded to the nearest integer.
* @function
* @param {OpenSeadragon.Point} point The point to add vector components.
* @returns {OpenSeadragon.Point} A new point representing the sum of the
* vector components
* @returns {String} A string representation of this point.
*/
toString: function() {
return "(" + Math.round(this.x) + "," + Math.round(this.y) + ")";

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,
@ -298,7 +303,7 @@ $.Tile.prototype = /** @lends OpenSeadragon.Tile.prototype */{
},
/**
* Removes tile from it's contianer.
* Removes tile from its container.
* @function
*/
unload: function() {

View File

@ -55,7 +55,7 @@
* @param {Number|Object|Array|String} width
* If more than a single argument is supplied, the traditional use of
* positional parameters is supplied and width is expected to be the width
* source image at it's max resolution in pixels. If a single argument is supplied and
* source image at its max resolution in pixels. If a single argument is supplied and
* it is an Object or Array, the construction is assumed to occur through
* the extending classes implementation of 'configure'. Finally if only a
* single argument is supplied and it is a String, the extending class is
@ -93,7 +93,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
}
//Tile sources supply some events, namely 'ready' when they must be configured
//by asyncronously fetching their configuration data.
//by asynchronously fetching their configuration data.
$.EventSource.call( this );
//we allow options to override anything we dont treat as
@ -131,7 +131,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
* @memberof OpenSeadragon.TileSource#
*/
/**
* The overlap in pixels each tile shares with it's adjacent neighbors.
* The overlap in pixels each tile shares with its adjacent neighbors.
* @member {Number} tileOverlap
* @memberof OpenSeadragon.TileSource#
*/
@ -366,7 +366,7 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{
callback: callback
});
} else {
// request info via xhr asyncronously.
// request info via xhr asynchronously.
$.makeAjaxRequest( url, function( xhr ) {
var data = processResponse( xhr );
callback( data );

View File

@ -74,8 +74,7 @@ $.Viewer = function( options ) {
xmlPath: args.length > 1 ? args[ 1 ] : undefined,
prefixUrl: args.length > 2 ? args[ 2 ] : undefined,
controls: args.length > 3 ? args[ 3 ] : undefined,
overlays: args.length > 4 ? args[ 4 ] : undefined,
overlayControls: args.length > 5 ? args[ 5 ] : undefined
overlays: args.length > 4 ? args[ 4 ] : undefined
};
}
@ -127,9 +126,8 @@ $.Viewer = function( options ) {
*/
canvas: null,
//TODO: not sure how to best describe these
overlays: [],
overlayControls:[],
// Overlays list. An overlay allows to add html on top of the viewer.
overlays: [],
//private state properties
previousBody: [],
@ -211,6 +209,7 @@ $.Viewer = function( options ) {
};
this._updateRequestId = null;
this.currentOverlays = [];
//Inherit some behaviors and properties
$.EventSource.call( this );
@ -517,9 +516,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
this.navigator.close();
}
if ( this.drawer ) {
this.drawer.clearOverlays();
}
this.clearOverlays();
this.source = null;
this.drawer = null;
@ -856,6 +853,10 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
}
if ( this.navigator && this.viewport ) {
this.navigator.update( this.viewport );
}
/**
* Raised when the viewer has changed to/from full-page mode (see {@link OpenSeadragon.Viewer#setFullPage}).
*
@ -937,6 +938,9 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
_this.element.style.height = _this.fullPageStyleHeight;
}
}
if ( _this.navigator && _this.viewport ) {
_this.navigator.update( _this.viewport );
}
/**
* Raised when the viewer has changed to/from full-screen mode (see {@link OpenSeadragon.Viewer#setFullScreen}).
*
@ -1318,7 +1322,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
}else{
this.addControl(
this.pagingControl,
{anchor: $.ControlAnchor.TOP_LEFT}
{anchor: this.sequenceControlAnchor || $.ControlAnchor.TOP_LEFT}
);
}
}
@ -1342,6 +1346,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,
@ -1421,6 +1427,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,
@ -1439,7 +1476,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
}else{
this.addControl(
this.navControl,
{anchor: $.ControlAnchor.TOP_LEFT}
{anchor: this.navigationControlAnchor || $.ControlAnchor.TOP_LEFT}
);
}
}
@ -1490,6 +1527,173 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
return this;
},
/**
* Adds an html element as an overlay to the current viewport. Useful for
* highlighting words or areas of interest on an image or other zoomable
* interface. The overlays added via this method are removed when the viewport
* is closed which include when changing page.
* @method
* @param {Element|String|Object} element - A reference to an element or an id for
* the element which will overlayed. Or an Object specifying the configuration for the overlay
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point or
* rectangle which will be overlayed.
* @param {OpenSeadragon.OverlayPlacement} placement - The position of the
* viewport which the location coordinates will be treated as relative
* to.
* @param {function} onDraw - If supplied the callback is called when the overlay
* needs to be drawn. It it the responsibility of the callback to do any drawing/positioning.
* It is passed position, size and element.
* @return {OpenSeadragon.Viewer} Chainable.
* @fires OpenSeadragon.Viewer.event:add-overlay
*/
addOverlay: function( element, location, placement, onDraw ) {
var options;
if( $.isPlainObject( element ) ){
options = element;
} else {
options = {
element: element,
location: location,
placement: placement,
onDraw: onDraw
};
}
element = $.getElement( options.element );
if ( getOverlayIndex( this.currentOverlays, element ) >= 0 ) {
// they're trying to add a duplicate overlay
return this;
}
this.currentOverlays.push( getOverlayObject( this, options ) );
THIS[ this.hash ].forceRedraw = true;
/**
* Raised when an overlay is added to the viewer (see {@link OpenSeadragon.Viewer#addOverlay}).
*
* @event add-overlay
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {Element} element - The overlay element.
* @property {OpenSeadragon.Point|OpenSeadragon.Rect} location
* @property {OpenSeadragon.OverlayPlacement} placement
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.raiseEvent( 'add-overlay', {
element: element,
location: options.location,
placement: options.placement
});
return this;
},
/**
* Updates the overlay represented by the reference to the element or
* element id moving it to the new location, relative to the new placement.
* @method
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point or
* rectangle which will be overlayed.
* @param {OpenSeadragon.OverlayPlacement} placement - The position of the
* viewport which the location coordinates will be treated as relative
* to.
* @return {OpenSeadragon.Viewer} Chainable.
* @fires OpenSeadragon.Viewer.event:update-overlay
*/
updateOverlay: function( element, location, placement ) {
var i;
element = $.getElement( element );
i = getOverlayIndex( this.currentOverlays, element );
if ( i >= 0 ) {
this.currentOverlays[ i ].update( location, placement );
THIS[ this.hash ].forceRedraw = true;
/**
* Raised when an overlay's location or placement changes
* (see {@link OpenSeadragon.Viewer#updateOverlay}).
*
* @event update-overlay
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the
* Viewer which raised the event.
* @property {Element} element
* @property {OpenSeadragon.Point|OpenSeadragon.Rect} location
* @property {OpenSeadragon.OverlayPlacement} placement
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.raiseEvent( 'update-overlay', {
element: element,
location: location,
placement: placement
});
}
return this;
},
/**
* Removes an overlay identified by the reference element or element id
* and schedules an update.
* @method
* @param {Element|String} element - A reference to the element or an
* element id which represent the ovelay content to be removed.
* @return {OpenSeadragon.Viewer} Chainable.
* @fires OpenSeadragon.Viewer.event:remove-overlay
*/
removeOverlay: function( element ) {
var i;
element = $.getElement( element );
i = getOverlayIndex( this.currentOverlays, element );
if ( i >= 0 ) {
this.currentOverlays[ i ].destroy();
this.currentOverlays.splice( i, 1 );
THIS[ this.hash ].forceRedraw = true;
/**
* Raised when an overlay is removed from the viewer
* (see {@link OpenSeadragon.Viewer#removeOverlay}).
*
* @event remove-overlay
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the
* Viewer which raised the event.
* @property {Element} element - The overlay element.
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.raiseEvent( 'remove-overlay', {
element: element
});
}
return this;
},
/**
* Removes all currently configured Overlays from this Viewer and schedules
* an update.
* @method
* @return {OpenSeadragon.Viewer} Chainable.
* @fires OpenSeadragon.Viewer.event:clear-overlay
*/
clearOverlays: function() {
while ( this.currentOverlays.length > 0 ) {
this.currentOverlays.pop().destroy();
}
THIS[ this.hash ].forceRedraw = true;
/**
* Raised when all overlays are removed from the viewer (see {@link OpenSeadragon.Drawer#clearOverlays}).
*
* @event clear-overlay
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
* @property {?Object} userData - Arbitrary subscriber-defined object.
*/
this.raiseEvent( 'clear-overlay', {} );
return this;
},
/**
* Updates the sequence buttons.
* @function OpenSeadragon.Viewer.prototype._updateSequenceButtons
@ -1630,9 +1834,8 @@ function getTileSourceImplementation( viewer, tileSource, successCallback,
* @private
*/
function openTileSource( viewer, source ) {
var _this = viewer,
overlay,
i;
var i,
_this = viewer;
if ( _this.source ) {
_this.close( );
@ -1660,12 +1863,13 @@ 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
});
}else{
} else {
if( source ){
_this.source = source;
}
@ -1682,7 +1886,8 @@ function openTileSource( viewer, source ) {
defaultZoomLevel: _this.defaultZoomLevel,
minZoomLevel: _this.minZoomLevel,
maxZoomLevel: _this.maxZoomLevel,
viewer: _this
viewer: _this,
degrees: _this.degrees
});
}
@ -1697,7 +1902,6 @@ function openTileSource( viewer, source ) {
source: _this.source,
viewport: _this.viewport,
element: _this.canvas,
overlays: [].concat( _this.overlays ).concat( _this.source.overlays ),
opacity: _this.opacity,
maxImageCacheCount: _this.maxImageCacheCount,
imageLoaderLimit: _this.imageLoaderLimit,
@ -1714,6 +1918,21 @@ function openTileSource( viewer, source ) {
});
_this.drawers = [_this.drawer];
// 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
@ -1722,16 +1941,19 @@ function openTileSource( viewer, source ) {
_this.navigator.open( source );
} else {
_this.navigator = new $.Navigator({
id: _this.navigatorId,
position: _this.navigatorPosition,
sizeRatio: _this.navigatorSizeRatio,
height: _this.navigatorHeight,
width: _this.navigatorWidth,
tileSources: source,
tileHost: _this.tileHost,
prefixUrl: _this.prefixUrl,
overlays: _this.overlays,
viewer: _this
id: _this.navigatorId,
position: _this.navigatorPosition,
sizeRatio: _this.navigatorSizeRatio,
maintainSizeRatio: _this.navigatorMaintainSizeRatio,
top: _this.navigatorTop,
left: _this.navigatorLeft,
width: _this.navigatorWidth,
height: _this.navigatorHeight,
autoResize: _this.navigatorAutoResize,
tileSources: source,
tileHost: _this.tileHost,
prefixUrl: _this.prefixUrl,
viewer: _this
});
}
}
@ -1748,7 +1970,6 @@ function openTileSource( viewer, source ) {
tileSources: _this.tileSources,
tileHost: _this.tileHost,
prefixUrl: _this.prefixUrl,
overlays: _this.overlays,
viewer: _this
});
}
@ -1759,40 +1980,10 @@ function openTileSource( viewer, source ) {
THIS[ _this.hash ].forceRedraw = true;
_this._updateRequestId = scheduleUpdate( _this, updateMulti );
//Assuming you had programatically created a bunch of overlays
//and added them via configuration
for ( i = 0; i < _this.overlayControls.length; i++ ) {
overlay = _this.overlayControls[ i ];
if ( overlay.point ) {
_this.drawer.addOverlay(
overlay.id,
new $.Point(
overlay.point.X,
overlay.point.Y
),
$.OverlayPlacement.TOP_LEFT
);
} else {
_this.drawer.addOverlay(
overlay.id,
new $.Rect(
overlay.rect.Point.X,
overlay.rect.Point.Y,
overlay.rect.Width,
overlay.rect.Height
),
overlay.placement
);
}
}
VIEWERS[ _this.hash ] = _this;
loadOverlays( _this );
/**
* Raised when the viewer has opened and loaded one or more TileSources.
*
@ -1808,8 +1999,98 @@ function openTileSource( viewer, source ) {
return _this;
}
function loadOverlays( _this ) {
_this.currentOverlays = [];
for ( var i = 0; i < _this.overlays.length; i++ ) {
_this.currentOverlays[ i ] = getOverlayObject( _this, _this.overlays[ i ] );
}
for ( var j = 0; j < _this.source.overlays.length; j++ ) {
_this.currentOverlays[ i + j ] =
getOverlayObject( _this, _this.source.overlays[ j ] );
}
}
function getOverlayObject( viewer, overlay ) {
if ( overlay instanceof $.Overlay ) {
return overlay;
}
var element = null;
if ( overlay.element ) {
element = $.getElement( overlay.element );
} else {
var id = overlay.id ?
overlay.id :
"openseadragon-overlay-" + Math.floor( Math.random() * 10000000 );
element = $.getElement( overlay.id );
if ( !element ) {
element = document.createElement( "a" );
element.href = "#/overlay/" + id;
}
element.id = id;
$.addClass( element, overlay.className ?
overlay.className :
"openseadragon-overlay"
);
}
var location = overlay.location;
if ( !location ) {
var rect = ( overlay.height && overlay.width ) ? new $.Rect(
overlay.x || overlay.px,
overlay.y || overlay.py,
overlay.width,
overlay.height
) : new $.Point(
overlay.x || overlay.px,
overlay.y || overlay.py
);
if( overlay.px !== undefined ) {
//if they specified 'px' so it's in pixel coordinates so
//we need to translate to viewport coordinates
rect = viewer.viewport.imageToViewportRectangle( rect );
}
location = overlay.placement ? viewer.viewport.pointFromPixel( rect ) :
rect;
}
var placement = overlay.placement;
if ( placement && ( $.type( placement ) === "string" ) ) {
placement = $.OverlayPlacement[ overlay.placement.toUpperCase() ];
}
return new $.Overlay({
element: element,
location: location,
placement: placement,
onDraw: overlay.onDraw
});
}
/**
* @private
* @inner
* Determines the index of the given overlay in the given overlays array.
*/
function getOverlayIndex( overlays, element ) {
var i;
for ( i = overlays.length - 1; i >= 0; i-- ) {
if ( overlays[ i ].element === element ) {
return i;
}
}
return -1;
}
function drawOverlays( viewport, overlays, container ) {
var i,
length = overlays.length;
for ( i = 0; i < length; i++ ) {
overlays[ i ].drawHTML( container, viewport );
}
}
///////////////////////////////////////////////////////////////////////////////
// Schedulers provide the general engine for animation
@ -2183,6 +2464,7 @@ function updateOnce( viewer ) {
if ( animated ) {
updateDrawers( viewer );
drawOverlays( viewer.viewport, viewer.currentOverlays, viewer.canvas );
if( viewer.navigator ){
viewer.navigator.update( viewer.viewport );
}
@ -2198,6 +2480,7 @@ function updateOnce( viewer ) {
viewer.raiseEvent( "animation" );
} else if ( THIS[ viewer.hash ].forceRedraw || drawersNeedUpdate( viewer ) ) {
updateDrawers( viewer );
drawOverlays( viewer.viewport, viewer.currentOverlays, viewer.canvas );
if( viewer.navigator ){
viewer.navigator.update( viewer.viewport );
}
@ -2371,6 +2654,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

@ -920,12 +920,12 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
/**
* Convert pixel coordinates relative to the image to
* viewer element coordinates.
* @param {OpenSeadragon.Point} point
* @param {OpenSeadragon.Point} pixel
* @returns {OpenSeadragon.Point}
*/
imageToViewerElementCoordinates: function( point ) {
var pixel = this.pixelFromPoint( point, true );
return this.imageToViewportCoordinates( pixel );
imageToViewerElementCoordinates: function( pixel ) {
var point = this.imageToViewportCoordinates( pixel );
return this.pixelFromPoint( point, true );
},
/**

View File

@ -0,0 +1,18 @@
{
"profile": "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1",
"height": 870,
"width": 1048,
"qualities": [
"native",
"color",
"grey",
"bitonal"
],
"formats": [
"jpg",
"png",
"gif"
],
"@context": "http://library.stanford.edu/iiif/image-api/1.1/context.json",
"@id": "http://localhost:8000/test/data/iiif_1_1_no_tiles_1048"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 829 B

After

Width:  |  Height:  |  Size: 710 B

View File

@ -0,0 +1,18 @@
{
"profile": "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1",
"height": 212,
"width": 255,
"qualities": [
"native",
"color",
"grey",
"bitonal"
],
"formats": [
"jpg",
"png",
"gif"
],
"@context": "http://library.stanford.edu/iiif/image-api/1.1/context.json",
"@id": "http://localhost:8000/test/data/iiif_1_1_no_tiles_255"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

View File

@ -0,0 +1,18 @@
{
"profile": "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level1",
"height": 319,
"width": 384,
"qualities": [
"native",
"color",
"grey",
"bitonal"
],
"formats": [
"jpg",
"png",
"gif"
],
"@context": "http://library.stanford.edu/iiif/image-api/1.1/context.json",
"@id": "http://localhost:8000/test/data/iiif_1_1_no_tiles_384"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -1,7 +1,7 @@
{
"profile": "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2",
"height": 850,
"width": 1024,
"height": 637,
"width": 768,
"qualities": [
"native",
"color",
@ -14,6 +14,5 @@
"gif"
],
"@context": "http://library.stanford.edu/iiif/image-api/1.1/context.json",
"@id": "http://localhost:8000/test/data/iiif_no_tiles"
"@id": "http://localhost:8000/test/data/iiif_1_1_no_tiles_768"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -24,5 +24,5 @@
"gif"
],
"@context": "http://library.stanford.edu/iiif/image-api/1.1/context.json",
"@id": "http://localhost:8000/test/data/iiif_1_1_files"
"@id": "http://localhost:8000/test/data/iiif_1_1_tiled"
}

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 717 B

After

Width:  |  Height:  |  Size: 717 B

View File

Before

Width:  |  Height:  |  Size: 716 B

After

Width:  |  Height:  |  Size: 716 B

View File

Before

Width:  |  Height:  |  Size: 717 B

After

Width:  |  Height:  |  Size: 717 B

View File

Before

Width:  |  Height:  |  Size: 712 B

After

Width:  |  Height:  |  Size: 712 B

View File

Before

Width:  |  Height:  |  Size: 633 B

After

Width:  |  Height:  |  Size: 633 B

View File

Before

Width:  |  Height:  |  Size: 810 B

After

Width:  |  Height:  |  Size: 810 B

View File

Before

Width:  |  Height:  |  Size: 663 B

After

Width:  |  Height:  |  Size: 663 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 675 B

After

Width:  |  Height:  |  Size: 675 B

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 683 B

After

Width:  |  Height:  |  Size: 683 B

Some files were not shown because too many files have changed in this diff Show More