mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 06:36:11 +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.canvas.height = 1;
|
||||||
this.sketchCanvas = null;
|
this.sketchCanvas = null;
|
||||||
this.sketchContext = null;
|
this.sketchContext = null;
|
||||||
|
this.container.removeChild(this.canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -455,35 +455,13 @@ $.Viewer = function( options ) {
|
|||||||
|
|
||||||
|
|
||||||
this.drawer = null;
|
this.drawer = null;
|
||||||
for (let i = 0; i < drawerCandidates.length; i++) {
|
for (const drawerCandidate of drawerCandidates){
|
||||||
|
let success = this.setDrawer(drawerCandidate, false);
|
||||||
let drawerCandidate = drawerCandidates[i];
|
if(success){
|
||||||
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],
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.drawer){
|
if (!this.drawer){
|
||||||
$.console.error('No drawer could be created!');
|
$.console.error('No drawer could be created!');
|
||||||
throw('Error with creating the selected drawer(s)');
|
throw('Error with creating the selected drawer(s)');
|
||||||
@ -950,6 +928,57 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
this.removeAllHandlers();
|
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
|
* @function
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
|
@ -158,6 +158,16 @@
|
|||||||
// set our webgl context reference to null to enable garbage collection
|
// set our webgl context reference to null to enable garbage collection
|
||||||
this._gl = null;
|
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
|
// set our destroyed flag to true
|
||||||
this._destroyed = true;
|
this._destroyed = true;
|
||||||
}
|
}
|
||||||
@ -355,6 +365,15 @@
|
|||||||
let tileContext = tile.getCanvasContext();
|
let tileContext = tile.getCanvasContext();
|
||||||
|
|
||||||
let textureInfo = tileContext ? this._TextureMap.get(tileContext.canvas) : null;
|
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){
|
if(textureInfo){
|
||||||
this._getTileData(tile, tiledImage, textureInfo, overallMatrix, indexInDrawArray, texturePositionArray, textureDataArray, matrixArray, opacityArray);
|
this._getTileData(tile, tiledImage, textureInfo, overallMatrix, indexInDrawArray, texturePositionArray, textureDataArray, matrixArray, opacityArray);
|
||||||
} else {
|
} else {
|
||||||
@ -840,11 +859,18 @@
|
|||||||
_tileReadyHandler(event){
|
_tileReadyHandler(event){
|
||||||
let tile = event.tile;
|
let tile = event.tile;
|
||||||
let tiledImage = event.tiledImage;
|
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 tileContext = tile.getCanvasContext();
|
||||||
let canvas = tileContext && tileContext.canvas;
|
let canvas = tileContext && tileContext.canvas;
|
||||||
// if the tile doesn't provide a canvas, or is tainted by cross-origin
|
// 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
|
// 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)){
|
if(!canvas || $.isCanvasTainted(canvas)){
|
||||||
const wasTainted = tiledImage.isTainted();
|
const wasTainted = tiledImage.isTainted();
|
||||||
if(!wasTainted){
|
if(!wasTainted){
|
||||||
|
Loading…
Reference in New Issue
Block a user