mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-21 20:56:09 +03:00
support hot-swapping drawers with viewer.setDrawer()
This commit is contained in:
parent
0a154a3b21
commit
8967e2bb03
@ -139,6 +139,7 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
|
||||
this.canvas.height = 1;
|
||||
this.sketchCanvas = null;
|
||||
this.sketchContext = null;
|
||||
this.container.removeChild(this.canvas);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -455,35 +455,13 @@ $.Viewer = function( options ) {
|
||||
|
||||
|
||||
this.drawer = null;
|
||||
for (let i = 0; i < drawerCandidates.length; i++) {
|
||||
|
||||
let drawerCandidate = drawerCandidates[i];
|
||||
let Drawer = null;
|
||||
|
||||
//if inherits from a drawer base, use it
|
||||
if (drawerCandidate && drawerCandidate.prototype instanceof $.DrawerBase) {
|
||||
Drawer = drawerCandidate;
|
||||
drawerCandidate = 'custom';
|
||||
} else if (typeof drawerCandidate === "string") {
|
||||
Drawer = $.determineDrawer(drawerCandidate);
|
||||
} else {
|
||||
$.console.warn('Unsupported drawer! Drawer must be an existing string type, or a class that extends OpenSeadragon.DrawerBase.');
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the drawer is supported, create it and break the loop
|
||||
if (Drawer && Drawer.isSupported()) {
|
||||
this.drawer = new Drawer({
|
||||
viewer: this,
|
||||
viewport: this.viewport,
|
||||
element: this.canvas,
|
||||
debugGridColor: this.debugGridColor,
|
||||
options: this.drawerOptions[drawerCandidate],
|
||||
});
|
||||
|
||||
for (const drawerCandidate of drawerCandidates){
|
||||
let success = this.setDrawer(drawerCandidate, false);
|
||||
if(success){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.drawer){
|
||||
$.console.error('No drawer could be created!');
|
||||
throw('Error with creating the selected drawer(s)');
|
||||
@ -950,6 +928,57 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
||||
this.removeAllHandlers();
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the drawer for this viewer, as a supported string or drawer constructor.
|
||||
* @param {String | OpenSeadragon.DrawerBase} drawerCandidate The type of drawer to try to construct
|
||||
* @param { Boolean } [redrawImmediately] Whether to immediately draw a new frame. Default = true.
|
||||
* @param { Object } [drawerOptions] Options for this drawer. If falsey, defaults to viewer.drawerOptions
|
||||
* for this viewer type. See {@link OpenSeadragon.Options}.
|
||||
* @returns {Boolean} whether the drawer was created successfully
|
||||
*/
|
||||
setDrawer(drawerCandidate, redrawImmediately = true, drawerOptions = null){
|
||||
const oldDrawer = this.drawer;
|
||||
|
||||
let Drawer = null;
|
||||
|
||||
//if inherits from a drawer base, use it
|
||||
if (drawerCandidate && drawerCandidate.prototype instanceof $.DrawerBase) {
|
||||
Drawer = drawerCandidate;
|
||||
drawerCandidate = 'custom';
|
||||
} else if (typeof drawerCandidate === "string") {
|
||||
Drawer = $.determineDrawer(drawerCandidate);
|
||||
}
|
||||
|
||||
if(!Drawer){
|
||||
$.console.warn('Unsupported drawer! Drawer must be an existing string type, or a class that extends OpenSeadragon.DrawerBase.');
|
||||
}
|
||||
|
||||
// if the drawer is supported, create it and return true
|
||||
if (Drawer && Drawer.isSupported()) {
|
||||
|
||||
// first destroy the previous drawer
|
||||
if(oldDrawer){
|
||||
oldDrawer.destroy();
|
||||
}
|
||||
|
||||
// create the new drawer
|
||||
this.drawer = new Drawer({
|
||||
viewer: this,
|
||||
viewport: this.viewport,
|
||||
element: this.canvas,
|
||||
debugGridColor: this.debugGridColor,
|
||||
options: drawerOptions || this.drawerOptions[drawerCandidate],
|
||||
});
|
||||
|
||||
if(redrawImmediately){
|
||||
this.forceRedraw();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* @function
|
||||
* @returns {Boolean}
|
||||
|
@ -158,6 +158,16 @@
|
||||
// set our webgl context reference to null to enable garbage collection
|
||||
this._gl = null;
|
||||
|
||||
if(this._backupCanvasDrawer){
|
||||
this._backupCanvasDrawer.destroy();
|
||||
this._backupCanvasDrawer = null;
|
||||
}
|
||||
|
||||
this.container.removeChild(this.canvas);
|
||||
if(this.viewer.drawer === this){
|
||||
this.viewer.drawer = null;
|
||||
}
|
||||
|
||||
// set our destroyed flag to true
|
||||
this._destroyed = true;
|
||||
}
|
||||
@ -355,6 +365,15 @@
|
||||
let tileContext = tile.getCanvasContext();
|
||||
|
||||
let textureInfo = tileContext ? this._TextureMap.get(tileContext.canvas) : null;
|
||||
if(!textureInfo){
|
||||
// tile was not processed in the tile-ready event (this can happen
|
||||
// if this drawer was created after the tile was downloaded)
|
||||
this._tileReadyHandler({tile: tile, tiledImage: tiledImage});
|
||||
|
||||
// retry getting textureInfo
|
||||
textureInfo = tileContext ? this._TextureMap.get(tileContext.canvas) : null;
|
||||
}
|
||||
|
||||
if(textureInfo){
|
||||
this._getTileData(tile, tiledImage, textureInfo, overallMatrix, indexInDrawArray, texturePositionArray, textureDataArray, matrixArray, opacityArray);
|
||||
} else {
|
||||
@ -840,11 +859,18 @@
|
||||
_tileReadyHandler(event){
|
||||
let tile = event.tile;
|
||||
let tiledImage = event.tiledImage;
|
||||
|
||||
// If a tiledImage is already known to be tainted, don't try to upload any
|
||||
// textures to webgl, because they won't be used even if it succeeds
|
||||
if(tiledImage.isTainted()){
|
||||
return;
|
||||
}
|
||||
|
||||
let tileContext = tile.getCanvasContext();
|
||||
let canvas = tileContext && tileContext.canvas;
|
||||
// if the tile doesn't provide a canvas, or is tainted by cross-origin
|
||||
// data, marked the TiledImage as tainted so the canvas drawer can be
|
||||
// used instead, and return immediately - data cannot be uploaded to webgl
|
||||
// used instead, and return immediately - tainted data cannot be uploaded to webgl
|
||||
if(!canvas || $.isCanvasTainted(canvas)){
|
||||
const wasTainted = tiledImage.isTainted();
|
||||
if(!wasTainted){
|
||||
|
Loading…
Reference in New Issue
Block a user