2023-03-12 18:42:03 +03:00
|
|
|
/*
|
2023-06-07 22:42:16 +03:00
|
|
|
* OpenSeadragon - HTMLDrawer
|
2023-03-12 18:42:03 +03:00
|
|
|
*
|
|
|
|
* Copyright (C) 2009 CodePlex Foundation
|
2023-12-15 03:14:05 +03:00
|
|
|
* Copyright (C) 2010-2024 OpenSeadragon contributors
|
2023-03-12 18:42:03 +03:00
|
|
|
*
|
|
|
|
* 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( $ ){
|
|
|
|
|
2024-02-01 22:24:25 +03:00
|
|
|
const OpenSeadragon = $; // alias back for JSDoc
|
|
|
|
|
2023-03-12 18:42:03 +03:00
|
|
|
/**
|
2024-02-01 22:24:25 +03:00
|
|
|
* @class OpenSeadragon.HTMLDrawer
|
|
|
|
* @extends OpenSeadragon.DrawerBase
|
2023-03-12 18:42:03 +03:00
|
|
|
* @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.
|
|
|
|
*/
|
|
|
|
|
2024-02-01 22:24:25 +03:00
|
|
|
class HTMLDrawer extends OpenSeadragon.DrawerBase{
|
2023-12-15 21:13:40 +03:00
|
|
|
constructor(options){
|
|
|
|
super(options);
|
2024-01-29 18:39:55 +03:00
|
|
|
|
2024-02-01 22:24:25 +03:00
|
|
|
/**
|
2024-02-01 22:29:10 +03:00
|
|
|
* The HTML element (div) that this drawer uses for drawing
|
2024-02-01 22:24:25 +03:00
|
|
|
* @member {Element} canvas
|
|
|
|
* @memberof OpenSeadragon.HTMLDrawer#
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The parent element of this Drawer instance, passed in when the Drawer was created.
|
|
|
|
* The parent of {@link OpenSeadragon.WebGLDrawer#canvas}.
|
|
|
|
* @member {Element} container
|
|
|
|
* @memberof OpenSeadragon.HTMLDrawer#
|
|
|
|
*/
|
|
|
|
|
2024-01-29 18:39:55 +03:00
|
|
|
// Reject listening for the tile-drawing event, which this drawer does not fire
|
|
|
|
this.viewer.rejectEventHandler("tile-drawing", "The HTMLDrawer does not raise the tile-drawing event");
|
2024-01-29 21:01:44 +03:00
|
|
|
// Since the tile-drawn event is fired by this drawer, make sure handlers can be added for it
|
|
|
|
this.viewer.allowEventHandler("tile-drawn");
|
2023-06-19 02:08:33 +03:00
|
|
|
}
|
2023-06-07 22:42:16 +03:00
|
|
|
|
2023-06-19 02:08:33 +03:00
|
|
|
/**
|
|
|
|
* @returns {Boolean} always true
|
|
|
|
*/
|
2023-06-30 04:55:59 +03:00
|
|
|
static isSupported(){
|
2023-06-19 02:08:33 +03:00
|
|
|
return true;
|
|
|
|
}
|
2023-06-07 22:42:16 +03:00
|
|
|
|
2024-02-01 22:24:25 +03:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @returns 'html'
|
|
|
|
*/
|
2023-07-09 19:05:17 +03:00
|
|
|
getType(){
|
2023-06-30 23:38:07 +03:00
|
|
|
return 'html';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @returns {Boolean} Whether this drawer requires enforcing minimum tile overlap to avoid showing seams.
|
|
|
|
*/
|
|
|
|
minimumOverlapRequired() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-06-19 02:08:33 +03:00
|
|
|
/**
|
|
|
|
* create the HTML element (e.g. canvas, div) that the image will be drawn into
|
|
|
|
* @returns {Element} the div to draw into
|
|
|
|
*/
|
2023-12-13 05:45:24 +03:00
|
|
|
_createDrawingElement(){
|
2023-06-19 02:08:33 +03:00
|
|
|
let canvas = $.makeNeutralElement("div");
|
|
|
|
return canvas;
|
2023-06-07 22:42:16 +03:00
|
|
|
}
|
2023-03-12 18:42:03 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Draws the TiledImages
|
|
|
|
*/
|
2023-06-07 22:42:16 +03:00
|
|
|
draw(tiledImages) {
|
2023-03-12 18:42:03 +03:00
|
|
|
var _this = this;
|
|
|
|
this._prepareNewFrame(); // prepare to draw a new frame
|
|
|
|
tiledImages.forEach(function(tiledImage){
|
2024-02-01 18:46:45 +03:00
|
|
|
if (tiledImage.opacity !== 0) {
|
2023-03-13 22:56:04 +03:00
|
|
|
_this._drawTiles(tiledImage);
|
2023-03-12 18:42:03 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-06-07 22:42:16 +03:00
|
|
|
}
|
2023-03-12 18:42:03 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @returns {Boolean} False - rotation is not supported.
|
|
|
|
*/
|
2023-06-07 22:42:16 +03:00
|
|
|
canRotate() {
|
2023-03-12 18:42:03 +03:00
|
|
|
return false;
|
2023-06-07 22:42:16 +03:00
|
|
|
}
|
2023-03-12 18:42:03 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Destroy the drawer (unload current loaded tiles)
|
|
|
|
*/
|
2023-06-07 22:42:16 +03:00
|
|
|
destroy() {
|
|
|
|
this.canvas.innerHTML = "";
|
|
|
|
}
|
2023-03-12 18:42:03 +03:00
|
|
|
|
|
|
|
/**
|
2024-02-01 22:24:25 +03:00
|
|
|
* This function is ignored by the HTML Drawer. Implementing it is required by DrawerBase.
|
2023-03-12 18:42:03 +03:00
|
|
|
* @param {Boolean} [imageSmoothingEnabled] - Whether or not the image is
|
|
|
|
* drawn smoothly on the canvas; see imageSmoothingEnabled in
|
|
|
|
* {@link OpenSeadragon.Options} for more explanation.
|
|
|
|
*/
|
2023-06-07 22:42:16 +03:00
|
|
|
setImageSmoothingEnabled(){
|
2023-03-12 18:42:03 +03:00
|
|
|
// noop - HTML Drawer does not deal with this property
|
2023-06-07 22:42:16 +03:00
|
|
|
}
|
2023-03-12 18:42:03 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clears the Drawer so it's ready to draw another frame.
|
2023-12-19 01:01:17 +03:00
|
|
|
* @private
|
2023-03-12 18:42:03 +03:00
|
|
|
*
|
|
|
|
*/
|
2023-06-07 22:42:16 +03:00
|
|
|
_prepareNewFrame() {
|
2023-03-12 18:42:03 +03:00
|
|
|
this.canvas.innerHTML = "";
|
2023-06-07 22:42:16 +03:00
|
|
|
}
|
2023-03-12 18:42:03 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Draws a TiledImage.
|
2023-12-19 01:01:17 +03:00
|
|
|
* @private
|
2023-03-12 18:42:03 +03:00
|
|
|
*
|
|
|
|
*/
|
2023-06-07 22:42:16 +03:00
|
|
|
_drawTiles( tiledImage ) {
|
2023-06-08 22:10:55 +03:00
|
|
|
var lastDrawn = tiledImage.getTilesToDraw().map(info => info.tile);
|
2023-03-12 18:42:03 +03:00
|
|
|
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 );
|
|
|
|
|
|
|
|
if( this.viewer ){
|
|
|
|
/**
|
2023-06-27 20:57:02 +03:00
|
|
|
* Raised when a tile is drawn to the canvas. Only valid for
|
|
|
|
* context2d and html drawers.
|
2023-03-12 18:42:03 +03:00
|
|
|
*
|
|
|
|
* @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
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-07 22:42:16 +03:00
|
|
|
}
|
2023-03-12 18:42:03 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Draws the given tile.
|
2023-12-19 01:01:17 +03:00
|
|
|
* @private
|
2023-03-12 18:42:03 +03:00
|
|
|
* @param {OpenSeadragon.Tile} tile - The tile to draw.
|
|
|
|
* @param {Function} drawingHandler - Method for firing the drawing event if using canvas.
|
|
|
|
* drawingHandler({context, tile, rendered})
|
|
|
|
*/
|
2023-06-07 22:42:16 +03:00
|
|
|
_drawTile( tile ) {
|
2023-03-12 18:42:03 +03:00
|
|
|
$.console.assert(tile, '[Drawer._drawTile] tile is required');
|
|
|
|
|
2023-06-07 22:42:16 +03:00
|
|
|
let container = this.canvas;
|
2023-03-12 18:42:03 +03:00
|
|
|
|
|
|
|
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";
|
|
|
|
}
|
2023-06-07 22:42:16 +03:00
|
|
|
|
2023-03-12 18:42:03 +03:00
|
|
|
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 );
|
2023-06-07 22:42:16 +03:00
|
|
|
}
|
2023-03-12 18:42:03 +03:00
|
|
|
|
2023-06-07 22:42:16 +03:00
|
|
|
}
|
2023-03-12 18:42:03 +03:00
|
|
|
|
2023-06-07 22:42:16 +03:00
|
|
|
$.HTMLDrawer = HTMLDrawer;
|
2023-03-12 18:42:03 +03:00
|
|
|
|
|
|
|
|
|
|
|
}( OpenSeadragon ));
|