mirror of
https://github.com/openseadragon/openseadragon.git
synced 2025-01-20 09:41:45 +03:00
Add support to add/remove layers and change their levels.
This commit is contained in:
parent
58da998d75
commit
0c2af6550a
@ -91,6 +91,7 @@ $.Drawer = function( options ) {
|
|||||||
collectionOverlays: {},
|
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,
|
||||||
@ -143,6 +144,7 @@ $.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";
|
||||||
@ -340,6 +342,26 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{
|
|||||||
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
|
||||||
|
@ -190,6 +190,9 @@
|
|||||||
* 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} [degrees=0]
|
* @property {Number} [degrees=0]
|
||||||
* Initial rotation.
|
* Initial rotation.
|
||||||
*
|
*
|
||||||
@ -715,6 +718,9 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
// INITIAL ROTATION
|
// INITIAL ROTATION
|
||||||
degrees: 0,
|
degrees: 0,
|
||||||
|
|
||||||
|
// APPEARANCE
|
||||||
|
opacity: 1,
|
||||||
|
|
||||||
//REFERENCE STRIP SETTINGS
|
//REFERENCE STRIP SETTINGS
|
||||||
showReferenceStrip: false,
|
showReferenceStrip: false,
|
||||||
referenceStripScroll: 'horizontal',
|
referenceStripScroll: 'horizontal',
|
||||||
|
319
src/viewer.js
319
src/viewer.js
@ -477,81 +477,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;
|
||||||
},
|
},
|
||||||
@ -1047,18 +992,155 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Add a layer.
|
||||||
|
* options.tileSource can be anything that {@link OpenSeadragon.Viewer#open}
|
||||||
|
* supports.
|
||||||
* @function
|
* @function
|
||||||
* @name OpenSeadragon.Viewer.prototype.addLayer
|
* @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.
|
||||||
|
* @returns {OpenSeadragon.Viewer} Chainable.
|
||||||
|
* @fires OpenSeadragon.Viewer.event:add-layer
|
||||||
|
* @fires OpenSeadragon.Viewer.event:add-layer-failed
|
||||||
*/
|
*/
|
||||||
addLayer: function( tileSource ) {
|
addLayer: function( options ) {
|
||||||
var drawer = new $.Drawer(
|
var _this = this,
|
||||||
tileSource,
|
tileSource = options.tileSource;
|
||||||
this.viewport,
|
|
||||||
this.canvas
|
if ( !tileSource ) {
|
||||||
);
|
throw new Error( "No tile source provided as new layer." );
|
||||||
this.drawers.push( drawer );
|
}
|
||||||
updateOnce( this );
|
|
||||||
return drawer.canvas;
|
getTileSourceImplementation( this, tileSource, function( tileSource ) {
|
||||||
|
var drawer = new $.Drawer({
|
||||||
|
viewer: _this,
|
||||||
|
source: tileSource,
|
||||||
|
viewport: _this.viewport,
|
||||||
|
element: _this.canvas,
|
||||||
|
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 ) {
|
||||||
|
_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 {OpenSeadragon.Drawer} drawer The layer's underlying drawer.
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
_this.raiseEvent( 'add-layer', { drawer: drawer } );
|
||||||
|
}, function( 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} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
_this.raiseEvent( 'add-layer-failed', event );
|
||||||
|
} );
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
getLayerLevel: function( drawer ) {
|
||||||
|
return this.drawers.indexOf( drawer );
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
setLayerLevel: function( drawer, level ) {
|
||||||
|
var oldLevel = this.drawers.indexOf( drawer );
|
||||||
|
if ( level === 0 || oldLevel === 0 ) {
|
||||||
|
throw new Error( "Cannot reassign base level." );
|
||||||
|
}
|
||||||
|
if ( level > this.drawers.length - 1 ) {
|
||||||
|
throw new Error( "Level bigger than number of layers." );
|
||||||
|
}
|
||||||
|
if ( level === oldLevel || oldLevel === -1 ) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this.drawers.splice( oldLevel, 1 );
|
||||||
|
this.drawers.splice( level, 0, drawer );
|
||||||
|
this.canvas.removeChild( drawer.canvas );
|
||||||
|
// Insert right after layer at level - 1
|
||||||
|
var prevLevelCanvas = this.drawers[level - 1].canvas;
|
||||||
|
prevLevelCanvas.parentNode.insertBefore( drawer.canvas,
|
||||||
|
prevLevelCanvas.nextSibling );
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 ) {
|
||||||
|
throw new Error( "Cannot remove base layer." );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.drawers.splice( index, 1 );
|
||||||
|
this.canvas.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;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1389,6 +1471,61 @@ 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
|
||||||
@ -1462,6 +1599,7 @@ function openTileSource( viewer, source ) {
|
|||||||
viewport: _this.viewport,
|
viewport: _this.viewport,
|
||||||
element: _this.canvas,
|
element: _this.canvas,
|
||||||
overlays: [].concat( _this.overlays ).concat( _this.source.overlays ),
|
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,
|
||||||
@ -1475,7 +1613,7 @@ function openTileSource( viewer, source ) {
|
|||||||
debugMode: _this.debugMode,
|
debugMode: _this.debugMode,
|
||||||
debugGridColor: _this.debugGridColor
|
debugGridColor: _this.debugGridColor
|
||||||
});
|
});
|
||||||
_this.drawers.push( _this.drawer );
|
_this.drawers = [_this.drawer];
|
||||||
|
|
||||||
//Instantiate a navigator if configured
|
//Instantiate a navigator if configured
|
||||||
if ( _this.showNavigator && !_this.collectionMode ){
|
if ( _this.showNavigator && !_this.collectionMode ){
|
||||||
@ -2015,15 +2153,18 @@ function resizeViewportAndRecenter( viewer, containerSize, oldBounds, oldCenter
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateDrawers( viewer ) {
|
function updateDrawers( viewer ) {
|
||||||
viewer.drawers.forEach( function( drawer ) {
|
for (var i = 0; i < viewer.drawers.length; i++ ) {
|
||||||
drawer.update();
|
viewer.drawers[i].update();
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawersNeedUpdate( viewer ) {
|
function drawersNeedUpdate( viewer ) {
|
||||||
return viewer.drawers.some( function( drawer ) {
|
for (var i = 0; i < viewer.drawers.length; i++ ) {
|
||||||
return drawer.needsUpdate();
|
if (viewer.drawers[i].needsUpdate()) {
|
||||||
});
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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;
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user