mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 06:36:11 +03:00
split canvas from html rendering
This commit is contained in:
parent
467597e2c2
commit
2f3bef0865
@ -58,7 +58,8 @@ module.exports = function(grunt) {
|
|||||||
"src/tile.js",
|
"src/tile.js",
|
||||||
"src/overlay.js",
|
"src/overlay.js",
|
||||||
"src/drawerbase.js",
|
"src/drawerbase.js",
|
||||||
"src/drawer.js",
|
"src/htmldrawer.js",
|
||||||
|
"src/canvasdrawer.js",
|
||||||
"src/viewport.js",
|
"src/viewport.js",
|
||||||
"src/tiledimage.js",
|
"src/tiledimage.js",
|
||||||
"src/tilecache.js",
|
"src/tilecache.js",
|
||||||
|
1218
src/canvasdrawer.js
Normal file
1218
src/canvasdrawer.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -444,7 +444,7 @@ $.extend( $.Drawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadragon.D
|
|||||||
fillStyle = tiledImage.placeholderFillStyle;
|
fillStyle = tiledImage.placeholderFillStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.drawRectangle(placeholderRect, fillStyle, useSketch);
|
this._drawRectangle(placeholderRect, fillStyle, useSketch);
|
||||||
}
|
}
|
||||||
|
|
||||||
var subPixelRoundingRule = determineSubPixelRoundingRule(tiledImage.subPixelRoundingForTransparency);
|
var subPixelRoundingRule = determineSubPixelRoundingRule(tiledImage.subPixelRoundingForTransparency);
|
||||||
@ -611,7 +611,7 @@ $.extend( $.Drawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadragon.D
|
|||||||
scale = scale || 1;
|
scale = scale || 1;
|
||||||
this._drawTileToCanvas(tile, context, drawingHandler, scale, translate, shouldRoundPositionAndSize, source);
|
this._drawTileToCanvas(tile, context, drawingHandler, scale, translate, shouldRoundPositionAndSize, source);
|
||||||
} else {
|
} else {
|
||||||
tile._drawTileToHTML( tile, this.canvas );
|
this._drawTileToHTML( tile, this.canvas );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -868,7 +868,7 @@ $.extend( $.Drawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadragon.D
|
|||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
drawRectangle: function(rect, fillStyle, useSketch) {
|
_drawRectangle: function(rect, fillStyle, useSketch) {
|
||||||
if (!this.useCanvas) {
|
if (!this.useCanvas) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
347
src/htmldrawer.js
Normal file
347
src/htmldrawer.js
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
/*
|
||||||
|
* OpenSeadragon - Drawer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
|
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of CodePlex Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function( $ ){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class HTMLDrawer
|
||||||
|
* @memberof OpenSeadragon
|
||||||
|
* @classdesc HTML-based implementation of DrawerBase for an {@link OpenSeadragon.Viewer}.
|
||||||
|
* @param {Object} options - Options for this Drawer.
|
||||||
|
* @param {OpenSeadragon.Viewer} options.viewer - The Viewer that owns this Drawer.
|
||||||
|
* @param {OpenSeadragon.Viewport} options.viewport - Reference to Viewer viewport.
|
||||||
|
* @param {Element} options.element - Parent element.
|
||||||
|
* @param {Number} [options.debugGridColor] - See debugGridColor in {@link OpenSeadragon.Options} for details.
|
||||||
|
*/
|
||||||
|
$.HTMLDrawer = function(options) {
|
||||||
|
|
||||||
|
$.DrawerBase.call(this, options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2d drawing context for {@link OpenSeadragon.Drawer#canvas} if it's a <canvas> element, otherwise null.
|
||||||
|
* @member {Object} context
|
||||||
|
* @memberof OpenSeadragon.Drawer#
|
||||||
|
*/
|
||||||
|
this.context = null;
|
||||||
|
|
||||||
|
|
||||||
|
// We force our container to ltr because our drawing math doesn't work in rtl.
|
||||||
|
// This issue only affects our canvas renderer, but we do it always for consistency.
|
||||||
|
// Note that this means overlays you want to be rtl need to be explicitly set to rtl.
|
||||||
|
this.container.dir = 'ltr';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$.extend( $.HTMLDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadragon.Drawer.prototype */ {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the TiledImages
|
||||||
|
*/
|
||||||
|
draw: function(tiledImages) {
|
||||||
|
var _this = this;
|
||||||
|
this._prepareNewFrame(); // prepare to draw a new frame
|
||||||
|
tiledImages.forEach(function(tiledImage){
|
||||||
|
if (tiledImage.opacity !== 0 || tiledImage._preload) {
|
||||||
|
tiledImage._midDraw = true;
|
||||||
|
_this._updateViewportWithTiledImage(tiledImage);
|
||||||
|
tiledImage._midDraw = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tiledImage._needsDraw = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Boolean} False - rotation is not supported.
|
||||||
|
*/
|
||||||
|
canRotate: function() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the drawer (unload current loaded tiles)
|
||||||
|
*/
|
||||||
|
destroy: function() {
|
||||||
|
//force unloading of current canvas (1x1 will be gc later, trick not necessarily needed)
|
||||||
|
this.canvas.width = 1;
|
||||||
|
this.canvas.height = 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns image smoothing on or off for this viewer. Note: Ignored by HTML Drawer
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {Boolean} [imageSmoothingEnabled] - Whether or not the image is
|
||||||
|
* drawn smoothly on the canvas; see imageSmoothingEnabled in
|
||||||
|
* {@link OpenSeadragon.Options} for more explanation.
|
||||||
|
*/
|
||||||
|
setImageSmoothingEnabled: function(){
|
||||||
|
// noop - HTML Drawer does not deal with this property
|
||||||
|
$.console.warn('HTMLDrawer.setImageSmoothingEnabled does not have an effect.');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @inner
|
||||||
|
* Clears the Drawer so it's ready to draw another frame.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
_prepareNewFrame: function() {
|
||||||
|
this.canvas.innerHTML = "";
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Methods from TiledImage */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @inner
|
||||||
|
* Handles drawing a single TiledImage to the canvas
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
_updateViewportWithTiledImage: function(tiledImage) {
|
||||||
|
var _this = this;
|
||||||
|
tiledImage._needsDraw = false;
|
||||||
|
tiledImage._tilesLoading = 0;
|
||||||
|
tiledImage.loadingCoverage = {};
|
||||||
|
|
||||||
|
// Reset tile's internal drawn state
|
||||||
|
while (tiledImage.lastDrawn.length > 0) {
|
||||||
|
var tile = tiledImage.lastDrawn.pop();
|
||||||
|
tile.beingDrawn = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var drawArea = tiledImage.getDrawArea();
|
||||||
|
if(!drawArea){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTile(info){
|
||||||
|
var tile = info.tile;
|
||||||
|
if(tile && tile.loaded){
|
||||||
|
var needsDraw = _this._blendTile(
|
||||||
|
tiledImage,
|
||||||
|
tile,
|
||||||
|
tile.x,
|
||||||
|
tile.y,
|
||||||
|
info.level,
|
||||||
|
info.levelOpacity,
|
||||||
|
info.currentTime
|
||||||
|
);
|
||||||
|
if(needsDraw){
|
||||||
|
tiledImage._needsDraw = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var infoArray = tiledImage.getTileInfoForDrawing();
|
||||||
|
infoArray.forEach(updateTile);
|
||||||
|
|
||||||
|
this._drawTiles(tiledImage);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @inner
|
||||||
|
* Updates the opacity of a tile according to the time it has been on screen
|
||||||
|
* to perform a fade-in.
|
||||||
|
* Updates coverage once a tile is fully opaque.
|
||||||
|
* Returns whether the fade-in has completed.
|
||||||
|
*
|
||||||
|
* @param {OpenSeadragon.Tile} tile
|
||||||
|
* @param {Number} x
|
||||||
|
* @param {Number} y
|
||||||
|
* @param {Number} level
|
||||||
|
* @param {Number} levelOpacity
|
||||||
|
* @param {Number} currentTime
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
_blendTile: function( tiledImage, tile, x, y, level, levelOpacity, currentTime ){
|
||||||
|
var blendTimeMillis = 1000 * tiledImage.blendTime,
|
||||||
|
deltaTime,
|
||||||
|
opacity;
|
||||||
|
|
||||||
|
if ( !tile.blendStart ) {
|
||||||
|
tile.blendStart = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
deltaTime = currentTime - tile.blendStart;
|
||||||
|
opacity = blendTimeMillis ? Math.min( 1, deltaTime / ( blendTimeMillis ) ) : 1;
|
||||||
|
|
||||||
|
if ( tiledImage.alwaysBlend ) {
|
||||||
|
opacity *= levelOpacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.opacity = opacity;
|
||||||
|
|
||||||
|
tiledImage.lastDrawn.push( tile );
|
||||||
|
|
||||||
|
if ( opacity === 1 ) {
|
||||||
|
tiledImage._setCoverage( tiledImage.coverage, level, x, y, true );
|
||||||
|
tiledImage._hasOpaqueTile = true;
|
||||||
|
} else if ( deltaTime < blendTimeMillis ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @inner
|
||||||
|
* Draws a TiledImage.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
_drawTiles: function( tiledImage ) {
|
||||||
|
var lastDrawn = tiledImage.lastDrawn;
|
||||||
|
if (tiledImage.opacity === 0 || (lastDrawn.length === 0 && !tiledImage.placeholderFillStyle)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over the tiles to draw, and draw them
|
||||||
|
for (var i = lastDrawn.length - 1; i >= 0; i--) {
|
||||||
|
var tile = lastDrawn[ i ];
|
||||||
|
this._drawTile( tile );
|
||||||
|
tile.beingDrawn = true;
|
||||||
|
|
||||||
|
if( this.viewer ){
|
||||||
|
/**
|
||||||
|
* Raised when a tile is drawn to the canvas
|
||||||
|
*
|
||||||
|
* @event tile-drawn
|
||||||
|
* @memberof OpenSeadragon.Viewer
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event.
|
||||||
|
* @property {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn.
|
||||||
|
* @property {OpenSeadragon.Tile} tile
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
this.viewer.raiseEvent( 'tile-drawn', {
|
||||||
|
tiledImage: tiledImage,
|
||||||
|
tile: tile
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Methods from Tile */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @inner
|
||||||
|
* Draws the given tile.
|
||||||
|
* @param {OpenSeadragon.Tile} tile - The tile to draw.
|
||||||
|
* @param {Function} drawingHandler - Method for firing the drawing event if using canvas.
|
||||||
|
* drawingHandler({context, tile, rendered})
|
||||||
|
*/
|
||||||
|
_drawTile: function( tile ) {
|
||||||
|
$.console.assert(tile, '[Drawer._drawTile] tile is required');
|
||||||
|
|
||||||
|
this._drawTileToHTML( tile, this.canvas );
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @inner
|
||||||
|
* Renders the tile in an html container.
|
||||||
|
* @function
|
||||||
|
* @param {OpenSeadragon.Tile} tile
|
||||||
|
* @param {Element} container
|
||||||
|
*/
|
||||||
|
_drawTileToHTML: function( tile, container ) {
|
||||||
|
if (!tile.cacheImageRecord) {
|
||||||
|
$.console.warn(
|
||||||
|
'[Drawer._drawTileToHTML] attempting to draw tile %s when it\'s not cached',
|
||||||
|
tile.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !tile.loaded ) {
|
||||||
|
$.console.warn(
|
||||||
|
"Attempting to draw tile %s when it's not yet loaded.",
|
||||||
|
tile.toString()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//EXPERIMENTAL - trying to figure out how to scale the container
|
||||||
|
// content during animation of the container size.
|
||||||
|
|
||||||
|
if ( !tile.element ) {
|
||||||
|
var image = tile.getImage();
|
||||||
|
if (!image) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.element = $.makeNeutralElement( "div" );
|
||||||
|
tile.imgElement = image.cloneNode();
|
||||||
|
tile.imgElement.style.msInterpolationMode = "nearest-neighbor";
|
||||||
|
tile.imgElement.style.width = "100%";
|
||||||
|
tile.imgElement.style.height = "100%";
|
||||||
|
|
||||||
|
tile.style = tile.element.style;
|
||||||
|
tile.style.position = "absolute";
|
||||||
|
}
|
||||||
|
if ( tile.element.parentNode !== container ) {
|
||||||
|
container.appendChild( tile.element );
|
||||||
|
}
|
||||||
|
if ( tile.imgElement.parentNode !== tile.element ) {
|
||||||
|
tile.element.appendChild( tile.imgElement );
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.style.top = tile.position.y + "px";
|
||||||
|
tile.style.left = tile.position.x + "px";
|
||||||
|
tile.style.height = tile.size.y + "px";
|
||||||
|
tile.style.width = tile.size.x + "px";
|
||||||
|
|
||||||
|
if (tile.flipped) {
|
||||||
|
tile.style.transform = "scaleX(-1)";
|
||||||
|
}
|
||||||
|
|
||||||
|
$.setElementOpacity( tile.element, tile.opacity );
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}( OpenSeadragon ));
|
@ -433,13 +433,20 @@ $.Viewer = function( options ) {
|
|||||||
throw('Viewer option customDrawer must derive from OpenSeadragon.DrawerBase');
|
throw('Viewer option customDrawer must derive from OpenSeadragon.DrawerBase');
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else if(this.useCanvas && $.supportsCanvas) {
|
||||||
this.drawer = new $.Drawer({
|
this.drawer = new $.Drawer({
|
||||||
viewer: this,
|
viewer: this,
|
||||||
viewport: this.viewport,
|
viewport: this.viewport,
|
||||||
element: this.canvas,
|
element: this.canvas,
|
||||||
debugGridColor: this.debugGridColor
|
debugGridColor: this.debugGridColor
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
this.drawer = new $.HTMLDrawer({
|
||||||
|
viewer: this,
|
||||||
|
viewport: this.viewport,
|
||||||
|
element: this.canvas,
|
||||||
|
debugGridColor: this.debugGridColor
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,10 +27,11 @@ var viewer = window.viewer = OpenSeadragon({
|
|||||||
maxZoomPixelRatio:100,
|
maxZoomPixelRatio:100,
|
||||||
smoothTileEdgesMinZoom:1.1,
|
smoothTileEdgesMinZoom:1.1,
|
||||||
crossOriginPolicy: 'Anonymous',
|
crossOriginPolicy: 'Anonymous',
|
||||||
ajaxWithCredentials: false
|
ajaxWithCredentials: false,
|
||||||
|
useCanvas:false,
|
||||||
});
|
});
|
||||||
|
|
||||||
let threeRenderer = window.threeRenderer = new ThreeJSDrawer({viewer, viewport: viewer.viewport, element:viewer.element});
|
// let threeRenderer = window.threeRenderer = new ThreeJSDrawer({viewer, viewport: viewer.viewport, element:viewer.element});
|
||||||
|
|
||||||
var viewer2 = window.viewer2 = OpenSeadragon({
|
var viewer2 = window.viewer2 = OpenSeadragon({
|
||||||
id: "three-viewer",
|
id: "three-viewer",
|
||||||
@ -45,15 +46,15 @@ var viewer2 = window.viewer2 = OpenSeadragon({
|
|||||||
});
|
});
|
||||||
|
|
||||||
//make the test canvas mirror all changes to the viewer canvas
|
//make the test canvas mirror all changes to the viewer canvas
|
||||||
let viewerCanvas = viewer.drawer.canvas;
|
// let viewerCanvas = viewer.drawer.canvas;
|
||||||
let canvas = threeRenderer.canvas;
|
// let canvas = threeRenderer.canvas;
|
||||||
let canvasContainer = $('#three-canvas-container').append(canvas);
|
// let canvasContainer = $('#three-canvas-container').append(canvas);
|
||||||
viewer.addHandler("resize", function(){
|
// viewer.addHandler("resize", function(){
|
||||||
canvasContainer[0].style.width = viewerCanvas.clientWidth+'px';
|
// canvasContainer[0].style.width = viewerCanvas.clientWidth+'px';
|
||||||
canvasContainer[0].style.height = viewerCanvas.clientHeight+'px';
|
// canvasContainer[0].style.height = viewerCanvas.clientHeight+'px';
|
||||||
// canvas.width = viewerCanvas.width;
|
// // canvas.width = viewerCanvas.width;
|
||||||
// canvas.height = viewerCanvas.height;
|
// // canvas.height = viewerCanvas.height;
|
||||||
})
|
// })
|
||||||
|
|
||||||
|
|
||||||
// viewer.addHandler("open", () => viewer.world.getItemAt(0).source.hasTransparency = function(){ return true; });
|
// viewer.addHandler("open", () => viewer.world.getItemAt(0).source.hasTransparency = function(){ return true; });
|
||||||
|
Loading…
Reference in New Issue
Block a user