mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 14:46:10 +03:00
Merge branch 'master' of https://github.com/openseadragon/openseadragon into fullscreen-inputs
This commit is contained in:
commit
a15c8b035f
@ -3,9 +3,16 @@ OPENSEADRAGON CHANGELOG
|
|||||||
|
|
||||||
1.0.1: (in progress)
|
1.0.1: (in progress)
|
||||||
|
|
||||||
|
* BREAKING CHANGE: the openseadragon-canvas element now has two child divs. This means: (#298)
|
||||||
|
* The drawer element is no longer accessible via viewer.canvas.firstChild but via viewer.drawersContainer.firstChild or viewer.drawer.canvas.
|
||||||
|
* The overlays elements are no longer accessible via viewer.canvas.childNodes but via viewer.overlaysContainer.childNodes or viewer.currentOverlays[i].element.
|
||||||
|
* DEPRECATION: overlay functions have been moved from Drawer to Viewer (#331)
|
||||||
|
* Added layers support. Multiple images can now been displayed on top of each other with transparency via the Viewer.addLayer method (#298)
|
||||||
|
* Improved overlay functions (#331)
|
||||||
* Fixed: Nav button highlight states aren't quite aligned on Firefox (#303)
|
* Fixed: Nav button highlight states aren't quite aligned on Firefox (#303)
|
||||||
* Added ControlAnchor options for default controls (#304)
|
* Added ControlAnchor options for default controls (#304)
|
||||||
* Enabled basic cross-domain tile loading without tainting canvas (works in Chrome and Firefox) (#308)
|
* Enabled basic cross-domain tile loading without tainting canvas (works in Chrome and Firefox) (#308)
|
||||||
|
* Added crossOriginPolicy drawer configuration to enable or disable CORS image requests (#364)
|
||||||
* Added a ControlAnchor.ABSOLUTE enumeration. Enables absolute positioning of control elements in the viewer (#310)
|
* 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 '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 a navigatorMaintainSizeRatio option. If set to true, the navigator minimap resizes when the viewer element is resized (#310)
|
||||||
@ -15,6 +22,7 @@ OPENSEADRAGON CHANGELOG
|
|||||||
* Fixed: Setting degrees in Viewer constructor has no effect (#336)
|
* 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 pre-draw event for tiles to allow applications to alter the image (#348)
|
||||||
* Added optional Rotate Left/Right buttons to standard controls (#341)
|
* Added optional Rotate Left/Right buttons to standard controls (#341)
|
||||||
|
* Added optimization for large numbers of overlays: `checkResize = false` option for OpenSeadragon.Overlay (#365)
|
||||||
|
|
||||||
1.0.0:
|
1.0.0:
|
||||||
|
|
||||||
|
267
src/drawer.js
267
src/drawer.js
@ -87,10 +87,10 @@ $.Drawer = function( options ) {
|
|||||||
|
|
||||||
|
|
||||||
//internal state / configurable settings
|
//internal state / configurable settings
|
||||||
overlays: [], // An unordered list of Overlays added.
|
collectionOverlays: {}, // For collection mode. Here an overlay is actually a viewer.
|
||||||
collectionOverlays: {},
|
|
||||||
|
|
||||||
//configurable settings
|
//configurable settings
|
||||||
|
opacity: $.DEFAULT_SETTINGS.opacity,
|
||||||
maxImageCacheCount: $.DEFAULT_SETTINGS.maxImageCacheCount,
|
maxImageCacheCount: $.DEFAULT_SETTINGS.maxImageCacheCount,
|
||||||
imageLoaderLimit: $.DEFAULT_SETTINGS.imageLoaderLimit,
|
imageLoaderLimit: $.DEFAULT_SETTINGS.imageLoaderLimit,
|
||||||
minZoomImageRatio: $.DEFAULT_SETTINGS.minZoomImageRatio,
|
minZoomImageRatio: $.DEFAULT_SETTINGS.minZoomImageRatio,
|
||||||
@ -101,7 +101,8 @@ $.Drawer = function( options ) {
|
|||||||
alwaysBlend: $.DEFAULT_SETTINGS.alwaysBlend,
|
alwaysBlend: $.DEFAULT_SETTINGS.alwaysBlend,
|
||||||
minPixelRatio: $.DEFAULT_SETTINGS.minPixelRatio,
|
minPixelRatio: $.DEFAULT_SETTINGS.minPixelRatio,
|
||||||
debugMode: $.DEFAULT_SETTINGS.debugMode,
|
debugMode: $.DEFAULT_SETTINGS.debugMode,
|
||||||
timeout: $.DEFAULT_SETTINGS.timeout
|
timeout: $.DEFAULT_SETTINGS.timeout,
|
||||||
|
crossOriginPolicy: $.DEFAULT_SETTINGS.crossOriginPolicy
|
||||||
|
|
||||||
}, options );
|
}, options );
|
||||||
|
|
||||||
@ -143,23 +144,12 @@ $.Drawer = function( options ) {
|
|||||||
this.canvas.style.width = "100%";
|
this.canvas.style.width = "100%";
|
||||||
this.canvas.style.height = "100%";
|
this.canvas.style.height = "100%";
|
||||||
this.canvas.style.position = "absolute";
|
this.canvas.style.position = "absolute";
|
||||||
|
$.setElementOpacity( this.canvas, this.opacity, true );
|
||||||
|
|
||||||
// explicit left-align
|
// explicit left-align
|
||||||
this.container.style.textAlign = "left";
|
this.container.style.textAlign = "left";
|
||||||
this.container.appendChild( this.canvas );
|
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();
|
//this.profiler = new $.Profiler();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,53 +171,11 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
|
|||||||
* needs to be drawn. It it the responsibility of the callback to do any drawing/positioning.
|
* needs to be drawn. It it the responsibility of the callback to do any drawing/positioning.
|
||||||
* It is passed position, size and element.
|
* It is passed position, size and element.
|
||||||
* @fires OpenSeadragon.Viewer.event:add-overlay
|
* @fires OpenSeadragon.Viewer.event:add-overlay
|
||||||
|
* @deprecated - use {@link OpenSeadragon.Viewer#addOverlay} instead.
|
||||||
*/
|
*/
|
||||||
addOverlay: function( element, location, placement, onDraw ) {
|
addOverlay: function( element, location, placement, onDraw ) {
|
||||||
var options;
|
$.console.error("drawer.addOverlay is deprecated. Use viewer.addOverlay instead.");
|
||||||
if( $.isPlainObject( element ) ){
|
this.viewer.addOverlay( element, location, placement, onDraw );
|
||||||
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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -242,36 +190,11 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
|
|||||||
* to.
|
* to.
|
||||||
* @return {OpenSeadragon.Drawer} Chainable.
|
* @return {OpenSeadragon.Drawer} Chainable.
|
||||||
* @fires OpenSeadragon.Viewer.event:update-overlay
|
* @fires OpenSeadragon.Viewer.event:update-overlay
|
||||||
|
* @deprecated - use {@link OpenSeadragon.Viewer#updateOverlay} instead.
|
||||||
*/
|
*/
|
||||||
updateOverlay: function( element, location, placement ) {
|
updateOverlay: function( element, location, placement ) {
|
||||||
var i;
|
$.console.error("drawer.updateOverlay is deprecated. Use viewer.updateOverlay instead.");
|
||||||
|
this.viewer.updateOverlay( element, location, placement );
|
||||||
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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -283,33 +206,11 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
|
|||||||
* element id which represent the ovelay content to be removed.
|
* element id which represent the ovelay content to be removed.
|
||||||
* @return {OpenSeadragon.Drawer} Chainable.
|
* @return {OpenSeadragon.Drawer} Chainable.
|
||||||
* @fires OpenSeadragon.Viewer.event:remove-overlay
|
* @fires OpenSeadragon.Viewer.event:remove-overlay
|
||||||
|
* @deprecated - use {@link OpenSeadragon.Viewer#removeOverlay} instead.
|
||||||
*/
|
*/
|
||||||
removeOverlay: function( element ) {
|
removeOverlay: function( element ) {
|
||||||
var i;
|
$.console.error("drawer.removeOverlay is deprecated. Use viewer.removeOverlay instead.");
|
||||||
|
this.viewer.updateOverlay( element );
|
||||||
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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -319,28 +220,34 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
|
|||||||
* @method
|
* @method
|
||||||
* @return {OpenSeadragon.Drawer} Chainable.
|
* @return {OpenSeadragon.Drawer} Chainable.
|
||||||
* @fires OpenSeadragon.Viewer.event:clear-overlay
|
* @fires OpenSeadragon.Viewer.event:clear-overlay
|
||||||
|
* @deprecated - use {@link OpenSeadragon.Viewer#clearOverlays} instead.
|
||||||
*/
|
*/
|
||||||
clearOverlays: function() {
|
clearOverlays: function() {
|
||||||
while ( this.overlays.length > 0 ) {
|
$.console.error("drawer.clearOverlays is deprecated. Use viewer.clearOverlays instead.");
|
||||||
this.overlays.pop().destroy();
|
this.viewer.clearOverlays();
|
||||||
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', {} );
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the opacity of the drawer.
|
||||||
|
* @method
|
||||||
|
* @param {Number} opacity
|
||||||
|
* @return {OpenSeadragon.Drawer} Chainable.
|
||||||
|
*/
|
||||||
|
setOpacity: function( opacity ) {
|
||||||
|
this.opacity = opacity;
|
||||||
|
$.setElementOpacity( this.canvas, this.opacity, true );
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the opacity of the drawer.
|
||||||
|
* @method
|
||||||
|
* @returns {Number}
|
||||||
|
*/
|
||||||
|
getOpacity: function() {
|
||||||
|
return this.opacity;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Returns whether the Drawer is scheduled for an update at the
|
* Returns whether the Drawer is scheduled for an update at the
|
||||||
* soonest possible opportunity.
|
* soonest possible opportunity.
|
||||||
@ -419,7 +326,10 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
|
|||||||
this.downloading++;
|
this.downloading++;
|
||||||
|
|
||||||
image = new Image();
|
image = new Image();
|
||||||
image.crossOrigin = 'Anonymous';
|
|
||||||
|
if (_this.crossOriginPolicy !== false) {
|
||||||
|
image.crossOrigin = _this.crossOriginPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
complete = function( imagesrc, resultingImage ){
|
complete = function( imagesrc, resultingImage ){
|
||||||
_this.downloading--;
|
_this.downloading--;
|
||||||
@ -467,61 +377,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
|
* @private
|
||||||
* @inner
|
* @inner
|
||||||
@ -695,7 +550,6 @@ function updateViewport( drawer ) {
|
|||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
drawTiles( drawer, drawer.lastDrawn );
|
drawTiles( drawer, drawer.lastDrawn );
|
||||||
drawOverlays( drawer.viewport, drawer.overlays, drawer.container );
|
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
if ( best ) {
|
if ( best ) {
|
||||||
@ -1142,23 +996,6 @@ function resetCoverage( coverage, level ) {
|
|||||||
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
|
* @private
|
||||||
* @inner
|
* @inner
|
||||||
@ -1196,28 +1033,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 ){
|
function drawTiles( drawer, lastDrawn ){
|
||||||
var i,
|
var i,
|
||||||
tile,
|
tile,
|
||||||
@ -1297,7 +1112,7 @@ function drawTiles( drawer, lastDrawn ){
|
|||||||
')';
|
')';
|
||||||
}
|
}
|
||||||
|
|
||||||
drawer.addOverlay(
|
drawer.viewer.addOverlay(
|
||||||
viewer.element,
|
viewer.element,
|
||||||
tile.bounds
|
tile.bounds
|
||||||
);
|
);
|
||||||
|
@ -136,6 +136,28 @@
|
|||||||
* is an Array of objects, it is used to create a
|
* is an Array of objects, it is used to create a
|
||||||
* {@link OpenSeadragon.LegacyTileSource}.
|
* {@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]
|
* @property {String} [xmlPath=null]
|
||||||
* <strong>DEPRECATED</strong>. A relative path to load a DZI file from the server.
|
* <strong>DEPRECATED</strong>. A relative path to load a DZI file from the server.
|
||||||
* Prefer the newer Options.tileSources.
|
* Prefer the newer Options.tileSources.
|
||||||
@ -190,6 +212,12 @@
|
|||||||
* Zoom level to use when image is first opened or the home button is clicked.
|
* Zoom level to use when image is first opened or the home button is clicked.
|
||||||
* If 0, adjusts to fit viewer.
|
* If 0, adjusts to fit viewer.
|
||||||
*
|
*
|
||||||
|
* @property {Number} [opacity=1]
|
||||||
|
* Opacity of the drawer (1=opaque, 0=transparent)
|
||||||
|
*
|
||||||
|
* @property {Number} [layersAspectRatioEpsilon=0.0001]
|
||||||
|
* Maximum aspectRatio mismatch between 2 layers.
|
||||||
|
*
|
||||||
* @property {Number} [degrees=0]
|
* @property {Number} [degrees=0]
|
||||||
* Initial rotation.
|
* Initial rotation.
|
||||||
*
|
*
|
||||||
@ -381,6 +409,10 @@
|
|||||||
*
|
*
|
||||||
* @property {Number} [collectionTileSize=800]
|
* @property {Number} [collectionTileSize=800]
|
||||||
*
|
*
|
||||||
|
* @property {String} [crossOriginPolicy='Anonymous']
|
||||||
|
* Valid values are 'Anonymous', 'use-credentials', and false. If false, canvas requests will
|
||||||
|
* not use CORS, and the canvas will be tainted.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -695,6 +727,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
tileSources: null,
|
tileSources: null,
|
||||||
tileHost: null,
|
tileHost: null,
|
||||||
initialPage: 0,
|
initialPage: 0,
|
||||||
|
crossOriginPolicy: 'Anonymous',
|
||||||
|
|
||||||
//PAN AND ZOOM SETTINGS AND CONSTRAINTS
|
//PAN AND ZOOM SETTINGS AND CONSTRAINTS
|
||||||
panHorizontal: true,
|
panHorizontal: true,
|
||||||
@ -750,6 +783,12 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
// INITIAL ROTATION
|
// INITIAL ROTATION
|
||||||
degrees: 0,
|
degrees: 0,
|
||||||
|
|
||||||
|
// APPEARANCE
|
||||||
|
opacity: 1,
|
||||||
|
|
||||||
|
// LAYERS SETTINGS
|
||||||
|
layersAspectRatioEpsilon: 0.0001,
|
||||||
|
|
||||||
//REFERENCE STRIP SETTINGS
|
//REFERENCE STRIP SETTINGS
|
||||||
showReferenceStrip: false,
|
showReferenceStrip: false,
|
||||||
referenceStripScroll: 'horizontal',
|
referenceStripScroll: 'horizontal',
|
||||||
@ -1374,6 +1413,52 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the first index at which an element is found in an array or -1
|
||||||
|
* if not present.
|
||||||
|
*
|
||||||
|
* Code taken and adapted from
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf#Compatibility
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {Array} array The array from which to find the element
|
||||||
|
* @param {Object} searchElement The element to find
|
||||||
|
* @param {Number} [fromIndex=0] Index to start research.
|
||||||
|
* @returns {Number} The index of the element in the array.
|
||||||
|
*/
|
||||||
|
indexOf: function( array, searchElement, fromIndex ) {
|
||||||
|
if ( Array.prototype.indexOf ) {
|
||||||
|
this.indexOf = function( array, searchElement, fromIndex ) {
|
||||||
|
return array.indexOf( searchElement, fromIndex );
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.indexOf = function( array, searchElement, fromIndex ) {
|
||||||
|
var i,
|
||||||
|
pivot = ( fromIndex ) ? fromIndex : 0,
|
||||||
|
length;
|
||||||
|
if ( !array ) {
|
||||||
|
throw new TypeError( );
|
||||||
|
}
|
||||||
|
|
||||||
|
length = array.length;
|
||||||
|
if ( length === 0 || pivot >= length ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pivot < 0 ) {
|
||||||
|
pivot = length - Math.abs( pivot );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = pivot; i < length; i++ ) {
|
||||||
|
if ( array[i] === searchElement ) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return this.indexOf( array, searchElement, fromIndex );
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the specified CSS class from the element.
|
* Remove the specified CSS class from the element.
|
||||||
|
@ -35,7 +35,8 @@
|
|||||||
(function( $ ){
|
(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
|
* @member OverlayPlacement
|
||||||
* @memberof OpenSeadragon
|
* @memberof OpenSeadragon
|
||||||
* @static
|
* @static
|
||||||
@ -69,9 +70,19 @@
|
|||||||
* @memberof OpenSeadragon
|
* @memberof OpenSeadragon
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* @param {Element} options.element
|
* @param {Element} options.element
|
||||||
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} options.location
|
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} options.location - The
|
||||||
* @param {OpenSeadragon.OverlayPlacement} options.placement - Only used if location is an {@link OpenSeadragon.Point}.
|
* location of the overlay on the image. If a {@link OpenSeadragon.Point}
|
||||||
* @param {OpenSeadragon.Overlay.OnDrawCallback} options.onDraw
|
* 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]
|
||||||
|
* @param {Boolean} [options.checkResize=true] Set to false to avoid to
|
||||||
|
* check the size of the overlay everytime it is drawn when using a
|
||||||
|
* {@link OpenSeadragon.Point} as options.location. It will improve
|
||||||
|
* performances but will cause a misalignment if the overlay size changes.
|
||||||
*/
|
*/
|
||||||
$.Overlay = function( element, location, placement ) {
|
$.Overlay = function( element, location, placement ) {
|
||||||
|
|
||||||
@ -86,9 +97,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
var options;
|
var options;
|
||||||
if( $.isPlainObject( element ) ){
|
if ( $.isPlainObject( element ) ) {
|
||||||
options = element;
|
options = element;
|
||||||
} else{
|
} else {
|
||||||
options = {
|
options = {
|
||||||
element: element,
|
element: element,
|
||||||
location: location,
|
location: location,
|
||||||
@ -118,6 +129,8 @@
|
|||||||
options.placement :
|
options.placement :
|
||||||
$.OverlayPlacement.TOP_LEFT;
|
$.OverlayPlacement.TOP_LEFT;
|
||||||
this.onDraw = options.onDraw;
|
this.onDraw = options.onDraw;
|
||||||
|
this.checkResize = options.checkResize === undefined ?
|
||||||
|
true : options.checkResize;
|
||||||
};
|
};
|
||||||
|
|
||||||
$.Overlay.prototype = /** @lends OpenSeadragon.Overlay.prototype */{
|
$.Overlay.prototype = /** @lends OpenSeadragon.Overlay.prototype */{
|
||||||
@ -174,7 +187,7 @@
|
|||||||
element.parentNode.removeChild( element );
|
element.parentNode.removeChild( element );
|
||||||
//this should allow us to preserve overlays when required between
|
//this should allow us to preserve overlays when required between
|
||||||
//pages
|
//pages
|
||||||
if( element.prevElementParent ){
|
if ( element.prevElementParent ) {
|
||||||
style.display = 'none';
|
style.display = 'none';
|
||||||
//element.prevElementParent.insertBefore(
|
//element.prevElementParent.insertBefore(
|
||||||
// element,
|
// element,
|
||||||
@ -205,12 +218,11 @@
|
|||||||
var element = this.element,
|
var element = this.element,
|
||||||
style = this.style,
|
style = this.style,
|
||||||
scales = this.scales,
|
scales = this.scales,
|
||||||
drawerCenter = new $.Point(
|
degrees = viewport.degrees,
|
||||||
viewport.viewer.drawer.canvas.width / 2,
|
position = viewport.pixelFromPoint(
|
||||||
viewport.viewer.drawer.canvas.height / 2
|
this.bounds.getTopLeft(),
|
||||||
|
true
|
||||||
),
|
),
|
||||||
degrees = viewport.degrees,
|
|
||||||
position,
|
|
||||||
size,
|
size,
|
||||||
overlayCenter;
|
overlayCenter;
|
||||||
|
|
||||||
@ -219,14 +231,22 @@
|
|||||||
element.prevElementParent = element.parentNode;
|
element.prevElementParent = element.parentNode;
|
||||||
element.prevNextSibling = element.nextSibling;
|
element.prevNextSibling = element.nextSibling;
|
||||||
container.appendChild( element );
|
container.appendChild( element );
|
||||||
}
|
|
||||||
|
|
||||||
if ( !scales ) {
|
|
||||||
this.size = $.getElementSize( element );
|
this.size = $.getElementSize( element );
|
||||||
}
|
}
|
||||||
|
|
||||||
position = this.position;
|
if ( scales ) {
|
||||||
size = this.size;
|
size = viewport.deltaPixelsFromPoints(
|
||||||
|
this.bounds.getSize(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
} else if ( this.checkResize ) {
|
||||||
|
size = $.getElementSize( element );
|
||||||
|
} else {
|
||||||
|
size = this.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.position = position;
|
||||||
|
this.size = size;
|
||||||
|
|
||||||
this.adjust( position, size );
|
this.adjust( position, size );
|
||||||
|
|
||||||
@ -241,6 +261,10 @@
|
|||||||
if( degrees !== 0 && this.scales ) {
|
if( degrees !== 0 && this.scales ) {
|
||||||
overlayCenter = new $.Point( size.x / 2, size.y / 2 );
|
overlayCenter = new $.Point( size.x / 2, size.y / 2 );
|
||||||
|
|
||||||
|
var drawerCenter = new $.Point(
|
||||||
|
viewport.viewer.drawer.canvas.width / 2,
|
||||||
|
viewport.viewer.drawer.canvas.height / 2
|
||||||
|
);
|
||||||
position = position.plus( overlayCenter ).rotate(
|
position = position.plus( overlayCenter ).rotate(
|
||||||
degrees,
|
degrees,
|
||||||
drawerCenter
|
drawerCenter
|
||||||
@ -250,10 +274,10 @@
|
|||||||
size = new $.Point( Math.abs( size.x ), Math.abs( size.y ) );
|
size = new $.Point( Math.abs( size.x ), Math.abs( size.y ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// call the onDraw callback if there is one to allow, this allows someone to overwrite
|
// call the onDraw callback if it exists to allow one to overwrite
|
||||||
// the drawing/positioning/sizing of the overlay
|
// the drawing/positioning/sizing of the overlay
|
||||||
if (this.onDraw) {
|
if ( this.onDraw ) {
|
||||||
this.onDraw(position, size, element);
|
this.onDraw( position, size, element );
|
||||||
} else {
|
} else {
|
||||||
style.left = position.x + "px";
|
style.left = position.x + "px";
|
||||||
style.top = position.y + "px";
|
style.top = position.y + "px";
|
||||||
|
56
src/point.js
56
src/point.js
@ -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
|
* @function
|
||||||
* @param {OpenSeadragon.Point} point The point to add vector components.
|
* @param {OpenSeadragon.Point} point The point to substract vector components.
|
||||||
* @returns {OpenSeadragon.Point} A new point representing the sum of the
|
* @returns {OpenSeadragon.Point} A new point representing the substraction of the
|
||||||
* vector components
|
* vector components
|
||||||
*/
|
*/
|
||||||
minus: function( point ) {
|
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
|
* @function
|
||||||
* @param {OpenSeadragon.Point} point The point to add vector components.
|
* @param {Number} factor The factor to multiply vector components.
|
||||||
* @returns {OpenSeadragon.Point} A new point representing the sum of the
|
* @returns {OpenSeadragon.Point} A new point representing the multiplication
|
||||||
* vector components
|
* of the vector components by the factor
|
||||||
*/
|
*/
|
||||||
times: function( factor ) {
|
times: function( factor ) {
|
||||||
return new $.Point(
|
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
|
* @function
|
||||||
* @param {OpenSeadragon.Point} point The point to add vector components.
|
* @param {Number} factor The factor to divide vector components.
|
||||||
* @returns {OpenSeadragon.Point} A new point representing the sum of the
|
* @returns {OpenSeadragon.Point} A new point representing the division of the
|
||||||
* vector components
|
* vector components by the factor
|
||||||
*/
|
*/
|
||||||
divide: function( factor ) {
|
divide: function( factor ) {
|
||||||
return new $.Point(
|
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
|
* @function
|
||||||
* @param {OpenSeadragon.Point} point The point to add vector components.
|
* @returns {OpenSeadragon.Point} A new point representing the opposite of the
|
||||||
* @returns {OpenSeadragon.Point} A new point representing the sum of the
|
|
||||||
* vector components
|
* vector components
|
||||||
*/
|
*/
|
||||||
negate: function() {
|
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
|
* @function
|
||||||
* @param {OpenSeadragon.Point} point The point to add vector components.
|
* @param {OpenSeadragon.Point} point The point to compute the distance with.
|
||||||
* @returns {OpenSeadragon.Point} A new point representing the sum of the
|
* @returns {Number} The distance between the 2 points
|
||||||
* vector components
|
|
||||||
*/
|
*/
|
||||||
distanceTo: function( point ) {
|
distanceTo: function( point ) {
|
||||||
return Math.sqrt(
|
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
|
* @function
|
||||||
* @param {OpenSeadragon.Point} point The point to add vector components.
|
* @param {function} func The function to apply to each coordinate.
|
||||||
* @returns {OpenSeadragon.Point} A new point representing the sum of the
|
* @returns {OpenSeadragon.Point} A new point with the coordinates computed
|
||||||
* vector components
|
* by the specified function
|
||||||
*/
|
*/
|
||||||
apply: function( func ) {
|
apply: function( func ) {
|
||||||
return new $.Point( func( this.x ), func( this.y ) );
|
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
|
* @function
|
||||||
* @param {OpenSeadragon.Point} point The point to add vector components.
|
* @param {OpenSeadragon.Point} point The point to compare this point with.
|
||||||
* @returns {OpenSeadragon.Point} A new point representing the sum of the
|
* @returns {Boolean} true if they are equal, false otherwise.
|
||||||
* vector components
|
|
||||||
*/
|
*/
|
||||||
equals: function( point ) {
|
equals: function( point ) {
|
||||||
return (
|
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
|
* @function
|
||||||
* @param {OpenSeadragon.Point} point The point to add vector components.
|
* @returns {String} A string representation of this point.
|
||||||
* @returns {OpenSeadragon.Point} A new point representing the sum of the
|
|
||||||
* vector components
|
|
||||||
*/
|
*/
|
||||||
toString: function() {
|
toString: function() {
|
||||||
return "(" + Math.round(this.x) + "," + Math.round(this.y) + ")";
|
return "(" + Math.round(this.x) + "," + Math.round(this.y) + ")";
|
||||||
|
770
src/viewer.js
770
src/viewer.js
@ -74,8 +74,7 @@ $.Viewer = function( options ) {
|
|||||||
xmlPath: args.length > 1 ? args[ 1 ] : undefined,
|
xmlPath: args.length > 1 ? args[ 1 ] : undefined,
|
||||||
prefixUrl: args.length > 2 ? args[ 2 ] : undefined,
|
prefixUrl: args.length > 2 ? args[ 2 ] : undefined,
|
||||||
controls: args.length > 3 ? args[ 3 ] : undefined,
|
controls: args.length > 3 ? args[ 3 ] : undefined,
|
||||||
overlays: args.length > 4 ? args[ 4 ] : undefined,
|
overlays: args.length > 4 ? args[ 4 ] : undefined
|
||||||
overlayControls: args.length > 5 ? args[ 5 ] : undefined
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,9 +126,10 @@ $.Viewer = function( options ) {
|
|||||||
*/
|
*/
|
||||||
canvas: null,
|
canvas: null,
|
||||||
|
|
||||||
//TODO: not sure how to best describe these
|
// Overlays list. An overlay allows to add html on top of the viewer.
|
||||||
overlays: [],
|
overlays: [],
|
||||||
overlayControls:[],
|
// Container inside the canvas where overlays are drawn.
|
||||||
|
overlaysContainer: null,
|
||||||
|
|
||||||
//private state properties
|
//private state properties
|
||||||
previousBody: [],
|
previousBody: [],
|
||||||
@ -150,8 +150,10 @@ $.Viewer = function( options ) {
|
|||||||
* @member {OpenSeadragon.Drawer} drawer
|
* @member {OpenSeadragon.Drawer} drawer
|
||||||
* @memberof OpenSeadragon.Viewer#
|
* @memberof OpenSeadragon.Viewer#
|
||||||
*/
|
*/
|
||||||
drawer: null,
|
drawer: null,
|
||||||
drawers: [],
|
drawers: [],
|
||||||
|
// Container inside the canvas where drawers (layers) are drawn.
|
||||||
|
drawersContainer: null,
|
||||||
/**
|
/**
|
||||||
* Handles coordinate-related functionality - zoom, pan, rotation, etc. Created for each TileSource opened.
|
* Handles coordinate-related functionality - zoom, pan, rotation, etc. Created for each TileSource opened.
|
||||||
* @member {OpenSeadragon.Viewport} viewport
|
* @member {OpenSeadragon.Viewport} viewport
|
||||||
@ -211,6 +213,7 @@ $.Viewer = function( options ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this._updateRequestId = null;
|
this._updateRequestId = null;
|
||||||
|
this.currentOverlays = [];
|
||||||
|
|
||||||
//Inherit some behaviors and properties
|
//Inherit some behaviors and properties
|
||||||
$.EventSource.call( this );
|
$.EventSource.call( this );
|
||||||
@ -261,6 +264,8 @@ $.Viewer = function( options ) {
|
|||||||
this.element = this.element || document.getElementById( this.id );
|
this.element = this.element || document.getElementById( this.id );
|
||||||
this.canvas = $.makeNeutralElement( "div" );
|
this.canvas = $.makeNeutralElement( "div" );
|
||||||
this.keyboardCommandArea = $.makeNeutralElement( "textarea" );
|
this.keyboardCommandArea = $.makeNeutralElement( "textarea" );
|
||||||
|
this.drawersContainer = $.makeNeutralElement( "div" );
|
||||||
|
this.overlaysContainer = $.makeNeutralElement( "div" );
|
||||||
|
|
||||||
this.canvas.className = "openseadragon-canvas";
|
this.canvas.className = "openseadragon-canvas";
|
||||||
(function( style ){
|
(function( style ){
|
||||||
@ -298,6 +303,8 @@ $.Viewer = function( options ) {
|
|||||||
this.container.insertBefore( this.canvas, this.container.firstChild );
|
this.container.insertBefore( this.canvas, this.container.firstChild );
|
||||||
this.container.insertBefore( this.keyboardCommandArea, this.container.firstChild );
|
this.container.insertBefore( this.keyboardCommandArea, this.container.firstChild );
|
||||||
this.element.appendChild( this.container );
|
this.element.appendChild( this.container );
|
||||||
|
this.canvas.appendChild( this.drawersContainer );
|
||||||
|
this.canvas.appendChild( this.overlaysContainer );
|
||||||
|
|
||||||
//Used for toggling between fullscreen and default container size
|
//Used for toggling between fullscreen and default container size
|
||||||
//TODO: these can be closure private and shared across Viewer
|
//TODO: these can be closure private and shared across Viewer
|
||||||
@ -477,81 +484,26 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
* @fires OpenSeadragon.Viewer.event:open-failed
|
* @fires OpenSeadragon.Viewer.event:open-failed
|
||||||
*/
|
*/
|
||||||
open: function ( tileSource ) {
|
open: function ( tileSource ) {
|
||||||
var _this = this,
|
var _this = this;
|
||||||
customTileSource,
|
|
||||||
readySource,
|
|
||||||
$TileSource,
|
|
||||||
options;
|
|
||||||
|
|
||||||
_this._hideMessage();
|
_this._hideMessage();
|
||||||
|
|
||||||
//allow plain xml strings or json strings to be parsed here
|
getTileSourceImplementation( _this, tileSource, function( tileSource ) {
|
||||||
if( $.type( tileSource ) == 'string' ){
|
openTileSource( _this, tileSource );
|
||||||
if( tileSource.match(/\s*<.*/) ){
|
}, function( event ) {
|
||||||
tileSource = $.parseXml( tileSource );
|
/**
|
||||||
}else if( tileSource.match(/\s*[\{\[].*/) ){
|
* Raised when an error occurs loading a TileSource.
|
||||||
/*jshint evil:true*/
|
*
|
||||||
tileSource = eval( '('+tileSource+')' );
|
* @event open-failed
|
||||||
}
|
* @memberof OpenSeadragon.Viewer
|
||||||
}
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
|
||||||
setTimeout(function(){
|
* @property {String} message
|
||||||
if ( $.type( tileSource ) == 'string') {
|
* @property {String} source
|
||||||
//If its still a string it means it must be a url at this point
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
tileSource = new $.TileSource( tileSource, function( event ){
|
*/
|
||||||
openTileSource( _this, event.tileSource );
|
_this.raiseEvent( 'open-failed', event );
|
||||||
});
|
});
|
||||||
tileSource.addHandler( 'open-failed', function ( event ) {
|
|
||||||
/**
|
|
||||||
* Raised when an error occurs loading a TileSource.
|
|
||||||
*
|
|
||||||
* @event open-failed
|
|
||||||
* @memberof OpenSeadragon.Viewer
|
|
||||||
* @type {object}
|
|
||||||
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
|
|
||||||
* @property {String} message
|
|
||||||
* @property {String} source
|
|
||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
||||||
*/
|
|
||||||
_this.raiseEvent( 'open-failed', event );
|
|
||||||
});
|
|
||||||
|
|
||||||
} else if ( $.isPlainObject( tileSource ) || tileSource.nodeType ){
|
|
||||||
if( $.isFunction( tileSource.getTileUrl ) ){
|
|
||||||
//Custom tile source
|
|
||||||
customTileSource = new $.TileSource(tileSource);
|
|
||||||
customTileSource.getTileUrl = tileSource.getTileUrl;
|
|
||||||
openTileSource( _this, customTileSource );
|
|
||||||
} else {
|
|
||||||
//inline configuration
|
|
||||||
$TileSource = $.TileSource.determineType( _this, tileSource );
|
|
||||||
if ( !$TileSource ) {
|
|
||||||
/***
|
|
||||||
* Raised when an error occurs loading a TileSource.
|
|
||||||
*
|
|
||||||
* @event open-failed
|
|
||||||
* @memberof OpenSeadragon.Viewer
|
|
||||||
* @type {object}
|
|
||||||
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
|
|
||||||
* @property {String} message
|
|
||||||
* @property {String} source
|
|
||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
||||||
*/
|
|
||||||
_this.raiseEvent( 'open-failed', {
|
|
||||||
message: "Unable to load TileSource",
|
|
||||||
source: tileSource
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
options = $TileSource.prototype.configure.apply( _this, [ tileSource ]);
|
|
||||||
readySource = new $TileSource( options );
|
|
||||||
openTileSource( _this, readySource );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//can assume it's already a tile source implementation
|
|
||||||
openTileSource( _this, tileSource );
|
|
||||||
}
|
|
||||||
}, 1);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
@ -572,18 +524,16 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
this.navigator.close();
|
this.navigator.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( this.drawer ) {
|
this.clearOverlays();
|
||||||
this.drawer.clearOverlays();
|
this.drawersContainer.innerHTML = "";
|
||||||
}
|
this.overlaysContainer.innerHTML = "";
|
||||||
|
|
||||||
this.source = null;
|
this.source = null;
|
||||||
this.drawer = null;
|
this.drawer = null;
|
||||||
|
this.drawers = [];
|
||||||
|
|
||||||
this.viewport = this.preserveViewport ? this.viewport : null;
|
this.viewport = this.preserveViewport ? this.viewport : null;
|
||||||
//this.profiler = null;
|
|
||||||
if (this.canvas){
|
|
||||||
this.canvas.innerHTML = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
VIEWERS[ this.hash ] = null;
|
VIEWERS[ this.hash ] = null;
|
||||||
delete VIEWERS[ this.hash ];
|
delete VIEWERS[ this.hash ];
|
||||||
@ -1052,6 +1002,257 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a layer.
|
||||||
|
* options.tileSource can be anything that {@link OpenSeadragon.Viewer#open}
|
||||||
|
* supports except arrays of images as layers cannot be sequences.
|
||||||
|
* @function
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {String|Object|Function} options.tileSource The TileSource of the layer.
|
||||||
|
* @param {Number} [options.opacity=1] The opacity of the layer.
|
||||||
|
* @param {Number} [options.level] The level of the layer. Added on top of
|
||||||
|
* all other layers if not specified.
|
||||||
|
* @returns {OpenSeadragon.Viewer} Chainable.
|
||||||
|
* @fires OpenSeadragon.Viewer.event:add-layer
|
||||||
|
* @fires OpenSeadragon.Viewer.event:add-layer-failed
|
||||||
|
*/
|
||||||
|
addLayer: function( options ) {
|
||||||
|
var _this = this,
|
||||||
|
tileSource = options.tileSource;
|
||||||
|
|
||||||
|
if ( !this.isOpen() ) {
|
||||||
|
throw new Error( "An image must be loaded before adding layers." );
|
||||||
|
}
|
||||||
|
if ( !tileSource ) {
|
||||||
|
throw new Error( "No tile source provided as new layer." );
|
||||||
|
}
|
||||||
|
if ( this.collectionMode ) {
|
||||||
|
throw new Error( "Layers not supported in collection mode." );
|
||||||
|
}
|
||||||
|
|
||||||
|
function raiseAddLayerFailed( event ) {
|
||||||
|
/**
|
||||||
|
* Raised when an error occurs while adding a layer.
|
||||||
|
* @event add-layer-failed
|
||||||
|
* @memberOf OpenSeadragon.Viewer
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
|
||||||
|
* @property {String} message
|
||||||
|
* @property {String} source
|
||||||
|
* @property {Object} options The options passed to the addLayer method.
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
_this.raiseEvent( 'add-layer-failed', event );
|
||||||
|
}
|
||||||
|
|
||||||
|
getTileSourceImplementation( this, tileSource, function( tileSource ) {
|
||||||
|
|
||||||
|
if ( tileSource instanceof Array ) {
|
||||||
|
raiseAddLayerFailed({
|
||||||
|
message: "Sequences can not be added as layers.",
|
||||||
|
source: tileSource,
|
||||||
|
options: options
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( var i = 0; i < _this.drawers.length; i++ ) {
|
||||||
|
var otherAspectRatio = _this.drawers[ i ].source.aspectRatio;
|
||||||
|
var diff = otherAspectRatio - tileSource.aspectRatio;
|
||||||
|
if ( Math.abs( diff ) > _this.layersAspectRatioEpsilon ) {
|
||||||
|
raiseAddLayerFailed({
|
||||||
|
message: "Aspect ratio mismatch with layer " + i + ".",
|
||||||
|
source: tileSource,
|
||||||
|
options: options
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var drawer = new $.Drawer({
|
||||||
|
viewer: _this,
|
||||||
|
source: tileSource,
|
||||||
|
viewport: _this.viewport,
|
||||||
|
element: _this.drawersContainer,
|
||||||
|
opacity: options.opacity !== undefined ?
|
||||||
|
options.opacity : _this.opacity,
|
||||||
|
maxImageCacheCount: _this.maxImageCacheCount,
|
||||||
|
imageLoaderLimit: _this.imageLoaderLimit,
|
||||||
|
minZoomImageRatio: _this.minZoomImageRatio,
|
||||||
|
wrapHorizontal: _this.wrapHorizontal,
|
||||||
|
wrapVertical: _this.wrapVertical,
|
||||||
|
immediateRender: _this.immediateRender,
|
||||||
|
blendTime: _this.blendTime,
|
||||||
|
alwaysBlend: _this.alwaysBlend,
|
||||||
|
minPixelRatio: _this.minPixelRatio,
|
||||||
|
timeout: _this.timeout,
|
||||||
|
debugMode: _this.debugMode,
|
||||||
|
debugGridColor: _this.debugGridColor
|
||||||
|
});
|
||||||
|
_this.drawers.push( drawer );
|
||||||
|
if ( options.level !== undefined ) {
|
||||||
|
_this.setLayerLevel( drawer, options.level );
|
||||||
|
}
|
||||||
|
THIS[ _this.hash ].forceRedraw = true;
|
||||||
|
/**
|
||||||
|
* Raised when a layer is successfully added.
|
||||||
|
* @event add-layer
|
||||||
|
* @memberOf OpenSeadragon.Viewer
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
|
||||||
|
* @property {Object} options The options passed to the addLayer method.
|
||||||
|
* @property {OpenSeadragon.Drawer} drawer The layer's underlying drawer.
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
_this.raiseEvent( 'add-layer', {
|
||||||
|
options: options,
|
||||||
|
drawer: drawer
|
||||||
|
});
|
||||||
|
}, function( event ) {
|
||||||
|
event.options = options;
|
||||||
|
raiseAddLayerFailed(event);
|
||||||
|
} );
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the layer at the specified level.
|
||||||
|
* @param {Number} level The layer to retrieve level.
|
||||||
|
* @returns {OpenSeadragon.Drawer} The layer at the specified level.
|
||||||
|
*/
|
||||||
|
getLayerAtLevel: function( level ) {
|
||||||
|
if ( level >= this.drawers.length ) {
|
||||||
|
throw new Error( "Level bigger than number of layers." );
|
||||||
|
}
|
||||||
|
return this.drawers[ level ];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the level of the layer associated with the given drawer or -1 if not
|
||||||
|
* present.
|
||||||
|
* @param {OpenSeadragon.Drawer} drawer The underlying drawer of the layer.
|
||||||
|
* @returns {Number} The level of the layer or -1 if not present.
|
||||||
|
*/
|
||||||
|
getLevelOfLayer: function( drawer ) {
|
||||||
|
return $.indexOf( this.drawers, drawer );
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of layers used.
|
||||||
|
* @returns {Number} The number of layers used.
|
||||||
|
*/
|
||||||
|
getLayersCount: function() {
|
||||||
|
return this.drawers.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the level of a layer so that it appears over or under others.
|
||||||
|
* @param {OpenSeadragon.Drawer} drawer The underlying drawer of the changing
|
||||||
|
* level layer.
|
||||||
|
* @param {Number} level The new level
|
||||||
|
* @returns {OpenSeadragon.Viewer} Chainable.
|
||||||
|
* @fires OpenSeadragon.Viewer.event:layer-level-changed
|
||||||
|
*/
|
||||||
|
setLayerLevel: function( drawer, level ) {
|
||||||
|
var oldLevel = this.getLevelOfLayer( drawer );
|
||||||
|
|
||||||
|
if ( level >= this.drawers.length ) {
|
||||||
|
throw new Error( "Level bigger than number of layers." );
|
||||||
|
}
|
||||||
|
if ( level === oldLevel || oldLevel === -1 ) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
if ( level === 0 || oldLevel === 0 ) {
|
||||||
|
if ( THIS[ this.hash ].sequenced ) {
|
||||||
|
throw new Error( "Cannot reassign base level when in sequence mode." );
|
||||||
|
}
|
||||||
|
// We need to re-assign the base drawer and the source
|
||||||
|
this.drawer = level === 0 ? drawer : this.getLayerAtLevel( level );
|
||||||
|
this.source = this.drawer.source;
|
||||||
|
}
|
||||||
|
this.drawers.splice( oldLevel, 1 );
|
||||||
|
this.drawers.splice( level, 0, drawer );
|
||||||
|
this.drawersContainer.removeChild( drawer.canvas );
|
||||||
|
if ( level === 0 ) {
|
||||||
|
var nextLevelCanvas = this.drawers[ 1 ].canvas;
|
||||||
|
nextLevelCanvas.parentNode.insertBefore( drawer.canvas,
|
||||||
|
nextLevelCanvas );
|
||||||
|
} else {
|
||||||
|
// Insert right after layer at level - 1
|
||||||
|
var prevLevelCanvas = this.drawers[level - 1].canvas;
|
||||||
|
prevLevelCanvas.parentNode.insertBefore( drawer.canvas,
|
||||||
|
prevLevelCanvas.nextSibling );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raised when the order of the layers has been changed.
|
||||||
|
* @event layer-level-changed
|
||||||
|
* @memberOf OpenSeadragon.Viewer
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
|
||||||
|
* @property {OpenSeadragon.Drawer} drawer - The drawer which level has
|
||||||
|
* been changed
|
||||||
|
* @property {Number} previousLevel - The previous level of the drawer
|
||||||
|
* @property {Number} newLevel - The new level of the drawer
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
this.raiseEvent( 'layer-level-changed', {
|
||||||
|
drawer: drawer,
|
||||||
|
previousLevel: oldLevel,
|
||||||
|
newLevel: level
|
||||||
|
} );
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a layer. If there is only one layer, close the viewer.
|
||||||
|
* @function
|
||||||
|
* @param {OpenSeadragon.Drawer} drawer The underlying drawer of the layer
|
||||||
|
* to remove
|
||||||
|
* @returns {OpenSeadragon.Viewer} Chainable.
|
||||||
|
* @fires OpenSeadragon.Viewer.event:remove-layer
|
||||||
|
*/
|
||||||
|
removeLayer: function( drawer ) {
|
||||||
|
var index = this.drawers.indexOf( drawer );
|
||||||
|
if ( index === -1 ) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
if ( index === 0 ) {
|
||||||
|
if ( THIS[ this.hash ].sequenced ) {
|
||||||
|
throw new Error( "Cannot remove base layer when in sequence mode." );
|
||||||
|
}
|
||||||
|
if ( this.drawers.length === 1 ) {
|
||||||
|
this.close();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.drawer = this.drawers[ 1 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.drawers.splice( index, 1 );
|
||||||
|
this.drawersContainer.removeChild( drawer.canvas );
|
||||||
|
/**
|
||||||
|
* Raised when a layer is removed.
|
||||||
|
* @event remove-layer
|
||||||
|
* @memberOf OpenSeadragon.Viewer
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
|
||||||
|
* @property {OpenSeadragon.Drawer} drawer The layer's underlying drawer.
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
this.raiseEvent( 'remove-layer', { drawer: drawer } );
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force the viewer to redraw its drawers.
|
||||||
|
* @returns {OpenSeadragon.Viewer} Chainable.
|
||||||
|
*/
|
||||||
|
forceRedraw: function() {
|
||||||
|
THIS[ this.hash ].forceRedraw = true;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@ -1334,6 +1535,173 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
return this;
|
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.
|
* Updates the sequence buttons.
|
||||||
* @function OpenSeadragon.Viewer.prototype._updateSequenceButtons
|
* @function OpenSeadragon.Viewer.prototype._updateSequenceButtons
|
||||||
@ -1414,20 +1782,73 @@ function _getSafeElemSize (oElement) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
function getTileSourceImplementation( viewer, tileSource, successCallback,
|
||||||
|
failCallback ) {
|
||||||
|
var _this = viewer;
|
||||||
|
|
||||||
|
//allow plain xml strings or json strings to be parsed here
|
||||||
|
if ( $.type( tileSource ) == 'string' ) {
|
||||||
|
if ( tileSource.match( /\s*<.*/ ) ) {
|
||||||
|
tileSource = $.parseXml( tileSource );
|
||||||
|
} else if ( tileSource.match( /\s*[\{\[].*/ ) ) {
|
||||||
|
/*jshint evil:true*/
|
||||||
|
tileSource = eval( '(' + tileSource + ')' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout( function() {
|
||||||
|
if ( $.type( tileSource ) == 'string' ) {
|
||||||
|
//If its still a string it means it must be a url at this point
|
||||||
|
tileSource = new $.TileSource( tileSource, function( event ) {
|
||||||
|
successCallback( event.tileSource );
|
||||||
|
});
|
||||||
|
tileSource.addHandler( 'open-failed', function( event ) {
|
||||||
|
failCallback( event );
|
||||||
|
} );
|
||||||
|
|
||||||
|
} else if ( $.isPlainObject( tileSource ) || tileSource.nodeType ) {
|
||||||
|
if ( $.isFunction( tileSource.getTileUrl ) ) {
|
||||||
|
//Custom tile source
|
||||||
|
var customTileSource = new $.TileSource( tileSource );
|
||||||
|
customTileSource.getTileUrl = tileSource.getTileUrl;
|
||||||
|
successCallback( customTileSource );
|
||||||
|
} else {
|
||||||
|
//inline configuration
|
||||||
|
var $TileSource = $.TileSource.determineType( _this, tileSource );
|
||||||
|
if ( !$TileSource ) {
|
||||||
|
failCallback( {
|
||||||
|
message: "Unable to load TileSource",
|
||||||
|
source: tileSource
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var options = $TileSource.prototype.configure.apply( _this, [ tileSource ] );
|
||||||
|
var readySource = new $TileSource( options );
|
||||||
|
successCallback( readySource );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//can assume it's already a tile source implementation
|
||||||
|
successCallback( tileSource );
|
||||||
|
}
|
||||||
|
}, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function openTileSource( viewer, source ) {
|
function openTileSource( viewer, source ) {
|
||||||
var _this = viewer,
|
var i,
|
||||||
overlay,
|
_this = viewer;
|
||||||
i;
|
|
||||||
|
|
||||||
if ( _this.source ) {
|
if ( _this.source ) {
|
||||||
_this.close( );
|
_this.close( );
|
||||||
}
|
}
|
||||||
|
|
||||||
_this.canvas.innerHTML = "";
|
|
||||||
THIS[ _this.hash ].prevContainerSize = _getSafeElemSize( _this.container );
|
THIS[ _this.hash ].prevContainerSize = _getSafeElemSize( _this.container );
|
||||||
|
|
||||||
|
|
||||||
@ -1455,7 +1876,7 @@ function openTileSource( viewer, source ) {
|
|||||||
//minZoomLevel: this.minZoomLevel,
|
//minZoomLevel: this.minZoomLevel,
|
||||||
//maxZoomLevel: this.maxZoomLevel
|
//maxZoomLevel: this.maxZoomLevel
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
if( source ){
|
if( source ){
|
||||||
_this.source = source;
|
_this.source = source;
|
||||||
}
|
}
|
||||||
@ -1487,8 +1908,8 @@ function openTileSource( viewer, source ) {
|
|||||||
viewer: _this,
|
viewer: _this,
|
||||||
source: _this.source,
|
source: _this.source,
|
||||||
viewport: _this.viewport,
|
viewport: _this.viewport,
|
||||||
element: _this.canvas,
|
element: _this.drawersContainer,
|
||||||
overlays: [].concat( _this.overlays ).concat( _this.source.overlays ),
|
opacity: _this.opacity,
|
||||||
maxImageCacheCount: _this.maxImageCacheCount,
|
maxImageCacheCount: _this.maxImageCacheCount,
|
||||||
imageLoaderLimit: _this.imageLoaderLimit,
|
imageLoaderLimit: _this.imageLoaderLimit,
|
||||||
minZoomImageRatio: _this.minZoomImageRatio,
|
minZoomImageRatio: _this.minZoomImageRatio,
|
||||||
@ -1500,8 +1921,10 @@ function openTileSource( viewer, source ) {
|
|||||||
minPixelRatio: _this.collectionMode ? 0 : _this.minPixelRatio,
|
minPixelRatio: _this.collectionMode ? 0 : _this.minPixelRatio,
|
||||||
timeout: _this.timeout,
|
timeout: _this.timeout,
|
||||||
debugMode: _this.debugMode,
|
debugMode: _this.debugMode,
|
||||||
debugGridColor: _this.debugGridColor
|
debugGridColor: _this.debugGridColor,
|
||||||
|
crossOriginPolicy: _this.crossOriginPolicy
|
||||||
});
|
});
|
||||||
|
_this.drawers = [_this.drawer];
|
||||||
|
|
||||||
// Now that we have a drawer, see if it supports rotate. If not we need to remove the rotate buttons
|
// Now that we have a drawer, see if it supports rotate. If not we need to remove the rotate buttons
|
||||||
if (!_this.drawer.canRotate()) {
|
if (!_this.drawer.canRotate()) {
|
||||||
@ -1538,7 +1961,6 @@ function openTileSource( viewer, source ) {
|
|||||||
tileSources: source,
|
tileSources: source,
|
||||||
tileHost: _this.tileHost,
|
tileHost: _this.tileHost,
|
||||||
prefixUrl: _this.prefixUrl,
|
prefixUrl: _this.prefixUrl,
|
||||||
overlays: _this.overlays,
|
|
||||||
viewer: _this
|
viewer: _this
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1556,7 +1978,6 @@ function openTileSource( viewer, source ) {
|
|||||||
tileSources: _this.tileSources,
|
tileSources: _this.tileSources,
|
||||||
tileHost: _this.tileHost,
|
tileHost: _this.tileHost,
|
||||||
prefixUrl: _this.prefixUrl,
|
prefixUrl: _this.prefixUrl,
|
||||||
overlays: _this.overlays,
|
|
||||||
viewer: _this
|
viewer: _this
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1567,40 +1988,10 @@ function openTileSource( viewer, source ) {
|
|||||||
THIS[ _this.hash ].forceRedraw = true;
|
THIS[ _this.hash ].forceRedraw = true;
|
||||||
_this._updateRequestId = scheduleUpdate( _this, updateMulti );
|
_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;
|
VIEWERS[ _this.hash ] = _this;
|
||||||
|
|
||||||
|
loadOverlays( _this );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raised when the viewer has opened and loaded one or more TileSources.
|
* Raised when the viewer has opened and loaded one or more TileSources.
|
||||||
*
|
*
|
||||||
@ -1616,8 +2007,108 @@ function openTileSource( viewer, source ) {
|
|||||||
return _this;
|
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 ) {
|
||||||
|
if ( overlay.width && overlay.height ) {
|
||||||
|
location = overlay.px !== undefined ?
|
||||||
|
viewer.viewport.imageToViewportRectangle( new $.Rect(
|
||||||
|
overlay.px,
|
||||||
|
overlay.py,
|
||||||
|
overlay.width,
|
||||||
|
overlay.height
|
||||||
|
) ) :
|
||||||
|
new $.Rect(
|
||||||
|
overlay.x,
|
||||||
|
overlay.y,
|
||||||
|
overlay.width,
|
||||||
|
overlay.height
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
location = overlay.px !== undefined ?
|
||||||
|
viewer.viewport.imageToViewportCoordinates( new $.Point(
|
||||||
|
overlay.px,
|
||||||
|
overlay.py
|
||||||
|
) ) :
|
||||||
|
new $.Point(
|
||||||
|
overlay.x,
|
||||||
|
overlay.y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
checkResize: overlay.checkResize
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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
|
// Schedulers provide the general engine for animation
|
||||||
@ -1990,7 +2481,8 @@ function updateOnce( viewer ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( animated ) {
|
if ( animated ) {
|
||||||
viewer.drawer.update();
|
updateDrawers( viewer );
|
||||||
|
drawOverlays( viewer.viewport, viewer.currentOverlays, viewer.overlaysContainer );
|
||||||
if( viewer.navigator ){
|
if( viewer.navigator ){
|
||||||
viewer.navigator.update( viewer.viewport );
|
viewer.navigator.update( viewer.viewport );
|
||||||
}
|
}
|
||||||
@ -2004,8 +2496,9 @@ function updateOnce( viewer ) {
|
|||||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
*/
|
*/
|
||||||
viewer.raiseEvent( "animation" );
|
viewer.raiseEvent( "animation" );
|
||||||
} else if ( THIS[ viewer.hash ].forceRedraw || viewer.drawer.needsUpdate() ) {
|
} else if ( THIS[ viewer.hash ].forceRedraw || drawersNeedUpdate( viewer ) ) {
|
||||||
viewer.drawer.update();
|
updateDrawers( viewer );
|
||||||
|
drawOverlays( viewer.viewport, viewer.currentOverlays, viewer.overlaysContainer );
|
||||||
if( viewer.navigator ){
|
if( viewer.navigator ){
|
||||||
viewer.navigator.update( viewer.viewport );
|
viewer.navigator.update( viewer.viewport );
|
||||||
}
|
}
|
||||||
@ -2059,6 +2552,21 @@ function resizeViewportAndRecenter( viewer, containerSize, oldBounds, oldCenter
|
|||||||
viewport.fitBounds( newBounds, true );
|
viewport.fitBounds( newBounds, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateDrawers( viewer ) {
|
||||||
|
for (var i = 0; i < viewer.drawers.length; i++ ) {
|
||||||
|
viewer.drawers[i].update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawersNeedUpdate( viewer ) {
|
||||||
|
for (var i = 0; i < viewer.drawers.length; i++ ) {
|
||||||
|
if (viewer.drawers[i].needsUpdate()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Navigation Controls
|
// Navigation Controls
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -652,7 +652,7 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
|
|||||||
throw new Error('Currently only 0, 90, 180, and 270 degrees are supported.');
|
throw new Error('Currently only 0, 90, 180, and 270 degrees are supported.');
|
||||||
}
|
}
|
||||||
this.degrees = degrees;
|
this.degrees = degrees;
|
||||||
this.viewer.drawer.update();
|
this.viewer.forceRedraw();
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
@ -920,12 +920,12 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
|
|||||||
/**
|
/**
|
||||||
* Convert pixel coordinates relative to the image to
|
* Convert pixel coordinates relative to the image to
|
||||||
* viewer element coordinates.
|
* viewer element coordinates.
|
||||||
* @param {OpenSeadragon.Point} point
|
* @param {OpenSeadragon.Point} pixel
|
||||||
* @returns {OpenSeadragon.Point}
|
* @returns {OpenSeadragon.Point}
|
||||||
*/
|
*/
|
||||||
imageToViewerElementCoordinates: function( point ) {
|
imageToViewerElementCoordinates: function( pixel ) {
|
||||||
var pixel = this.pixelFromPoint( point, true );
|
var point = this.imageToViewportCoordinates( pixel );
|
||||||
return this.imageToViewportCoordinates( pixel );
|
return this.pixelFromPoint( point, true );
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
BIN
test/data/A.png
Normal file
BIN
test/data/A.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
test/data/BBlue.png
Normal file
BIN
test/data/BBlue.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
test/data/CCyan.png
Normal file
BIN
test/data/CCyan.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
test/data/DDandelion.png
Normal file
BIN
test/data/DDandelion.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.5 KiB |
194
test/demo/layers.html
Normal file
194
test/demo/layers.html
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>OpenSeadragon Layers Demo</title>
|
||||||
|
<script type="text/javascript" src='../../build/openseadragon/openseadragon.js'></script>
|
||||||
|
<script type="text/javascript" src='../lib/jquery-1.9.1.min.js'></script>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
.openseadragon1 {
|
||||||
|
width: 800px;
|
||||||
|
height: 600px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#availables, #arrows, #left, #updown, #right {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
Simple demo page to show an OpenSeadragon viewer with layers.
|
||||||
|
</div>
|
||||||
|
<div id="contentDiv" class="openseadragon1"></div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div id="availables">
|
||||||
|
Available layers<br>
|
||||||
|
<select name="layers-availables" size="4" multiple="multiple">
|
||||||
|
<option>CCyan</option>
|
||||||
|
<option>DDandelion</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div id="arrows">
|
||||||
|
<div id="left">
|
||||||
|
<button onclick="left();">⇚ Remove</button>
|
||||||
|
</div>
|
||||||
|
<div id="updown">
|
||||||
|
<div id="up">
|
||||||
|
<button onclick="up();">⇑ Up</button>
|
||||||
|
</div>
|
||||||
|
<div id="down">
|
||||||
|
<button onclick="down();">⇓ Down</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="right">
|
||||||
|
<button onclick="right();">⇛ Add</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="used">
|
||||||
|
Used layers<br>
|
||||||
|
<select name="layers-used" size="4" multiple="multiple">
|
||||||
|
<option>A</option>
|
||||||
|
<option>BBlue</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br><br><br><br>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Opacity: <br>
|
||||||
|
<label for="AOpacity" >A</label>
|
||||||
|
<input id="AOpacity" type="text" value="0.5"><br>
|
||||||
|
<label for="BBlueOpacity" >BBlue</label>
|
||||||
|
<input id="BBlueOpacity" type="text" value="1"><br>
|
||||||
|
<label for="CCyanOpacity" >CCyan</label>
|
||||||
|
<input id="CCyanOpacity" type="text" value="1"><br>
|
||||||
|
<label for="DDandelion" >DDandelion</label>
|
||||||
|
<input id="DDandelion" type="text" value="1"><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br><br><br><br>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button onclick="rotate();">Rotate</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
function getOpacity( layerName ) {
|
||||||
|
var id = $( "label" ).filter( function( index ) {
|
||||||
|
return layerName === this.innerHTML;
|
||||||
|
} ).attr( "for" );
|
||||||
|
return $( "#" + id ).val();
|
||||||
|
}
|
||||||
|
|
||||||
|
function right() {
|
||||||
|
var added = $( "#availables select option:selected" ).detach();
|
||||||
|
$( "#used select" ).append( added );
|
||||||
|
$.each( added, function( index, value ) {
|
||||||
|
addLayer( value.innerHTML );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
function addLayer( layerName ) {
|
||||||
|
var options = {
|
||||||
|
tileSource: {
|
||||||
|
type: 'legacy-image-pyramid',
|
||||||
|
levels: [ {
|
||||||
|
url: "../data/" + layerName + ".png",
|
||||||
|
width: 1000,
|
||||||
|
height: 1000
|
||||||
|
} ]
|
||||||
|
},
|
||||||
|
opacity: getOpacity( layerName )
|
||||||
|
};
|
||||||
|
var addLayerHandler = function( event ) {
|
||||||
|
if ( event.options === options ) {
|
||||||
|
viewer.removeHandler( "add-layer", addLayerHandler );
|
||||||
|
layers[layerName] = event.drawer;
|
||||||
|
updateOrder();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
viewer.addHandler( "add-layer", addLayerHandler );
|
||||||
|
viewer.addLayer( options );
|
||||||
|
}
|
||||||
|
|
||||||
|
function left() {
|
||||||
|
var removed = $( "#used select option:selected" ).detach();
|
||||||
|
$( "#availables select" ).append( removed );
|
||||||
|
$.each( removed, function( index, value ) {
|
||||||
|
var layer = value.innerHTML;
|
||||||
|
viewer.removeLayer( layers[layer] );
|
||||||
|
delete layers[layer];
|
||||||
|
updateOrder();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
function up() {
|
||||||
|
$.each( $( "#used select option:selected" ), function( index, value ) {
|
||||||
|
$( value ).prev( "option" ).insertAfter( value );
|
||||||
|
} );
|
||||||
|
updateOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
function down() {
|
||||||
|
$.each( $( "#used select option:selected" ).get().reverse(),
|
||||||
|
function( index, value ) {
|
||||||
|
$( value ).next( "option" ).insertBefore( value );
|
||||||
|
} );
|
||||||
|
updateOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateOrder() {
|
||||||
|
var nbLayers = viewer.getLayersCount();
|
||||||
|
if ( nbLayers < 2 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.each( $( "#used select option" ), function( index, value ) {
|
||||||
|
var layer = value.innerHTML;
|
||||||
|
viewer.setLayerLevel( layers[layer], nbLayers -1 - index );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
function rotate() {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
viewport.setRotation( viewport.getRotation() + 90 );
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewer = OpenSeadragon( {
|
||||||
|
id: "contentDiv",
|
||||||
|
prefixUrl: "../../build/openseadragon/images/",
|
||||||
|
tileSources: "../data/testpattern.dzi",
|
||||||
|
showNavigator: true
|
||||||
|
} );
|
||||||
|
viewer.addHandler( "open", function() {
|
||||||
|
$.each( $( "#used select option" ), function( index, value ) {
|
||||||
|
var layer = value.innerHTML;
|
||||||
|
addLayer( layer );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
var layers = { };
|
||||||
|
|
||||||
|
$( "input" ).keyup( function( event ) {
|
||||||
|
var elt = event.target;
|
||||||
|
var layerName = $( "label" ).filter( function( index ) {
|
||||||
|
return $( this ).attr( "for" ) === elt.id;
|
||||||
|
} ).html();
|
||||||
|
|
||||||
|
var layer = layers[layerName];
|
||||||
|
if ( layer ) {
|
||||||
|
var opacity = $(elt).val();
|
||||||
|
layer.setOpacity( opacity );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
278
test/layers.js
Normal file
278
test/layers.js
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */
|
||||||
|
|
||||||
|
( function() {
|
||||||
|
var viewer;
|
||||||
|
|
||||||
|
module( 'Layers', {
|
||||||
|
setup: function() {
|
||||||
|
$( '<div id="layersexample"></div>' ).appendTo( "#qunit-fixture" );
|
||||||
|
|
||||||
|
testLog.reset();
|
||||||
|
|
||||||
|
viewer = OpenSeadragon( {
|
||||||
|
id: 'layersexample',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
springStiffness: 100 // Faster animation = faster tests
|
||||||
|
});
|
||||||
|
},
|
||||||
|
teardown: function() {
|
||||||
|
if ( viewer && viewer.close ) {
|
||||||
|
viewer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
viewer = null;
|
||||||
|
$( "#layersexample" ).remove();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
asyncTest( 'Layers operations', function() {
|
||||||
|
expect( 23 );
|
||||||
|
viewer.addHandler( "open", function( ) {
|
||||||
|
equal( 1, viewer.getLayersCount( ),
|
||||||
|
"One layer should be present after opening." );
|
||||||
|
var options = {
|
||||||
|
tileSource: {
|
||||||
|
type: 'legacy-image-pyramid',
|
||||||
|
levels: [ {
|
||||||
|
url: "data/A.png",
|
||||||
|
width: 1000,
|
||||||
|
height: 1000
|
||||||
|
} ]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
viewer.addLayer( options );
|
||||||
|
viewer.addHandler( "add-layer", function addFirstLayerHandler( event ) {
|
||||||
|
viewer.removeHandler( "add-layer", addFirstLayerHandler );
|
||||||
|
var layer1 = event.drawer;
|
||||||
|
equal( viewer.getLayersCount( ), 2,
|
||||||
|
"2 layers should be present after adding a layer." );
|
||||||
|
equal( options, event.options,
|
||||||
|
"The options should be transmitted via the event." );
|
||||||
|
equal( viewer.getLevelOfLayer( layer1 ), 1,
|
||||||
|
"The first added layer should have a level of 1" );
|
||||||
|
equal( viewer.getLayerAtLevel( 1 ), layer1,
|
||||||
|
"The layer at level 1 should be the first added layer." );
|
||||||
|
|
||||||
|
viewer.addLayer( options );
|
||||||
|
viewer.addHandler( "add-layer", function addSecondLayerHandler( event ) {
|
||||||
|
viewer.removeHandler( "add-layer", addSecondLayerHandler );
|
||||||
|
var layer2 = event.drawer;
|
||||||
|
equal( viewer.getLayersCount( ), 3,
|
||||||
|
"3 layers should be present after adding a second layer." );
|
||||||
|
equal( viewer.getLevelOfLayer( layer2 ), 2,
|
||||||
|
"If not specified, a layer should be added with the highest level." );
|
||||||
|
equal( viewer.getLayerAtLevel( 2 ), layer2,
|
||||||
|
"The layer at level 2 should be the second added layer." );
|
||||||
|
|
||||||
|
viewer.addHandler( "layer-level-changed",
|
||||||
|
function layerLevelChangedHandler( event ) {
|
||||||
|
viewer.removeHandler( "layer-level-changed",
|
||||||
|
layerLevelChangedHandler );
|
||||||
|
equal( event.drawer, layer2,
|
||||||
|
"The layer which changed level should be layer2" );
|
||||||
|
equal( event.previousLevel, 2, "Previous level should be 2." );
|
||||||
|
equal( event.newLevel, 1, "New level should be 1." );
|
||||||
|
});
|
||||||
|
viewer.setLayerLevel( layer2, 1 );
|
||||||
|
equal( viewer.getLevelOfLayer( layer2 ), 1,
|
||||||
|
"Layer2 level should be 1 after setLayerLevel." );
|
||||||
|
equal( viewer.getLevelOfLayer( layer1 ), 2,
|
||||||
|
"Layer1 level should be 2 after setLayerLevel." );
|
||||||
|
equal( viewer.getLayerAtLevel( 1 ), layer2,
|
||||||
|
"The layer at level 1 should be layer2." );
|
||||||
|
equal( viewer.getLayerAtLevel( 2 ), layer1,
|
||||||
|
"The layer at level 2 should be layer1." );
|
||||||
|
|
||||||
|
options.level = 2;
|
||||||
|
options.tileSource.levels[0].url = "data/CCyan.png";
|
||||||
|
options.opacity = 0.5;
|
||||||
|
viewer.addLayer( options );
|
||||||
|
viewer.addHandler( "add-layer", function addThirdLayerHandler( event ) {
|
||||||
|
viewer.removeHandler( "add-layer", addThirdLayerHandler );
|
||||||
|
var layer3 = event.drawer;
|
||||||
|
equal( viewer.getLayersCount( ), 4,
|
||||||
|
"4 layers should be present after adding a third layer." );
|
||||||
|
equal( viewer.getLevelOfLayer( layer3 ), 2,
|
||||||
|
"Layer 3 should be added with level 2." );
|
||||||
|
equal( viewer.getLevelOfLayer( layer2 ), 1,
|
||||||
|
"Layer 2 should stay at level 1." );
|
||||||
|
|
||||||
|
viewer.addHandler( "remove-layer", function removeLayerHandler( event ) {
|
||||||
|
viewer.removeHandler( "remove-layer", removeLayerHandler );
|
||||||
|
|
||||||
|
equal( layer2, event.drawer, "Removed layer should be layer2." );
|
||||||
|
|
||||||
|
equal( viewer.getLevelOfLayer( layer1 ), 2,
|
||||||
|
"Layer 1 should be at level 2." );
|
||||||
|
equal( viewer.getLevelOfLayer( layer2 ), -1,
|
||||||
|
"Layer 2 should be at level -1." );
|
||||||
|
equal( viewer.getLevelOfLayer( layer3 ), 1,
|
||||||
|
"Layer 3 should be at level 1." );
|
||||||
|
|
||||||
|
});
|
||||||
|
viewer.removeLayer( layer2 );
|
||||||
|
|
||||||
|
options.tileSource.levels[0].width = 500;
|
||||||
|
viewer.addHandler( "add-layer-failed", function addLayerFailed( event ) {
|
||||||
|
viewer.removeHandler( "add-layer-failed", addLayerFailed );
|
||||||
|
|
||||||
|
equal( viewer.getLayersCount(), 3 );
|
||||||
|
|
||||||
|
start();
|
||||||
|
});
|
||||||
|
viewer.addLayer( options );
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
viewer.open( '/test/data/testpattern.dzi' );
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest( 'Sequences as layers', function() {
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
tileSource: [{
|
||||||
|
type: 'legacy-image-pyramid',
|
||||||
|
levels: [{
|
||||||
|
url: "data/A.png",
|
||||||
|
width: 1000,
|
||||||
|
height: 1000
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
type: 'legacy-image-pyramid',
|
||||||
|
levels: [{
|
||||||
|
url: "data/BBlue.png",
|
||||||
|
width: 1000,
|
||||||
|
height: 1000
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler( "open", function openHandler() {
|
||||||
|
viewer.removeHandler( "open", openHandler );
|
||||||
|
|
||||||
|
viewer.addHandler( "add-layer-failed",
|
||||||
|
function addLayerFailedHandler( event ) {
|
||||||
|
viewer.removeHandler( "add-layer-failed", addLayerFailedHandler );
|
||||||
|
equal( event.message, "Sequences can not be added as layers." );
|
||||||
|
equal( event.options, options, "Layer failed event should give the options." );
|
||||||
|
start();
|
||||||
|
} );
|
||||||
|
viewer.addLayer( options );
|
||||||
|
|
||||||
|
});
|
||||||
|
viewer.open( '/test/data/testpattern.dzi' );
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
asyncTest( 'Reassign base layer', function() {
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
tileSource: {
|
||||||
|
type: 'legacy-image-pyramid',
|
||||||
|
levels: [{
|
||||||
|
url: "data/A.png",
|
||||||
|
width: 1000,
|
||||||
|
height: 1000
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
level: 0
|
||||||
|
};
|
||||||
|
viewer.addHandler( "open", function openHandler( ) {
|
||||||
|
viewer.removeHandler( "open", openHandler );
|
||||||
|
var testPatternDrawer = viewer.drawer;
|
||||||
|
equal( viewer.drawer, testPatternDrawer, "Viewer.drawer should be set to testPatternDrawer." );
|
||||||
|
viewer.addHandler( "add-layer", function addLayerHandler( event ) {
|
||||||
|
viewer.removeHandler( "add-layer", addLayerHandler );
|
||||||
|
var aDrawer = event.drawer;
|
||||||
|
equal( viewer.drawer, aDrawer, "Viewer.drawer should be set to aDrawer." );
|
||||||
|
viewer.setLayerLevel( aDrawer, 1 );
|
||||||
|
equal( viewer.drawer, testPatternDrawer, "Viewer.drawer should be set back to testPatternDrawer." );
|
||||||
|
|
||||||
|
viewer.removeLayer( viewer.drawer );
|
||||||
|
equal( viewer.drawer, aDrawer, "Viewer.drawer must be reassigned when removing base layer." );
|
||||||
|
|
||||||
|
viewer.removeLayer( viewer.drawer );
|
||||||
|
ok( !viewer.isOpen(), "Viewer should be closed when removing last layer." );
|
||||||
|
|
||||||
|
start();
|
||||||
|
});
|
||||||
|
viewer.addLayer( options );
|
||||||
|
});
|
||||||
|
viewer.open( '/test/data/testpattern.dzi' );
|
||||||
|
});
|
||||||
|
|
||||||
|
asyncTest( 'Layers and sequences', function() {
|
||||||
|
expect( 1 );
|
||||||
|
|
||||||
|
// TODO: Remove workaround when issue #321 is fixed.
|
||||||
|
// https://github.com/openseadragon/openseadragon/issues/321
|
||||||
|
// viewer.open( [{
|
||||||
|
// type: 'legacy-image-pyramid',
|
||||||
|
// levels: [ {
|
||||||
|
// url: "data/A.png",
|
||||||
|
// width: 1000,
|
||||||
|
// height: 1000
|
||||||
|
// }]
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// type: 'legacy-image-pyramid',
|
||||||
|
// levels: [ {
|
||||||
|
// url: "data/BBlue.png",
|
||||||
|
// width: 1000,
|
||||||
|
// height: 1000
|
||||||
|
// }]}] );
|
||||||
|
|
||||||
|
viewer.close();
|
||||||
|
viewer = OpenSeadragon({
|
||||||
|
id: 'layersexample',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
tileSources: [{
|
||||||
|
type: 'legacy-image-pyramid',
|
||||||
|
levels: [{
|
||||||
|
url: "data/A.png",
|
||||||
|
width: 1000,
|
||||||
|
height: 1000
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'legacy-image-pyramid',
|
||||||
|
levels: [{
|
||||||
|
url: "data/BBlue.png",
|
||||||
|
width: 1000,
|
||||||
|
height: 1000
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
// End workaround
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
tileSource: {
|
||||||
|
type: 'legacy-image-pyramid',
|
||||||
|
levels: [{
|
||||||
|
url: "data/CCyan.png",
|
||||||
|
width: 1000,
|
||||||
|
height: 1000
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler( "open", function openHandler() {
|
||||||
|
viewer.addHandler( "add-layer", function addLayerHandler( event ) {
|
||||||
|
viewer.removeHandler( "add-layer", addLayerHandler );
|
||||||
|
|
||||||
|
var layer = event.drawer;
|
||||||
|
try {
|
||||||
|
viewer.setLayerLevel( layer, 0 );
|
||||||
|
} catch (e) {
|
||||||
|
ok( true );
|
||||||
|
}
|
||||||
|
start();
|
||||||
|
} );
|
||||||
|
viewer.addLayer( options );
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
})();
|
535
test/overlays.js
Normal file
535
test/overlays.js
Normal file
@ -0,0 +1,535 @@
|
|||||||
|
/* global QUnit, module, Util, $, console, test, asyncTest, start, ok, equal */
|
||||||
|
|
||||||
|
( function() {
|
||||||
|
var viewer;
|
||||||
|
|
||||||
|
module( "Overlays", {
|
||||||
|
setup: function() {
|
||||||
|
var example = $( '<div id="example-overlays"></div>' ).appendTo( "#qunit-fixture" );
|
||||||
|
var fixedOverlay = $( '<div id="fixed-overlay"></div>' ).appendTo( example );
|
||||||
|
fixedOverlay.width( 70 );
|
||||||
|
fixedOverlay.height( 60 );
|
||||||
|
|
||||||
|
testLog.reset();
|
||||||
|
},
|
||||||
|
teardown: function() {
|
||||||
|
resetTestVariables();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
var resetTestVariables = function() {
|
||||||
|
if ( viewer ) {
|
||||||
|
viewer.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function waitForViewer( handler, count ) {
|
||||||
|
if ( typeof count !== "number" ) {
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
var ready = viewer.isOpen() &&
|
||||||
|
viewer.drawer !== null &&
|
||||||
|
!viewer.drawer.needsUpdate() &&
|
||||||
|
Util.equalsWithVariance( viewer.viewport.getBounds( true ).x,
|
||||||
|
viewer.viewport.getBounds().x, 0.000 ) &&
|
||||||
|
Util.equalsWithVariance( viewer.viewport.getBounds( true ).y,
|
||||||
|
viewer.viewport.getBounds().y, 0.000 ) &&
|
||||||
|
Util.equalsWithVariance( viewer.viewport.getBounds( true ).width,
|
||||||
|
viewer.viewport.getBounds().width, 0.000 );
|
||||||
|
|
||||||
|
if ( ready ) {
|
||||||
|
handler();
|
||||||
|
} else if ( count < 50 ) {
|
||||||
|
count++;
|
||||||
|
setTimeout( function() {
|
||||||
|
waitForViewer( handler, count );
|
||||||
|
}, 100 );
|
||||||
|
} else {
|
||||||
|
console.log( "waitForViewer:" + viewer.isOpen( ) + ":" + viewer.drawer +
|
||||||
|
":" + viewer.drawer.needsUpdate() );
|
||||||
|
handler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asyncTest( 'Overlays via viewer options', function() {
|
||||||
|
|
||||||
|
viewer = OpenSeadragon( {
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: [ '/test/data/testpattern.dzi', '/test/data/testpattern.dzi' ],
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
overlays: [ {
|
||||||
|
x: 0.1,
|
||||||
|
y: 0.4,
|
||||||
|
width: 0.09,
|
||||||
|
height: 0.09,
|
||||||
|
id: "overlay"
|
||||||
|
} ]
|
||||||
|
} );
|
||||||
|
viewer.addHandler( 'open', openHandler );
|
||||||
|
|
||||||
|
function openHandler() {
|
||||||
|
viewer.removeHandler( 'open', openHandler );
|
||||||
|
|
||||||
|
equal( viewer.overlays.length, 1, "Global overlay should be added." );
|
||||||
|
equal( viewer.currentOverlays.length, 1, "Global overlay should be open." );
|
||||||
|
|
||||||
|
viewer.addHandler( 'open', openPageHandler );
|
||||||
|
viewer.goToPage( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPageHandler() {
|
||||||
|
viewer.removeHandler( 'open', openPageHandler );
|
||||||
|
|
||||||
|
equal( viewer.overlays.length, 1, "Global overlay should stay after page switch." );
|
||||||
|
equal( viewer.currentOverlays.length, 1, "Global overlay should re-open after page switch." );
|
||||||
|
|
||||||
|
viewer.addHandler( 'close', closeHandler );
|
||||||
|
viewer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeHandler() {
|
||||||
|
viewer.removeHandler( 'close', closeHandler );
|
||||||
|
|
||||||
|
equal( viewer.overlays.length, 1, "Global overlay should not be removed on close." );
|
||||||
|
equal( viewer.currentOverlays.length, 0, "Global overlay should be closed on close." );
|
||||||
|
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
asyncTest( 'Page Overlays via viewer options', function() {
|
||||||
|
|
||||||
|
viewer = OpenSeadragon( {
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: [ {
|
||||||
|
Image: {
|
||||||
|
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
||||||
|
Url: "/test/data/testpattern_files/",
|
||||||
|
Format: "jpg",
|
||||||
|
Overlap: "1",
|
||||||
|
TileSize: "254",
|
||||||
|
Size: {
|
||||||
|
Width: 1000,
|
||||||
|
Height: 1000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
overlays: [ {
|
||||||
|
x: 0.1,
|
||||||
|
y: 0.4,
|
||||||
|
width: 0.09,
|
||||||
|
height: 0.09,
|
||||||
|
id: "overlay"
|
||||||
|
} ]
|
||||||
|
}, {
|
||||||
|
Image: {
|
||||||
|
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
||||||
|
Url: "/test/data/testpattern_files/",
|
||||||
|
Format: "jpg",
|
||||||
|
Overlap: "1",
|
||||||
|
TileSize: "254",
|
||||||
|
Size: {
|
||||||
|
Width: 1000,
|
||||||
|
Height: 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ],
|
||||||
|
springStiffness: 100 // Faster animation = faster tests
|
||||||
|
} );
|
||||||
|
viewer.addHandler( 'open', openHandler );
|
||||||
|
|
||||||
|
function openHandler() {
|
||||||
|
viewer.removeHandler( 'open', openHandler );
|
||||||
|
|
||||||
|
equal( viewer.overlays.length, 0, "No global overlay should be added." );
|
||||||
|
equal( viewer.currentOverlays.length, 1, "Page overlay should be open." );
|
||||||
|
|
||||||
|
viewer.addHandler( 'open', openPageHandler );
|
||||||
|
viewer.goToPage( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPageHandler() {
|
||||||
|
viewer.removeHandler( 'open', openPageHandler );
|
||||||
|
|
||||||
|
equal( viewer.overlays.length, 0, "No global overlay should be added after page switch." );
|
||||||
|
equal( viewer.currentOverlays.length, 0, "No page overlay should be opened after page switch." );
|
||||||
|
|
||||||
|
viewer.addHandler( 'close', closeHandler );
|
||||||
|
viewer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeHandler() {
|
||||||
|
viewer.removeHandler( 'close', closeHandler );
|
||||||
|
|
||||||
|
equal( viewer.overlays.length, 0, "No global overlay should be added on close." );
|
||||||
|
equal( viewer.currentOverlays.length, 0, "Page overlay should be closed on close." );
|
||||||
|
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
asyncTest( 'Overlays via addOverlay method', function() {
|
||||||
|
|
||||||
|
viewer = OpenSeadragon( {
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: [ '/test/data/testpattern.dzi', '/test/data/testpattern.dzi' ],
|
||||||
|
springStiffness: 100 // Faster animation = faster tests
|
||||||
|
} );
|
||||||
|
viewer.addHandler( 'open', openHandler );
|
||||||
|
|
||||||
|
function openHandler() {
|
||||||
|
viewer.removeHandler( 'open', openHandler );
|
||||||
|
|
||||||
|
equal( viewer.overlays.length, 0, "No global overlay should be added." );
|
||||||
|
equal( viewer.currentOverlays.length, 0, "No overlay should be open." );
|
||||||
|
|
||||||
|
var rect = new OpenSeadragon.Rect( 0.1, 0.1, 0.1, 0.1 );
|
||||||
|
var overlay = $( "<div/>" ).prop( "id", "overlay" ).get( 0 );
|
||||||
|
viewer.addOverlay( overlay, rect );
|
||||||
|
equal( viewer.overlays.length, 0, "No manual overlay should be added as global overlay." );
|
||||||
|
equal( viewer.currentOverlays.length, 1, "A manual overlay should be open." );
|
||||||
|
|
||||||
|
viewer.addHandler( 'open', openPageHandler );
|
||||||
|
viewer.goToPage( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPageHandler() {
|
||||||
|
viewer.removeHandler( 'open', openPageHandler );
|
||||||
|
|
||||||
|
equal( viewer.overlays.length, 0, "No global overlay should be added after page switch." );
|
||||||
|
equal( viewer.currentOverlays.length, 0, "Manual overlay should be removed after page switch." );
|
||||||
|
|
||||||
|
viewer.addHandler( 'close', closeHandler );
|
||||||
|
viewer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeHandler() {
|
||||||
|
viewer.removeHandler( 'close', closeHandler );
|
||||||
|
|
||||||
|
equal( viewer.overlays.length, 0, "No global overlay should be added on close." );
|
||||||
|
equal( viewer.currentOverlays.length, 0, "Manual overlay should be removed on close." );
|
||||||
|
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
asyncTest( 'Overlays size in pixels', function() {
|
||||||
|
|
||||||
|
viewer = OpenSeadragon( {
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: '/test/data/testpattern.dzi',
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
overlays: [ {
|
||||||
|
px: 13,
|
||||||
|
py: 120,
|
||||||
|
width: 124,
|
||||||
|
height: 132,
|
||||||
|
id: "overlay"
|
||||||
|
}, {
|
||||||
|
px: 400,
|
||||||
|
py: 500,
|
||||||
|
id: "fixed-overlay",
|
||||||
|
placement: "TOP_LEFT"
|
||||||
|
} ]
|
||||||
|
} );
|
||||||
|
|
||||||
|
function checkOverlayPosition( contextMessage ) {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
var expPosition = viewport.imageToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point( 13, 120 ) ).apply( Math.floor );
|
||||||
|
var actPosition = $( "#overlay" ).position();
|
||||||
|
equal( actPosition.left, expPosition.x, "X position mismatch " + contextMessage );
|
||||||
|
equal( actPosition.top, expPosition.y, "Y position mismatch " + contextMessage );
|
||||||
|
|
||||||
|
var zoom = viewport.viewportToImageZoom( viewport.getZoom( true ) );
|
||||||
|
var expectedWidth = Math.ceil( 124 * zoom );
|
||||||
|
var expectedHeight = Math.ceil( 132 * zoom );
|
||||||
|
equal( $( "#overlay" ).width(), expectedWidth, "Width mismatch " + contextMessage );
|
||||||
|
equal( $( "#overlay" ).height( ), expectedHeight, "Height mismatch " + contextMessage );
|
||||||
|
|
||||||
|
|
||||||
|
expPosition = viewport.imageToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point( 400, 500 ) ).apply( Math.floor );
|
||||||
|
actPosition = $( "#fixed-overlay" ).position();
|
||||||
|
equal( actPosition.left, expPosition.x, "Fixed overlay X position mismatch " + contextMessage );
|
||||||
|
equal( actPosition.top, expPosition.y, "Fixed overlay Y position mismatch " + contextMessage );
|
||||||
|
|
||||||
|
equal( $( "#fixed-overlay" ).width(), 70, "Fixed overlay width mismatch " + contextMessage );
|
||||||
|
equal( $( "#fixed-overlay" ).height( ), 60, "Fixed overlay height mismatch " + contextMessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForViewer( function() {
|
||||||
|
checkOverlayPosition( "after opening using image coordinates" );
|
||||||
|
|
||||||
|
viewer.viewport.zoomBy( 1.1 ).panBy( new OpenSeadragon.Point( 0.1, 0.2 ) );
|
||||||
|
waitForViewer( function() {
|
||||||
|
checkOverlayPosition( "after zoom and pan using image coordinates" );
|
||||||
|
|
||||||
|
viewer.viewport.goHome();
|
||||||
|
waitForViewer( function() {
|
||||||
|
checkOverlayPosition( "after goHome using image coordinates" );
|
||||||
|
start();
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
asyncTest( 'Overlays size in points', function() {
|
||||||
|
|
||||||
|
viewer = OpenSeadragon( {
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: '/test/data/testpattern.dzi',
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
overlays: [ {
|
||||||
|
x: 0.2,
|
||||||
|
y: 0.1,
|
||||||
|
width: 0.5,
|
||||||
|
height: 0.1,
|
||||||
|
id: "overlay"
|
||||||
|
}, {
|
||||||
|
x: 0.5,
|
||||||
|
y: 0.6,
|
||||||
|
id: "fixed-overlay",
|
||||||
|
placement: "TOP_LEFT"
|
||||||
|
} ]
|
||||||
|
} );
|
||||||
|
|
||||||
|
function checkOverlayPosition( contextMessage ) {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
var expPosition = viewport.viewportToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point( 0.2, 0.1 ) ).apply( Math.floor );
|
||||||
|
var actPosition = $( "#overlay" ).position();
|
||||||
|
equal( actPosition.left, expPosition.x, "X position mismatch " + contextMessage );
|
||||||
|
equal( actPosition.top, expPosition.y, "Y position mismatch " + contextMessage );
|
||||||
|
|
||||||
|
var expectedSize = viewport.deltaPixelsFromPoints(
|
||||||
|
new OpenSeadragon.Point( 0.5, 0.1 ) );
|
||||||
|
equal( $( "#overlay" ).width(), expectedSize.x, "Width mismatch " + contextMessage );
|
||||||
|
equal( $( "#overlay" ).height(), expectedSize.y, "Height mismatch " + contextMessage );
|
||||||
|
|
||||||
|
|
||||||
|
expPosition = viewport.viewportToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point( 0.5, 0.6 ) ).apply( Math.floor );
|
||||||
|
actPosition = $( "#fixed-overlay" ).position();
|
||||||
|
equal( actPosition.left, expPosition.x, "Fixed overlay X position mismatch " + contextMessage );
|
||||||
|
equal( actPosition.top, expPosition.y, "Fixed overlay Y position mismatch " + contextMessage );
|
||||||
|
|
||||||
|
equal( $( "#fixed-overlay" ).width(), 70, "Fixed overlay width mismatch " + contextMessage );
|
||||||
|
equal( $( "#fixed-overlay" ).height( ), 60, "Fixed overlay height mismatch " + contextMessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForViewer( function() {
|
||||||
|
checkOverlayPosition( "after opening using viewport coordinates" );
|
||||||
|
|
||||||
|
viewer.viewport.zoomBy( 1.1 ).panBy( new OpenSeadragon.Point( 0.1, 0.2 ) );
|
||||||
|
waitForViewer( function() {
|
||||||
|
checkOverlayPosition( "after zoom and pan using viewport coordinates" );
|
||||||
|
|
||||||
|
viewer.viewport.goHome();
|
||||||
|
waitForViewer( function() {
|
||||||
|
checkOverlayPosition( "after goHome using viewport coordinates" );
|
||||||
|
start();
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
asyncTest( 'Overlays placement', function() {
|
||||||
|
|
||||||
|
var scalableOverlayLocation = new OpenSeadragon.Rect( 0.2, 0.1, 0.5, 0.1 );
|
||||||
|
var fixedOverlayLocation = new OpenSeadragon.Point( 0.5, 0.6 );
|
||||||
|
|
||||||
|
viewer = OpenSeadragon( {
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: '/test/data/testpattern.dzi',
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
overlays: [ {
|
||||||
|
x: scalableOverlayLocation.x,
|
||||||
|
y: scalableOverlayLocation.y,
|
||||||
|
width: scalableOverlayLocation.width,
|
||||||
|
height: scalableOverlayLocation.height,
|
||||||
|
id: "overlay",
|
||||||
|
placement: "TOP_LEFT"
|
||||||
|
}, {
|
||||||
|
x: fixedOverlayLocation.x,
|
||||||
|
y: fixedOverlayLocation.y,
|
||||||
|
id: "fixed-overlay",
|
||||||
|
placement: "TOP_LEFT"
|
||||||
|
} ]
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Scalable overlays are always TOP_LEFT
|
||||||
|
function checkScalableOverlayPosition( contextMessage ) {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
var expPosition = viewport.viewportToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point( 0.2, 0.1 ) ).apply( Math.floor );
|
||||||
|
var actPosition = $( "#overlay" ).position();
|
||||||
|
equal( actPosition.left, expPosition.x, "X position mismatch " + contextMessage );
|
||||||
|
equal( actPosition.top, expPosition.y, "Y position mismatch " + contextMessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkFixedOverlayPosition( expectedOffset, contextMessage ) {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
var expPosition = viewport.viewportToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point( 0.5, 0.6 ) )
|
||||||
|
.apply( Math.floor )
|
||||||
|
.plus( expectedOffset );
|
||||||
|
var actPosition = $( "#fixed-overlay" ).position();
|
||||||
|
equal( actPosition.left, expPosition.x, "Fixed overlay X position mismatch " + contextMessage );
|
||||||
|
equal( actPosition.top, expPosition.y, "Fixed overlay Y position mismatch " + contextMessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForViewer( function() {
|
||||||
|
|
||||||
|
checkScalableOverlayPosition( "with TOP_LEFT placement." );
|
||||||
|
checkFixedOverlayPosition( new OpenSeadragon.Point( 0, 0 ),
|
||||||
|
"with TOP_LEFT placement." );
|
||||||
|
|
||||||
|
viewer.updateOverlay( "overlay", scalableOverlayLocation,
|
||||||
|
OpenSeadragon.OverlayPlacement.CENTER );
|
||||||
|
viewer.updateOverlay( "fixed-overlay", fixedOverlayLocation,
|
||||||
|
OpenSeadragon.OverlayPlacement.CENTER );
|
||||||
|
|
||||||
|
setTimeout( function() {
|
||||||
|
checkScalableOverlayPosition( "with CENTER placement." );
|
||||||
|
checkFixedOverlayPosition( new OpenSeadragon.Point( -35, -30 ),
|
||||||
|
"with CENTER placement." );
|
||||||
|
|
||||||
|
viewer.updateOverlay( "overlay", scalableOverlayLocation,
|
||||||
|
OpenSeadragon.OverlayPlacement.BOTTOM_RIGHT );
|
||||||
|
viewer.updateOverlay( "fixed-overlay", fixedOverlayLocation,
|
||||||
|
OpenSeadragon.OverlayPlacement.BOTTOM_RIGHT );
|
||||||
|
setTimeout( function() {
|
||||||
|
checkScalableOverlayPosition( "with BOTTOM_RIGHT placement." );
|
||||||
|
checkFixedOverlayPosition( new OpenSeadragon.Point( -70, -60 ),
|
||||||
|
"with BOTTOM_RIGHT placement." );
|
||||||
|
|
||||||
|
start();
|
||||||
|
}, 100 );
|
||||||
|
|
||||||
|
}, 100 );
|
||||||
|
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
asyncTest( 'Overlays placement and resizing check', function() {
|
||||||
|
|
||||||
|
var fixedOverlayLocation = new OpenSeadragon.Point( 0.5, 0.6 );
|
||||||
|
|
||||||
|
viewer = OpenSeadragon( {
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: '/test/data/testpattern.dzi',
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
overlays: [ {
|
||||||
|
x: fixedOverlayLocation.x,
|
||||||
|
y: fixedOverlayLocation.y,
|
||||||
|
id: "fixed-overlay",
|
||||||
|
placement: "CENTER",
|
||||||
|
checkResize: true
|
||||||
|
} ]
|
||||||
|
} );
|
||||||
|
|
||||||
|
function checkFixedOverlayPosition( expectedOffset, contextMessage ) {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
var expPosition = viewport.viewportToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point( 0.5, 0.6 ) )
|
||||||
|
.apply( Math.floor )
|
||||||
|
.plus( expectedOffset );
|
||||||
|
var actPosition = $( "#fixed-overlay" ).position();
|
||||||
|
equal( actPosition.left, expPosition.x, "Fixed overlay X position mismatch " + contextMessage );
|
||||||
|
equal( actPosition.top, expPosition.y, "Fixed overlay Y position mismatch " + contextMessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForViewer( function() {
|
||||||
|
checkFixedOverlayPosition( new OpenSeadragon.Point( -35, -30 ),
|
||||||
|
"with overlay of size 70,60." );
|
||||||
|
|
||||||
|
$( "#fixed-overlay" ).width( 50 );
|
||||||
|
$( "#fixed-overlay" ).height( 40 );
|
||||||
|
|
||||||
|
// The resizing of the overlays is not detected by the viewer's loop.
|
||||||
|
viewer.forceRedraw();
|
||||||
|
|
||||||
|
setTimeout( function() {
|
||||||
|
checkFixedOverlayPosition( new OpenSeadragon.Point( -25, -20 ),
|
||||||
|
"with overlay of size 50,40." );
|
||||||
|
|
||||||
|
// Restore original size
|
||||||
|
$( "#fixed-overlay" ).width( 70 );
|
||||||
|
$( "#fixed-overlay" ).height( 60 );
|
||||||
|
|
||||||
|
start();
|
||||||
|
}, 100 );
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
asyncTest( 'Overlays placement and no resizing check', function() {
|
||||||
|
|
||||||
|
var fixedOverlayLocation = new OpenSeadragon.Point( 0.5, 0.6 );
|
||||||
|
|
||||||
|
viewer = OpenSeadragon( {
|
||||||
|
id: 'example-overlays',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: '/test/data/testpattern.dzi',
|
||||||
|
springStiffness: 100, // Faster animation = faster tests
|
||||||
|
overlays: [ {
|
||||||
|
x: fixedOverlayLocation.x,
|
||||||
|
y: fixedOverlayLocation.y,
|
||||||
|
id: "fixed-overlay",
|
||||||
|
placement: "CENTER",
|
||||||
|
checkResize: false
|
||||||
|
} ]
|
||||||
|
} );
|
||||||
|
|
||||||
|
function checkFixedOverlayPosition( expectedOffset, contextMessage ) {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
var expPosition = viewport.viewportToViewerElementCoordinates(
|
||||||
|
new OpenSeadragon.Point( 0.5, 0.6 ) )
|
||||||
|
.apply( Math.floor )
|
||||||
|
.plus( expectedOffset );
|
||||||
|
var actPosition = $( "#fixed-overlay" ).position();
|
||||||
|
equal( actPosition.left, expPosition.x, "Fixed overlay X position mismatch " + contextMessage );
|
||||||
|
equal( actPosition.top, expPosition.y, "Fixed overlay Y position mismatch " + contextMessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForViewer( function() {
|
||||||
|
checkFixedOverlayPosition( new OpenSeadragon.Point( -35, -30 ),
|
||||||
|
"with overlay of size 70,60." );
|
||||||
|
|
||||||
|
$( "#fixed-overlay" ).width( 50 );
|
||||||
|
$( "#fixed-overlay" ).height( 40 );
|
||||||
|
|
||||||
|
// The resizing of the overlays is not detected by the viewer's loop.
|
||||||
|
viewer.forceRedraw();
|
||||||
|
|
||||||
|
setTimeout( function() {
|
||||||
|
checkFixedOverlayPosition( new OpenSeadragon.Point( -35, -30 ),
|
||||||
|
"with overlay of size 50,40." );
|
||||||
|
|
||||||
|
// Restore original size
|
||||||
|
$( "#fixed-overlay" ).width( 70 );
|
||||||
|
$( "#fixed-overlay" ).height( 60 );
|
||||||
|
|
||||||
|
start();
|
||||||
|
}, 100 );
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
} )( );
|
@ -18,7 +18,12 @@
|
|||||||
width: 300px;
|
width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#unitsexample {
|
#unitsexample, #example-overlays {
|
||||||
|
height: 500px;
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#layersexample {
|
||||||
height: 500px;
|
height: 500px;
|
||||||
width: 500px;
|
width: 500px;
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
<script src="/test/utils.js"></script>
|
<script src="/test/utils.js"></script>
|
||||||
<script src="/test/events.js"></script>
|
<script src="/test/events.js"></script>
|
||||||
<script src="/test/units.js"></script>
|
<script src="/test/units.js"></script>
|
||||||
|
<script src="/test/layers.js"></script>
|
||||||
|
<script src="/test/overlays.js"></script>
|
||||||
<script src="/test/rotate.js"></script>
|
<script src="/test/rotate.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -26,12 +26,34 @@
|
|||||||
|
|
||||||
|
|
||||||
function pointEqual(a, b, message) {
|
function pointEqual(a, b, message) {
|
||||||
ok(a.x === b.x && a.y === b.y, message);
|
Util.assessNumericValue(a.x, b.x, 0.00000001, message);
|
||||||
|
Util.assessNumericValue(a.y, b.y, 0.00000001, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
asyncTest('Coordinates conversions', function() {
|
asyncTest('Coordinates conversions', function() {
|
||||||
|
|
||||||
|
function checkPoint(context) {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
|
var point = new OpenSeadragon.Point(15, 12);
|
||||||
|
var result = viewport.viewerElementToImageCoordinates(
|
||||||
|
viewport.imageToViewerElementCoordinates(point));
|
||||||
|
pointEqual(result, point, 'viewerElement and image ' + context);
|
||||||
|
|
||||||
|
var result = viewport.windowToImageCoordinates(
|
||||||
|
viewport.imageToWindowCoordinates(point));
|
||||||
|
pointEqual(result, point, 'window and image ' + context);
|
||||||
|
|
||||||
|
var result = viewport.viewerElementToViewportCoordinates(
|
||||||
|
viewport.viewportToViewerElementCoordinates(point));
|
||||||
|
pointEqual(result, point, 'viewerElement and viewport ' + context);
|
||||||
|
|
||||||
|
var result = viewport.windowToViewportCoordinates(
|
||||||
|
viewport.viewportToWindowCoordinates(point));
|
||||||
|
pointEqual(result, point, 'window and viewport ' + context);
|
||||||
|
}
|
||||||
|
|
||||||
viewer.addHandler("open", function () {
|
viewer.addHandler("open", function () {
|
||||||
var viewport = viewer.viewport;
|
var viewport = viewer.viewport;
|
||||||
|
|
||||||
@ -52,24 +74,13 @@
|
|||||||
var pixel = viewport.viewerElementToImageCoordinates(viewerTopRight);
|
var pixel = viewport.viewerElementToImageCoordinates(viewerTopRight);
|
||||||
pointEqual(pixel, imageTopRight, 'Viewer top right has viewport coordinates imageWidth,0.');
|
pointEqual(pixel, imageTopRight, 'Viewer top right has viewport coordinates imageWidth,0.');
|
||||||
|
|
||||||
var point = new OpenSeadragon.Point(15, 12);
|
checkPoint('after opening');
|
||||||
var result = viewport.viewerElementToImageCoordinates(
|
viewer.addHandler('animation-finish', function animationHandler() {
|
||||||
viewport.imageToViewerElementCoordinates(point));
|
viewer.removeHandler('animation-finish', animationHandler);
|
||||||
pointEqual(result, point, 'viewerElement and image');
|
checkPoint('after zoom and pan');
|
||||||
|
start();
|
||||||
var result = viewport.windowToImageCoordinates(
|
});
|
||||||
viewport.imageToWindowCoordinates(point));
|
viewer.viewport.zoomTo(0.8).panTo(new OpenSeadragon.Point(0.1, 0.2));
|
||||||
pointEqual(result, point, 'window and image');
|
|
||||||
|
|
||||||
var result = viewport.viewerElementToViewportCoordinates(
|
|
||||||
viewport.viewportToViewerElementCoordinates(point));
|
|
||||||
pointEqual(result, point, 'viewerElement and viewport');
|
|
||||||
|
|
||||||
var result = viewport.windowToViewportCoordinates(
|
|
||||||
viewport.viewportToWindowCoordinates(point));
|
|
||||||
pointEqual(result, point, 'window and viewport');
|
|
||||||
|
|
||||||
start();
|
|
||||||
});
|
});
|
||||||
viewer.open('/test/data/testpattern.dzi');
|
viewer.open('/test/data/testpattern.dzi');
|
||||||
});
|
});
|
||||||
@ -104,14 +115,13 @@
|
|||||||
checkZoom();
|
checkZoom();
|
||||||
|
|
||||||
var zoomHandler = function() {
|
var zoomHandler = function() {
|
||||||
viewer.removeHandler('animationfinish', zoomHandler);
|
viewer.removeHandler('animation-finish', zoomHandler);
|
||||||
checkZoom();
|
checkZoom();
|
||||||
start();
|
start();
|
||||||
};
|
};
|
||||||
|
|
||||||
viewer.addHandler('animationfinish', zoomHandler);
|
viewer.addHandler('animation-finish', zoomHandler);
|
||||||
viewport.zoomTo(2);
|
viewport.zoomTo(2);
|
||||||
start();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
viewer.open('/test/data/testpattern.dzi');
|
viewer.open('/test/data/testpattern.dzi');
|
||||||
|
Loading…
Reference in New Issue
Block a user