mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 14:46:10 +03:00
convert DrawerBase and drawer implementations to classes; add html drawer to the demo page
This commit is contained in:
parent
8fda8ceae7
commit
354590a17a
@ -44,40 +44,39 @@
|
||||
* @param {Element} options.element - Parent element.
|
||||
* @param {Number} [options.debugGridColor] - See debugGridColor in {@link OpenSeadragon.Options} for details.
|
||||
*/
|
||||
$.CanvasDrawer = function(options) {
|
||||
|
||||
$.DrawerBase.call(this, options);
|
||||
class CanvasDrawer extends $.DrawerBase{
|
||||
constructor(options){
|
||||
super(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 = this.canvas.getContext( '2d' );
|
||||
/**
|
||||
* 2d drawing context for {@link OpenSeadragon.Drawer#canvas} if it's a <canvas> element, otherwise null.
|
||||
* @member {Object} context
|
||||
* @memberof OpenSeadragon.Drawer#
|
||||
*/
|
||||
this.context = this.canvas.getContext( '2d' );
|
||||
|
||||
/**
|
||||
* Sketch canvas used to temporarily draw tiles which cannot be drawn directly
|
||||
* to the main canvas due to opacity. Lazily initialized.
|
||||
*/
|
||||
this.sketchCanvas = null;
|
||||
this.sketchContext = null;
|
||||
/**
|
||||
* Sketch canvas used to temporarily draw tiles which cannot be drawn directly
|
||||
* to the main canvas due to opacity. Lazily initialized.
|
||||
*/
|
||||
this.sketchCanvas = null;
|
||||
this.sketchContext = 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';
|
||||
// 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';
|
||||
|
||||
// Image smoothing for canvas rendering (only if canvas is used).
|
||||
// Canvas default is "true", so this will only be changed if user specified "false".
|
||||
this._imageSmoothingEnabled = true;
|
||||
};
|
||||
|
||||
$.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadragon.Drawer.prototype */ {
|
||||
// Image smoothing for canvas rendering (only if canvas is used).
|
||||
// Canvas default is "true", so this will only be changed if user specified "false".
|
||||
this._imageSmoothingEnabled = true;
|
||||
|
||||
}
|
||||
/**
|
||||
* Draws the TiledImages
|
||||
*/
|
||||
draw: function(tiledImages) {
|
||||
draw(tiledImages) {
|
||||
var _this = this;
|
||||
this._prepareNewFrame(); // prepare to draw a new frame
|
||||
tiledImages.forEach(function(tiledImage){
|
||||
@ -89,26 +88,25 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
tiledImage._needsDraw = false;
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Boolean} True - rotation is supported.
|
||||
*/
|
||||
canRotate: function() {
|
||||
canRotate() {
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the drawer (unload current loaded tiles)
|
||||
*/
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
//force unloading of current canvas (1x1 will be gc later, trick not necessarily needed)
|
||||
this.canvas.width = 1;
|
||||
this.canvas.height = 1;
|
||||
this.sketchCanvas = null;
|
||||
this.sketchContext = null;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns image smoothing on or off for this viewer. Note: Ignored in some (especially older) browsers that do not support this property.
|
||||
@ -118,17 +116,17 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* drawn smoothly on the canvas; see imageSmoothingEnabled in
|
||||
* {@link OpenSeadragon.Options} for more explanation.
|
||||
*/
|
||||
setImageSmoothingEnabled: function(imageSmoothingEnabled){
|
||||
setImageSmoothingEnabled(imageSmoothingEnabled){
|
||||
this._imageSmoothingEnabled = imageSmoothingEnabled;
|
||||
this._updateImageSmoothingEnabled(this.context);
|
||||
this.viewer.forceRedraw();
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a rectangle onto the canvas
|
||||
* @param {OpenSeadragon.Rect} rect
|
||||
*/
|
||||
drawDebuggingRect: function(rect) {
|
||||
drawDebuggingRect(rect) {
|
||||
var context = this.context;
|
||||
context.save();
|
||||
context.lineWidth = 2 * $.pixelDensityRatio;
|
||||
@ -143,8 +141,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
);
|
||||
|
||||
context.restore();
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -152,7 +149,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* Clears the Drawer so it's ready to draw another frame.
|
||||
*
|
||||
*/
|
||||
_prepareNewFrame: function() {
|
||||
_prepareNewFrame() {
|
||||
var viewportSize = this._calculateCanvasSize();
|
||||
if( this.canvas.width !== viewportSize.x ||
|
||||
this.canvas.height !== viewportSize.y ) {
|
||||
@ -167,8 +164,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
}
|
||||
}
|
||||
this._clear();
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -176,7 +172,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* @param {Boolean} useSketch Whether to clear sketch canvas or main canvas
|
||||
* @param {OpenSeadragon.Rect} [bounds] The rectangle to clear
|
||||
*/
|
||||
_clear: function(useSketch, bounds){
|
||||
_clear(useSketch, bounds){
|
||||
var context = this._getContext(useSketch);
|
||||
if (bounds) {
|
||||
context.clearRect(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
@ -184,106 +180,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
var canvas = context.canvas;
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
},
|
||||
|
||||
/* 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
|
||||
@ -291,7 +188,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* Draws a TiledImage.
|
||||
*
|
||||
*/
|
||||
_drawTiles: function( tiledImage ) {
|
||||
_drawTiles( tiledImage ) {
|
||||
var lastDrawn = tiledImage.lastDrawn;
|
||||
if (tiledImage.opacity === 0 || (lastDrawn.length === 0 && !tiledImage.placeholderFillStyle)) {
|
||||
return;
|
||||
@ -532,7 +429,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
}
|
||||
|
||||
this._drawDebugInfo( tiledImage, lastDrawn );
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -540,7 +437,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* Draws special debug information for a TiledImage if in debug mode.
|
||||
* @param {OpenSeadragon.Tile[]} lastDrawn - An unordered list of Tiles drawn last frame.
|
||||
*/
|
||||
_drawDebugInfo: function( tiledImage, lastDrawn ) {
|
||||
_drawDebugInfo( tiledImage, lastDrawn ) {
|
||||
if( tiledImage.debugMode ) {
|
||||
for ( var i = lastDrawn.length - 1; i >= 0; i-- ) {
|
||||
var tile = lastDrawn[ i ];
|
||||
@ -551,7 +448,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/* Methods from Tile */
|
||||
|
||||
@ -563,7 +460,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* @param {OpenSeadragon.Point[][]} polygons - an array of polygons. A polygon is an array of OpenSeadragon.Point
|
||||
* @param {Boolean} useSketch - Whether to use the sketch canvas or not.
|
||||
*/
|
||||
_clipWithPolygons: function (polygons, useSketch) {
|
||||
_clipWithPolygons (polygons, useSketch) {
|
||||
var context = this._getContext(useSketch);
|
||||
context.beginPath();
|
||||
polygons.forEach(function (polygon) {
|
||||
@ -572,7 +469,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
});
|
||||
});
|
||||
context.clip();
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -590,7 +487,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* context.
|
||||
* @param {OpenSeadragon.TileSource} source - The source specification of the tile.
|
||||
*/
|
||||
_drawTile: function( tile, drawingHandler, useSketch, scale, translate, shouldRoundPositionAndSize, source) {
|
||||
_drawTile( tile, drawingHandler, useSketch, scale, translate, shouldRoundPositionAndSize, source) {
|
||||
$.console.assert(tile, '[Drawer._drawTile] tile is required');
|
||||
$.console.assert(drawingHandler, '[Drawer._drawTile] drawingHandler is required');
|
||||
|
||||
@ -598,7 +495,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
scale = scale || 1;
|
||||
this._drawTileToCanvas(tile, context, drawingHandler, scale, translate, shouldRoundPositionAndSize, source);
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -617,7 +514,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* context.
|
||||
* @param {OpenSeadragon.TileSource} source - The source specification of the tile.
|
||||
*/
|
||||
_drawTileToCanvas: function( tile, context, drawingHandler, scale, translate, shouldRoundPositionAndSize, source) {
|
||||
_drawTileToCanvas( tile, context, drawingHandler, scale, translate, shouldRoundPositionAndSize, source) {
|
||||
|
||||
var position = tile.position.times($.pixelDensityRatio),
|
||||
size = tile.size.times($.pixelDensityRatio),
|
||||
@ -708,68 +605,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
);
|
||||
|
||||
context.restore();
|
||||
},
|
||||
|
||||
/**
|
||||
* @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 );
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -778,7 +614,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* @param {Boolean} useSketch
|
||||
* @returns
|
||||
*/
|
||||
_getContext: function( useSketch ) {
|
||||
_getContext( useSketch ) {
|
||||
var context = this.context;
|
||||
if ( useSketch ) {
|
||||
if (this.sketchCanvas === null) {
|
||||
@ -808,7 +644,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
context = this.sketchContext;
|
||||
}
|
||||
return context;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -817,9 +653,9 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* @param {Boolean} useSketch
|
||||
* @returns
|
||||
*/
|
||||
_saveContext: function( useSketch ) {
|
||||
_saveContext( useSketch ) {
|
||||
this._getContext( useSketch ).save();
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -828,26 +664,26 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* @param {Boolean} useSketch
|
||||
* @returns
|
||||
*/
|
||||
_restoreContext: function( useSketch ) {
|
||||
_restoreContext( useSketch ) {
|
||||
this._getContext( useSketch ).restore();
|
||||
},
|
||||
}
|
||||
|
||||
// private
|
||||
_setClip: function(rect, useSketch) {
|
||||
_setClip(rect, useSketch) {
|
||||
var context = this._getContext( useSketch );
|
||||
context.beginPath();
|
||||
context.rect(rect.x, rect.y, rect.width, rect.height);
|
||||
context.clip();
|
||||
},
|
||||
}
|
||||
|
||||
// private
|
||||
_drawRectangle: function(rect, fillStyle, useSketch) {
|
||||
_drawRectangle(rect, fillStyle, useSketch) {
|
||||
var context = this._getContext( useSketch );
|
||||
context.save();
|
||||
context.fillStyle = fillStyle;
|
||||
context.fillRect(rect.x, rect.y, rect.width, rect.height);
|
||||
context.restore();
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Blends the sketch canvas in the main canvas.
|
||||
@ -865,7 +701,7 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* canvas to blend in the main canvas. If specified, options.scale and
|
||||
* options.translate get ignored.
|
||||
*/
|
||||
blendSketch: function(opacity, scale, translate, compositeOperation) {
|
||||
blendSketch(opacity, scale, translate, compositeOperation) {
|
||||
var options = opacity;
|
||||
if (!$.isPlainObject(options)) {
|
||||
options = {
|
||||
@ -942,10 +778,10 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
);
|
||||
}
|
||||
this.context.restore();
|
||||
},
|
||||
}
|
||||
|
||||
// private
|
||||
drawDebugInfo: function(tile, count, i, tiledImage) {
|
||||
drawDebugInfo(tile, count, i, tiledImage) {
|
||||
|
||||
var colorIndex = this.viewer.world.getIndexOfItem(tiledImage) % this.debugGridColor.length;
|
||||
var context = this.context;
|
||||
@ -1045,13 +881,13 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
}
|
||||
|
||||
context.restore();
|
||||
},
|
||||
}
|
||||
|
||||
// private
|
||||
_updateImageSmoothingEnabled: function(context){
|
||||
_updateImageSmoothingEnabled(context){
|
||||
context.msImageSmoothingEnabled = this._imageSmoothingEnabled;
|
||||
context.imageSmoothingEnabled = this._imageSmoothingEnabled;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -1060,10 +896,10 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* @param {Boolean} sketch If set to true return the size of the sketch canvas
|
||||
* @returns {OpenSeadragon.Point} The size of the canvas
|
||||
*/
|
||||
_getCanvasSize: function(sketch) {
|
||||
_getCanvasSize(sketch) {
|
||||
var canvas = this._getContext(sketch).canvas;
|
||||
return new $.Point(canvas.width, canvas.height);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -1072,12 +908,12 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
* @param {Boolean} sketch If set to true return the center point of the sketch canvas
|
||||
* @returns {OpenSeadragon.Point} The center point of the canvas
|
||||
*/
|
||||
_getCanvasCenter: function() {
|
||||
_getCanvasCenter() {
|
||||
return new $.Point(this.canvas.width / 2, this.canvas.height / 2);
|
||||
},
|
||||
}
|
||||
|
||||
// private
|
||||
_offsetForRotation: function(options) {
|
||||
_offsetForRotation(options) {
|
||||
var point = options.point ?
|
||||
options.point.times($.pixelDensityRatio) :
|
||||
this._getCanvasCenter();
|
||||
@ -1093,10 +929,10 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
context.rotate(Math.PI / 180 * options.degrees);
|
||||
}
|
||||
context.translate(-point.x, -point.y);
|
||||
},
|
||||
}
|
||||
|
||||
// private
|
||||
_flip: function(options) {
|
||||
_flip(options) {
|
||||
options = options || {};
|
||||
var point = options.point ?
|
||||
options.point.times($.pixelDensityRatio) :
|
||||
@ -1106,16 +942,16 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
context.translate(point.x, 0);
|
||||
context.scale(-1, 1);
|
||||
context.translate(-point.x, 0);
|
||||
},
|
||||
}
|
||||
|
||||
// private
|
||||
_restoreRotationChanges: function(useSketch) {
|
||||
_restoreRotationChanges(useSketch) {
|
||||
var context = this._getContext(useSketch);
|
||||
context.restore();
|
||||
},
|
||||
}
|
||||
|
||||
// private
|
||||
_calculateCanvasSize: function() {
|
||||
_calculateCanvasSize() {
|
||||
var pixelDensityRatio = $.pixelDensityRatio;
|
||||
var viewportSize = this.viewport.getContainerSize();
|
||||
return {
|
||||
@ -1123,10 +959,10 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
x: Math.round(viewportSize.x * pixelDensityRatio),
|
||||
y: Math.round(viewportSize.y * pixelDensityRatio)
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
// private
|
||||
_calculateSketchCanvasSize: function() {
|
||||
_calculateSketchCanvasSize() {
|
||||
var canvasSize = this._calculateCanvasSize();
|
||||
if (this.viewport.getRotation() === 0) {
|
||||
return canvasSize;
|
||||
@ -1140,11 +976,9 @@ $.extend( $.CanvasDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadr
|
||||
x: sketchCanvasSize,
|
||||
y: sketchCanvasSize
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
$.CanvasDrawer = CanvasDrawer;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -43,119 +43,113 @@
|
||||
* @param {OpenSeadragon.Viewport} options.viewport - Reference to Viewer viewport.
|
||||
* @param {Element} options.element - Parent element.
|
||||
*/
|
||||
$.DrawerBase = function( options ) {
|
||||
|
||||
$.console.assert( options.viewer, "[Drawer] options.viewer is required" );
|
||||
class DrawerBase{
|
||||
constructor(options){
|
||||
$.console.assert( options.viewer, "[Drawer] options.viewer is required" );
|
||||
|
||||
//backward compatibility for positional args while preferring more
|
||||
//idiomatic javascript options object as the only argument
|
||||
var args = arguments;
|
||||
//backward compatibility for positional args while preferring more
|
||||
//idiomatic javascript options object as the only argument
|
||||
var args = arguments;
|
||||
|
||||
if( !$.isPlainObject( options ) ){
|
||||
options = {
|
||||
source: args[ 0 ], // Reference to Viewer tile source.
|
||||
viewport: args[ 1 ], // Reference to Viewer viewport.
|
||||
element: args[ 2 ] // Parent element.
|
||||
};
|
||||
if( !$.isPlainObject( options ) ){
|
||||
options = {
|
||||
source: args[ 0 ], // Reference to Viewer tile source.
|
||||
viewport: args[ 1 ], // Reference to Viewer viewport.
|
||||
element: args[ 2 ] // Parent element.
|
||||
};
|
||||
}
|
||||
|
||||
$.console.assert( options.viewport, "[Drawer] options.viewport is required" );
|
||||
$.console.assert( options.element, "[Drawer] options.element is required" );
|
||||
|
||||
if ( options.source ) {
|
||||
$.console.error( "[Drawer] options.source is no longer accepted; use TiledImage instead" );
|
||||
}
|
||||
|
||||
this.viewer = options.viewer;
|
||||
this.viewport = options.viewport;
|
||||
this.debugGridColor = typeof options.debugGridColor === 'string' ? [options.debugGridColor] : options.debugGridColor || $.DEFAULT_SETTINGS.debugGridColor;
|
||||
|
||||
if (options.opacity) {
|
||||
$.console.error( "[Drawer] options.opacity is no longer accepted; set the opacity on the TiledImage instead" );
|
||||
}
|
||||
|
||||
this.useCanvas = $.supportsCanvas && ( this.viewer ? this.viewer.useCanvas : true );
|
||||
/**
|
||||
* The parent element of this Drawer instance, passed in when the Drawer was created.
|
||||
* The parent of {@link OpenSeadragon.DrawerBase#canvas}.
|
||||
* @member {Element} container
|
||||
* @memberof OpenSeadragon.DrawerBase#
|
||||
*/
|
||||
this.container = $.getElement( options.element );
|
||||
/**
|
||||
* A <canvas> element if the browser supports them, otherwise a <div> element.
|
||||
* Child element of {@link OpenSeadragon.DrawerBase#container}.
|
||||
* @member {Element} canvas
|
||||
* @memberof OpenSeadragon.DrawerBase#
|
||||
*/
|
||||
this.canvas = $.makeNeutralElement( this.useCanvas ? "canvas" : "div" );
|
||||
|
||||
|
||||
/**
|
||||
* @member {Element} element
|
||||
* @memberof OpenSeadragon.DrawerBase#
|
||||
* @deprecated Alias for {@link OpenSeadragon.DrawerBase#container}.
|
||||
*/
|
||||
this.element = this.container;
|
||||
|
||||
// TO DO: Does this need to be in DrawerBase, or only in Drawer implementations?
|
||||
// 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';
|
||||
|
||||
if (this.useCanvas) {
|
||||
var viewportSize = this._calculateCanvasSize();
|
||||
this.canvas.width = viewportSize.x;
|
||||
this.canvas.height = viewportSize.y;
|
||||
}
|
||||
|
||||
this.canvas.style.width = "100%";
|
||||
this.canvas.style.height = "100%";
|
||||
this.canvas.style.position = "absolute";
|
||||
$.setElementOpacity( this.canvas, this.opacity, true );
|
||||
|
||||
// Allow pointer events to pass through the canvas element so implicit
|
||||
// pointer capture works on touch devices
|
||||
$.setElementPointerEventsNone( this.canvas );
|
||||
$.setElementTouchActionNone( this.canvas );
|
||||
|
||||
// explicit left-align
|
||||
this.container.style.textAlign = "left";
|
||||
this.container.appendChild( this.canvas );
|
||||
|
||||
this._checkForAPIOverrides();
|
||||
}
|
||||
|
||||
$.console.assert( options.viewport, "[Drawer] options.viewport is required" );
|
||||
$.console.assert( options.element, "[Drawer] options.element is required" );
|
||||
|
||||
if ( options.source ) {
|
||||
$.console.error( "[Drawer] options.source is no longer accepted; use TiledImage instead" );
|
||||
get isOpenSeadragonDrawer(){
|
||||
return true;
|
||||
}
|
||||
|
||||
this.viewer = options.viewer;
|
||||
this.viewport = options.viewport;
|
||||
this.debugGridColor = typeof options.debugGridColor === 'string' ? [options.debugGridColor] : options.debugGridColor || $.DEFAULT_SETTINGS.debugGridColor;
|
||||
|
||||
if (options.opacity) {
|
||||
$.console.error( "[Drawer] options.opacity is no longer accepted; set the opacity on the TiledImage instead" );
|
||||
}
|
||||
|
||||
this.useCanvas = $.supportsCanvas && ( this.viewer ? this.viewer.useCanvas : true );
|
||||
/**
|
||||
* The parent element of this Drawer instance, passed in when the Drawer was created.
|
||||
* The parent of {@link OpenSeadragon.DrawerBase#canvas}.
|
||||
* @member {Element} container
|
||||
* @memberof OpenSeadragon.DrawerBase#
|
||||
*/
|
||||
this.container = $.getElement( options.element );
|
||||
/**
|
||||
* A <canvas> element if the browser supports them, otherwise a <div> element.
|
||||
* Child element of {@link OpenSeadragon.DrawerBase#container}.
|
||||
* @member {Element} canvas
|
||||
* @memberof OpenSeadragon.DrawerBase#
|
||||
*/
|
||||
this.canvas = $.makeNeutralElement( this.useCanvas ? "canvas" : "div" );
|
||||
|
||||
|
||||
/**
|
||||
* @member {Element} element
|
||||
* @memberof OpenSeadragon.DrawerBase#
|
||||
* @deprecated Alias for {@link OpenSeadragon.DrawerBase#container}.
|
||||
*/
|
||||
this.element = this.container;
|
||||
|
||||
// TO DO: Does this need to be in DrawerBase, or only in Drawer implementations?
|
||||
// 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';
|
||||
|
||||
if (this.useCanvas) {
|
||||
var viewportSize = this._calculateCanvasSize();
|
||||
this.canvas.width = viewportSize.x;
|
||||
this.canvas.height = viewportSize.y;
|
||||
}
|
||||
|
||||
this.canvas.style.width = "100%";
|
||||
this.canvas.style.height = "100%";
|
||||
this.canvas.style.position = "absolute";
|
||||
$.setElementOpacity( this.canvas, this.opacity, true );
|
||||
|
||||
// Allow pointer events to pass through the canvas element so implicit
|
||||
// pointer capture works on touch devices
|
||||
$.setElementPointerEventsNone( this.canvas );
|
||||
$.setElementTouchActionNone( this.canvas );
|
||||
|
||||
// explicit left-align
|
||||
this.container.style.textAlign = "left";
|
||||
this.container.appendChild( this.canvas );
|
||||
|
||||
this._checkForAPIOverrides();
|
||||
};
|
||||
|
||||
/** @lends OpenSeadragon.DrawerBaseBase.prototype */
|
||||
$.DrawerBase.prototype = {
|
||||
|
||||
// Drawer implementaions must define the next four methods. These are called
|
||||
// by core OSD and/or public APIs, and forcing overrides (even for nullop methods) makes the
|
||||
// behavior of the implementations explicitly clear in the code.
|
||||
// Whether these have been overridden by child classes is checked in the
|
||||
// constructor (via _checkForAPIOverrides).
|
||||
|
||||
/**
|
||||
* @param tiledImage the TiledImage that is ready to be drawn
|
||||
*/
|
||||
draw: function(tiledImage) {
|
||||
draw(tiledImage) {
|
||||
$.console.error('Drawer.draw must be implemented by child class');
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Boolean} True if rotation is supported.
|
||||
*/
|
||||
canRotate: function() {
|
||||
canRotate() {
|
||||
$.console.error('Drawer.canRotate must be implemented by child class');
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the drawer (unload current loaded tiles)
|
||||
*/
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
$.console.error('Drawer.destroy must be implemented by child class');
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns image smoothing on or off for this viewer. Note: Ignored in some (especially older) browsers that do not support this property.
|
||||
@ -165,23 +159,23 @@ $.DrawerBase.prototype = {
|
||||
* drawn smoothly on the canvas; see imageSmoothingEnabled in
|
||||
* {@link OpenSeadragon.Options} for more explanation.
|
||||
*/
|
||||
setImageSmoothingEnabled: function(imageSmoothingEnabled){
|
||||
setImageSmoothingEnabled(imageSmoothingEnabled){
|
||||
$.console.error('Drawer.setImageSmoothingEnabled must be implemented by child class');
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional public API to draw a rectangle (e.g. for debugging purposes)
|
||||
* Child classes can override this method if they wish to support this
|
||||
* @param {OpenSeadragon.Rect} rect
|
||||
*/
|
||||
drawDebuggingRect: function(rect) {
|
||||
drawDebuggingRect(rect) {
|
||||
$.console.warn('[drawer].drawDebuggingRect is not implemented by this drawer');
|
||||
},
|
||||
}
|
||||
|
||||
// Deprecated functions
|
||||
clear: function(){
|
||||
clear(){
|
||||
$.console.warn('[drawer].clear() is deprecated. The drawer is responsible for clearing itself as needed before drawing tiles.');
|
||||
},
|
||||
}
|
||||
|
||||
// Private functions
|
||||
|
||||
@ -192,7 +186,7 @@ $.DrawerBase.prototype = {
|
||||
* draw, canRotate, destroy, and setImageSmoothinEnabled. Throws an exception if the original
|
||||
* placeholder methods are still in place.
|
||||
*/
|
||||
_checkForAPIOverrides: function(){
|
||||
_checkForAPIOverrides(){
|
||||
if(this.draw === $.DrawerBase.prototype.draw){
|
||||
throw("[drawer].draw must be implemented by child class");
|
||||
}
|
||||
@ -206,7 +200,7 @@ $.DrawerBase.prototype = {
|
||||
if(this.setImageSmoothingEnabled === $.DrawerBase.prototype.setImageSmoothingEnabled){
|
||||
throw("[drawer].setImageSmoothingEnabled must be implemented by child class");
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
// Utility functions internal API
|
||||
@ -219,7 +213,7 @@ $.DrawerBase.prototype = {
|
||||
* @param {OpenSeadragon.Rect} rectangle - The rectangle in viewport coordinate system.
|
||||
* @returns {OpenSeadragon.Rect} Rectangle in drawer coordinate system.
|
||||
*/
|
||||
_viewportToDrawerRectangle: function(rectangle) {
|
||||
_viewportToDrawerRectangle(rectangle) {
|
||||
var topLeft = this.viewport.pixelFromPointNoRotate(rectangle.getTopLeft(), true);
|
||||
var size = this.viewport.deltaPixelsFromPointsNoRotate(rectangle.getSize(), true);
|
||||
|
||||
@ -229,7 +223,7 @@ $.DrawerBase.prototype = {
|
||||
size.x * $.pixelDensityRatio,
|
||||
size.y * $.pixelDensityRatio
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -241,13 +235,13 @@ $.DrawerBase.prototype = {
|
||||
* @param {OpenSeadragon.Point} point - the pixel point to convert
|
||||
* @returns {OpenSeadragon.Point} Point in drawer coordinate system.
|
||||
*/
|
||||
_viewportCoordToDrawerCoord: function(point) {
|
||||
_viewportCoordToDrawerCoord(point) {
|
||||
var vpPoint = this.viewport.pixelFromPointNoRotate(point, true);
|
||||
return new $.Point(
|
||||
vpPoint.x * $.pixelDensityRatio,
|
||||
vpPoint.y * $.pixelDensityRatio
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -256,7 +250,7 @@ $.DrawerBase.prototype = {
|
||||
* and pixelDensityRatio
|
||||
* @returns {Dictionary} {x, y} size of the canvas
|
||||
*/
|
||||
_calculateCanvasSize: function() {
|
||||
_calculateCanvasSize() {
|
||||
var pixelDensityRatio = $.pixelDensityRatio;
|
||||
var viewportSize = this.viewport.getContainerSize();
|
||||
return {
|
||||
@ -264,15 +258,240 @@ $.DrawerBase.prototype = {
|
||||
x: Math.round(viewportSize.x * pixelDensityRatio),
|
||||
y: Math.round(viewportSize.y * pixelDensityRatio)
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
Object.defineProperty($.DrawerBase.prototype, "isOpenSeadragonDrawer", {
|
||||
get: function get() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
$.DrawerBase = DrawerBase;
|
||||
// $.DrawerBase = function( options ) {
|
||||
|
||||
// $.console.assert( options.viewer, "[Drawer] options.viewer is required" );
|
||||
|
||||
// //backward compatibility for positional args while preferring more
|
||||
// //idiomatic javascript options object as the only argument
|
||||
// var args = arguments;
|
||||
|
||||
// if( !$.isPlainObject( options ) ){
|
||||
// options = {
|
||||
// source: args[ 0 ], // Reference to Viewer tile source.
|
||||
// viewport: args[ 1 ], // Reference to Viewer viewport.
|
||||
// element: args[ 2 ] // Parent element.
|
||||
// };
|
||||
// }
|
||||
|
||||
// $.console.assert( options.viewport, "[Drawer] options.viewport is required" );
|
||||
// $.console.assert( options.element, "[Drawer] options.element is required" );
|
||||
|
||||
// if ( options.source ) {
|
||||
// $.console.error( "[Drawer] options.source is no longer accepted; use TiledImage instead" );
|
||||
// }
|
||||
|
||||
// this.viewer = options.viewer;
|
||||
// this.viewport = options.viewport;
|
||||
// this.debugGridColor = typeof options.debugGridColor === 'string' ? [options.debugGridColor] : options.debugGridColor || $.DEFAULT_SETTINGS.debugGridColor;
|
||||
|
||||
// if (options.opacity) {
|
||||
// $.console.error( "[Drawer] options.opacity is no longer accepted; set the opacity on the TiledImage instead" );
|
||||
// }
|
||||
|
||||
// this.useCanvas = $.supportsCanvas && ( this.viewer ? this.viewer.useCanvas : true );
|
||||
// /**
|
||||
// * The parent element of this Drawer instance, passed in when the Drawer was created.
|
||||
// * The parent of {@link OpenSeadragon.DrawerBase#canvas}.
|
||||
// * @member {Element} container
|
||||
// * @memberof OpenSeadragon.DrawerBase#
|
||||
// */
|
||||
// this.container = $.getElement( options.element );
|
||||
// /**
|
||||
// * A <canvas> element if the browser supports them, otherwise a <div> element.
|
||||
// * Child element of {@link OpenSeadragon.DrawerBase#container}.
|
||||
// * @member {Element} canvas
|
||||
// * @memberof OpenSeadragon.DrawerBase#
|
||||
// */
|
||||
// this.canvas = $.makeNeutralElement( this.useCanvas ? "canvas" : "div" );
|
||||
|
||||
|
||||
// /**
|
||||
// * @member {Element} element
|
||||
// * @memberof OpenSeadragon.DrawerBase#
|
||||
// * @deprecated Alias for {@link OpenSeadragon.DrawerBase#container}.
|
||||
// */
|
||||
// this.element = this.container;
|
||||
|
||||
// // TO DO: Does this need to be in DrawerBase, or only in Drawer implementations?
|
||||
// // 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';
|
||||
|
||||
// if (this.useCanvas) {
|
||||
// var viewportSize = this._calculateCanvasSize();
|
||||
// this.canvas.width = viewportSize.x;
|
||||
// this.canvas.height = viewportSize.y;
|
||||
// }
|
||||
|
||||
// this.canvas.style.width = "100%";
|
||||
// this.canvas.style.height = "100%";
|
||||
// this.canvas.style.position = "absolute";
|
||||
// $.setElementOpacity( this.canvas, this.opacity, true );
|
||||
|
||||
// // Allow pointer events to pass through the canvas element so implicit
|
||||
// // pointer capture works on touch devices
|
||||
// $.setElementPointerEventsNone( this.canvas );
|
||||
// $.setElementTouchActionNone( this.canvas );
|
||||
|
||||
// // explicit left-align
|
||||
// this.container.style.textAlign = "left";
|
||||
// this.container.appendChild( this.canvas );
|
||||
|
||||
// this._checkForAPIOverrides();
|
||||
// };
|
||||
|
||||
// /** @lends OpenSeadragon.DrawerBaseBase.prototype */
|
||||
// $.DrawerBase.prototype = {
|
||||
|
||||
// // Drawer implementaions must define the next four methods. These are called
|
||||
// // by core OSD and/or public APIs, and forcing overrides (even for nullop methods) makes the
|
||||
// // behavior of the implementations explicitly clear in the code.
|
||||
// // Whether these have been overridden by child classes is checked in the
|
||||
// // constructor (via _checkForAPIOverrides).
|
||||
|
||||
// /**
|
||||
// * @param tiledImage the TiledImage that is ready to be drawn
|
||||
// */
|
||||
// draw: function(tiledImage) {
|
||||
// $.console.error('Drawer.draw must be implemented by child class');
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * @returns {Boolean} True if rotation is supported.
|
||||
// */
|
||||
// canRotate: function() {
|
||||
// $.console.error('Drawer.canRotate must be implemented by child class');
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * Destroy the drawer (unload current loaded tiles)
|
||||
// */
|
||||
// destroy: function() {
|
||||
// $.console.error('Drawer.destroy must be implemented by child class');
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * Turns image smoothing on or off for this viewer. Note: Ignored in some (especially older) browsers that do not support this property.
|
||||
// *
|
||||
// * @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(imageSmoothingEnabled){
|
||||
// $.console.error('Drawer.setImageSmoothingEnabled must be implemented by child class');
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * Optional public API to draw a rectangle (e.g. for debugging purposes)
|
||||
// * Child classes can override this method if they wish to support this
|
||||
// * @param {OpenSeadragon.Rect} rect
|
||||
// */
|
||||
// drawDebuggingRect: function(rect) {
|
||||
// $.console.warn('[drawer].drawDebuggingRect is not implemented by this drawer');
|
||||
// },
|
||||
|
||||
// // Deprecated functions
|
||||
// clear: function(){
|
||||
// $.console.warn('[drawer].clear() is deprecated. The drawer is responsible for clearing itself as needed before drawing tiles.');
|
||||
// },
|
||||
|
||||
// // Private functions
|
||||
|
||||
// /**
|
||||
// * @private
|
||||
// * @inner
|
||||
// * Ensures that child classes have provided implementations for public API methods
|
||||
// * draw, canRotate, destroy, and setImageSmoothinEnabled. Throws an exception if the original
|
||||
// * placeholder methods are still in place.
|
||||
// */
|
||||
// _checkForAPIOverrides: function(){
|
||||
// if(this.draw === $.DrawerBase.prototype.draw){
|
||||
// throw("[drawer].draw must be implemented by child class");
|
||||
// }
|
||||
// if(this.canRotate === $.DrawerBase.prototype.canRotate){
|
||||
// throw("[drawer].canRotate must be implemented by child class");
|
||||
// }
|
||||
// if(this.destroy === $.DrawerBase.prototype.destroy){
|
||||
// throw("[drawer].destroy must be implemented by child class");
|
||||
// }
|
||||
|
||||
// if(this.setImageSmoothingEnabled === $.DrawerBase.prototype.setImageSmoothingEnabled){
|
||||
// throw("[drawer].setImageSmoothingEnabled must be implemented by child class");
|
||||
// }
|
||||
// },
|
||||
|
||||
|
||||
// // Utility functions internal API
|
||||
|
||||
// /**
|
||||
// * @private
|
||||
// * @inner
|
||||
// * Scale from OpenSeadragon viewer rectangle to drawer rectangle
|
||||
// * (ignoring rotation)
|
||||
// * @param {OpenSeadragon.Rect} rectangle - The rectangle in viewport coordinate system.
|
||||
// * @returns {OpenSeadragon.Rect} Rectangle in drawer coordinate system.
|
||||
// */
|
||||
// _viewportToDrawerRectangle: function(rectangle) {
|
||||
// var topLeft = this.viewport.pixelFromPointNoRotate(rectangle.getTopLeft(), true);
|
||||
// var size = this.viewport.deltaPixelsFromPointsNoRotate(rectangle.getSize(), true);
|
||||
|
||||
// return new $.Rect(
|
||||
// topLeft.x * $.pixelDensityRatio,
|
||||
// topLeft.y * $.pixelDensityRatio,
|
||||
// size.x * $.pixelDensityRatio,
|
||||
// size.y * $.pixelDensityRatio
|
||||
// );
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * @private
|
||||
// * @inner
|
||||
// * This function converts the given point from to the drawer coordinate by
|
||||
// * multiplying it with the pixel density.
|
||||
// * This function does not take rotation into account, thus assuming provided
|
||||
// * point is at 0 degree.
|
||||
// * @param {OpenSeadragon.Point} point - the pixel point to convert
|
||||
// * @returns {OpenSeadragon.Point} Point in drawer coordinate system.
|
||||
// */
|
||||
// _viewportCoordToDrawerCoord: function(point) {
|
||||
// var vpPoint = this.viewport.pixelFromPointNoRotate(point, true);
|
||||
// return new $.Point(
|
||||
// vpPoint.x * $.pixelDensityRatio,
|
||||
// vpPoint.y * $.pixelDensityRatio
|
||||
// );
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * @private
|
||||
// * @inner
|
||||
// * Calculate width and height of the canvas based on viewport dimensions
|
||||
// * and pixelDensityRatio
|
||||
// * @returns {Dictionary} {x, y} size of the canvas
|
||||
// */
|
||||
// _calculateCanvasSize: function() {
|
||||
// var pixelDensityRatio = $.pixelDensityRatio;
|
||||
// var viewportSize = this.viewport.getContainerSize();
|
||||
// return {
|
||||
// // canvas width and height are integers
|
||||
// x: Math.round(viewportSize.x * pixelDensityRatio),
|
||||
// y: Math.round(viewportSize.y * pixelDensityRatio)
|
||||
// };
|
||||
// },
|
||||
|
||||
// };
|
||||
|
||||
// Object.defineProperty($.DrawerBase.prototype, "isOpenSeadragonDrawer", {
|
||||
// get: function get() {
|
||||
// return true;
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
}( OpenSeadragon ));
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* OpenSeadragon - Drawer
|
||||
* OpenSeadragon - HTMLDrawer
|
||||
*
|
||||
* Copyright (C) 2009 CodePlex Foundation
|
||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
||||
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
@ -44,36 +44,54 @@
|
||||
* @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);
|
||||
class HTMLDrawer extends $.DrawerBase{
|
||||
constructor(options){
|
||||
super(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;
|
||||
/**
|
||||
* 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';
|
||||
// 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';
|
||||
|
||||
};
|
||||
/**
|
||||
* Override default element to enforce div for HTMLDrawer
|
||||
*/
|
||||
this.canvas.parentNode.removeChild(this.canvas);
|
||||
this.canvas = $.makeNeutralElement( "div" );
|
||||
|
||||
$.extend( $.HTMLDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadragon.Drawer.prototype */ {
|
||||
this.canvas.style.width = "100%";
|
||||
this.canvas.style.height = "100%";
|
||||
this.canvas.style.position = "absolute";
|
||||
$.setElementOpacity( this.canvas, this.opacity, true );
|
||||
|
||||
// Allow pointer events to pass through the canvas element so implicit
|
||||
// pointer capture works on touch devices
|
||||
$.setElementPointerEventsNone( this.canvas );
|
||||
$.setElementTouchActionNone( this.canvas );
|
||||
|
||||
// explicit left-align
|
||||
this.container.style.textAlign = "left";
|
||||
this.container.appendChild( this.canvas );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the TiledImages
|
||||
*/
|
||||
draw: function(tiledImages) {
|
||||
draw(tiledImages) {
|
||||
var _this = this;
|
||||
this._prepareNewFrame(); // prepare to draw a new frame
|
||||
tiledImages.forEach(function(tiledImage){
|
||||
if (tiledImage.opacity !== 0 || tiledImage._preload) {
|
||||
// _this._updateViewportWithTiledImage(tiledImage);
|
||||
_this._drawTiles(tiledImage);
|
||||
}
|
||||
else {
|
||||
@ -81,23 +99,22 @@ $.extend( $.HTMLDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadrag
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Boolean} False - rotation is not supported.
|
||||
*/
|
||||
canRotate: function() {
|
||||
canRotate() {
|
||||
return false;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the drawer (unload current loaded tiles)
|
||||
*/
|
||||
destroy: function() {
|
||||
destroy() {
|
||||
//force unloading of current canvas (1x1 will be gc later, trick not necessarily needed)
|
||||
this.canvas.width = 1;
|
||||
this.canvas.height = 1;
|
||||
},
|
||||
this.canvas.innerHTML = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns image smoothing on or off for this viewer. Note: Ignored by HTML Drawer
|
||||
@ -107,10 +124,10 @@ $.extend( $.HTMLDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadrag
|
||||
* drawn smoothly on the canvas; see imageSmoothingEnabled in
|
||||
* {@link OpenSeadragon.Options} for more explanation.
|
||||
*/
|
||||
setImageSmoothingEnabled: function(){
|
||||
setImageSmoothingEnabled(){
|
||||
// noop - HTML Drawer does not deal with this property
|
||||
$.console.warn('HTMLDrawer.setImageSmoothingEnabled does not have an effect.');
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -118,108 +135,9 @@ $.extend( $.HTMLDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadrag
|
||||
* Clears the Drawer so it's ready to draw another frame.
|
||||
*
|
||||
*/
|
||||
_prepareNewFrame: function() {
|
||||
_prepareNewFrame() {
|
||||
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
|
||||
@ -227,7 +145,7 @@ $.extend( $.HTMLDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadrag
|
||||
* Draws a TiledImage.
|
||||
*
|
||||
*/
|
||||
_drawTiles: function( tiledImage ) {
|
||||
_drawTiles( tiledImage ) {
|
||||
var lastDrawn = tiledImage.lastDrawn;
|
||||
if (tiledImage.opacity === 0 || (lastDrawn.length === 0 && !tiledImage.placeholderFillStyle)) {
|
||||
return;
|
||||
@ -258,9 +176,7 @@ $.extend( $.HTMLDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadrag
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/* Methods from Tile */
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@ -270,22 +186,11 @@ $.extend( $.HTMLDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadrag
|
||||
* @param {Function} drawingHandler - Method for firing the drawing event if using canvas.
|
||||
* drawingHandler({context, tile, rendered})
|
||||
*/
|
||||
_drawTile: function( tile ) {
|
||||
_drawTile( tile ) {
|
||||
$.console.assert(tile, '[Drawer._drawTile] tile is required');
|
||||
|
||||
this._drawTileToHTML( tile, this.canvas );
|
||||
},
|
||||
let container = 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',
|
||||
@ -319,6 +224,7 @@ $.extend( $.HTMLDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadrag
|
||||
tile.style = tile.element.style;
|
||||
tile.style.position = "absolute";
|
||||
}
|
||||
|
||||
if ( tile.element.parentNode !== container ) {
|
||||
container.appendChild( tile.element );
|
||||
}
|
||||
@ -336,11 +242,11 @@ $.extend( $.HTMLDrawer.prototype, $.DrawerBase.prototype, /** @lends OpenSeadrag
|
||||
}
|
||||
|
||||
$.setElementOpacity( tile.element, tile.opacity );
|
||||
},
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$.HTMLDrawer = HTMLDrawer;
|
||||
|
||||
|
||||
}( OpenSeadragon ));
|
||||
|
@ -38,6 +38,7 @@
|
||||
border: thin black solid;
|
||||
padding:10px;
|
||||
display:inline-block;
|
||||
width:95%;
|
||||
}
|
||||
.description pre{
|
||||
display:inline-block;
|
||||
@ -164,9 +165,35 @@
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<h2>HTMLDrawer: legacy pre-HTML5 drawer that uses <img> elements for tiles</h2>
|
||||
<div class="mirrored">
|
||||
<div>
|
||||
<div class="description">
|
||||
HTML-based rendering can be selected in two different ways:
|
||||
</div>
|
||||
<pre class="example-code">
|
||||
// via the useCanvas option:
|
||||
let viewer = OpenSeadragon({
|
||||
...
|
||||
useCanvas: false,
|
||||
...
|
||||
});
|
||||
|
||||
// or by passing the HTMLDrawer constructor
|
||||
let viewer = OpenSeadragon({
|
||||
...
|
||||
customDrawer:OpenSeadragon.HTMLDrawer,
|
||||
...
|
||||
});
|
||||
</pre>
|
||||
</div>
|
||||
<div id="htmldrawer" class="viewer-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@ -69,6 +69,19 @@ var viewer2 = window.viewer2 = OpenSeadragon({
|
||||
ajaxWithCredentials: false
|
||||
});
|
||||
|
||||
// Single viewer showing how to use plugin Drawer via configuration
|
||||
// Also shows sequence mode
|
||||
var viewer3 = window.viewer3 = OpenSeadragon({
|
||||
id: "htmldrawer",
|
||||
prefixUrl: "../../build/openseadragon/images/",
|
||||
minZoomImageRatio:0.01,
|
||||
customDrawer: OpenSeadragon.HTMLDrawer,
|
||||
tileSources: [sources['leaves'], sources['rainbow'], sources['duomo']],
|
||||
sequenceMode: true,
|
||||
crossOriginPolicy: 'Anonymous',
|
||||
ajaxWithCredentials: false
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user