2013-05-01 08:46:16 +04:00
|
|
|
/*
|
2013-05-14 08:00:24 +04:00
|
|
|
* OpenSeadragon - Tile
|
2013-05-01 08:46:16 +04:00
|
|
|
*
|
|
|
|
* Copyright (C) 2009 CodePlex Foundation
|
2013-05-14 07:32:09 +04:00
|
|
|
* Copyright (C) 2010-2013 OpenSeadragon contributors
|
2013-05-01 08:46:16 +04: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.
|
|
|
|
*/
|
|
|
|
|
2011-12-06 07:50:25 +04:00
|
|
|
(function( $ ){
|
2014-11-06 00:48:27 +03:00
|
|
|
|
2012-01-25 23:14:02 +04:00
|
|
|
/**
|
2013-11-16 10:19:53 +04:00
|
|
|
* @class Tile
|
|
|
|
* @memberof OpenSeadragon
|
2012-02-01 00:59:09 +04:00
|
|
|
* @param {Number} level The zoom level this tile belongs to.
|
|
|
|
* @param {Number} x The vector component 'x'.
|
|
|
|
* @param {Number} y The vector component 'y'.
|
2018-03-22 00:07:00 +03:00
|
|
|
* @param {OpenSeadragon.Rect} bounds Where this tile fits, in normalized
|
2012-03-01 17:38:15 +04:00
|
|
|
* coordinates.
|
2013-06-19 21:33:25 +04:00
|
|
|
* @param {Boolean} exists Is this tile a part of a sparse image? ( Also has
|
2012-03-01 17:38:15 +04:00
|
|
|
* this tile failed to load? )
|
2012-02-01 00:59:09 +04:00
|
|
|
* @param {String} url The URL of this tile's image.
|
2015-11-03 03:42:14 +03:00
|
|
|
* @param {CanvasRenderingContext2D} context2D The context2D of this tile if it
|
2022-03-23 12:22:13 +03:00
|
|
|
* is provided directly by the tile source.
|
2016-10-22 00:28:12 +03:00
|
|
|
* @param {Boolean} loadWithAjax Whether this tile image should be loaded with an AJAX request .
|
2016-11-08 20:27:30 +03:00
|
|
|
* @param {Object} ajaxHeaders The headers to send with this tile's AJAX request (if applicable).
|
2018-03-22 00:07:00 +03:00
|
|
|
* @param {OpenSeadragon.Rect} sourceBounds The portion of the tile to use as the source of the
|
2022-03-23 12:22:13 +03:00
|
|
|
* drawing operation, in pixels. Note that this only works when drawing with canvas; when drawing
|
|
|
|
* with HTML the entire tile is always used.
|
2022-04-13 11:47:48 +03:00
|
|
|
* @param {String} postData HTTP POST data (usually but not necessarily in k=v&k2=v2... form,
|
2022-03-23 12:22:13 +03:00
|
|
|
* see TileSrouce::getPostData) or null
|
2022-03-29 10:30:25 +03:00
|
|
|
* @param {String} cacheKey key to act as a tile cache, must be unique for tiles with unique image data
|
2012-01-25 23:14:02 +04:00
|
|
|
*/
|
2022-03-29 10:30:25 +03:00
|
|
|
$.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, ajaxHeaders, sourceBounds, postData, cacheKey) {
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* The zoom level this tile belongs to.
|
|
|
|
* @member {Number} level
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-01-12 03:22:13 +04:00
|
|
|
this.level = level;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* The vector component 'x'.
|
|
|
|
* @member {Number} x
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-01-12 03:22:13 +04:00
|
|
|
this.x = x;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* The vector component 'y'.
|
|
|
|
* @member {Number} y
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-01-12 03:22:13 +04:00
|
|
|
this.y = y;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* Where this tile fits, in normalized coordinates
|
2015-04-19 23:10:37 +03:00
|
|
|
* @member {OpenSeadragon.Rect} bounds
|
2013-11-25 20:48:44 +04:00
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.bounds = bounds;
|
2018-03-22 00:07:00 +03:00
|
|
|
/**
|
2022-04-16 22:19:54 +03:00
|
|
|
* The portion of the tile to use as the source of the drawing operation, in pixels. Note that
|
|
|
|
* this only works when drawing with canvas; when drawing with HTML the entire tile is always used.
|
|
|
|
* @member {OpenSeadragon.Rect} sourceBounds
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2018-03-22 00:07:00 +03:00
|
|
|
this.sourceBounds = sourceBounds;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* Is this tile a part of a sparse image? Also has this tile failed to load?
|
|
|
|
* @member {Boolean} exists
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.exists = exists;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* The URL of this tile's image.
|
|
|
|
* @member {String} url
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.url = url;
|
2021-12-08 11:54:14 +03:00
|
|
|
/**
|
2022-04-13 11:47:48 +03:00
|
|
|
* Post parameters for this tile. For example, it can be an URL-encoded string
|
|
|
|
* in k1=v1&k2=v2... format, or a JSON, or a FormData instance... or null if no POST request used
|
2022-03-23 12:22:13 +03:00
|
|
|
* @member {String} postData HTTP POST data (usually but not necessarily in k=v&k2=v2... form,
|
|
|
|
* see TileSrouce::getPostData) or null
|
2021-12-08 11:54:14 +03:00
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
|
|
|
this.postData = postData;
|
2015-11-03 03:42:14 +03:00
|
|
|
/**
|
|
|
|
* The context2D of this tile if it is provided directly by the tile source.
|
|
|
|
* @member {CanvasRenderingContext2D} context2D
|
|
|
|
* @memberOf OpenSeadragon.Tile#
|
|
|
|
*/
|
|
|
|
this.context2D = context2D;
|
2016-10-22 00:28:12 +03:00
|
|
|
/**
|
2016-11-08 20:27:30 +03:00
|
|
|
* Whether to load this tile's image with an AJAX request.
|
2016-10-22 00:28:12 +03:00
|
|
|
* @member {Boolean} loadWithAjax
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
|
|
|
this.loadWithAjax = loadWithAjax;
|
|
|
|
/**
|
|
|
|
* The headers to be used in requesting this tile's image.
|
|
|
|
* Only used if loadWithAjax is set to true.
|
2016-11-08 20:27:30 +03:00
|
|
|
* @member {Object} ajaxHeaders
|
2016-10-22 00:28:12 +03:00
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2016-11-08 20:27:30 +03:00
|
|
|
this.ajaxHeaders = ajaxHeaders;
|
2022-04-16 22:19:54 +03:00
|
|
|
|
2022-04-07 15:48:26 +03:00
|
|
|
if (cacheKey === undefined) {
|
|
|
|
$.console.error("Tile constructor needs 'cacheKey' variable: creation tile cache" +
|
|
|
|
" in Tile class is deprecated. TileSource.prototype.getTileHashKey will be used.");
|
|
|
|
cacheKey = $.TileSource.prototype.getTileHashKey(level, x, y, url, ajaxHeaders, postData);
|
|
|
|
}
|
2022-04-16 22:19:54 +03:00
|
|
|
/**
|
|
|
|
* The unique cache key for this tile.
|
|
|
|
* @member {String} cacheKey
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2022-03-29 10:30:25 +03:00
|
|
|
this.cacheKey = cacheKey;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* Is this tile loaded?
|
|
|
|
* @member {Boolean} loaded
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.loaded = false;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* Is this tile loading?
|
|
|
|
* @member {Boolean} loading
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.loading = false;
|
|
|
|
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* The HTML div element for this tile
|
|
|
|
* @member {Element} element
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-02 01:56:04 +04:00
|
|
|
this.element = null;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* The HTML img element for this tile.
|
|
|
|
* @member {Element} imgElement
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2013-10-28 23:36:29 +04:00
|
|
|
this.imgElement = null;
|
2012-02-01 00:59:09 +04:00
|
|
|
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* The alias of this.element.style.
|
|
|
|
* @member {String} style
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.style = null;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* This tile's position on screen, in pixels.
|
|
|
|
* @member {OpenSeadragon.Point} position
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.position = null;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* This tile's size on screen, in pixels.
|
|
|
|
* @member {OpenSeadragon.Point} size
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.size = null;
|
2020-10-29 23:02:35 +03:00
|
|
|
/**
|
|
|
|
* Whether to flip the tile when rendering.
|
|
|
|
* @member {Boolean} flipped
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
|
|
|
this.flipped = false;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* The start time of this tile's blending.
|
|
|
|
* @member {Number} blendStart
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.blendStart = null;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* The current opacity this tile should be.
|
|
|
|
* @member {Number} opacity
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.opacity = null;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
2016-09-02 17:31:36 +03:00
|
|
|
* The squared distance of this tile to the viewport center.
|
|
|
|
* Use for comparing tiles.
|
2016-09-23 06:01:32 +03:00
|
|
|
* @private
|
2016-09-02 17:31:36 +03:00
|
|
|
* @member {Number} squaredDistance
|
2013-11-25 20:48:44 +04:00
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2016-09-02 17:31:36 +03:00
|
|
|
this.squaredDistance = null;
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* The visibility score of this tile.
|
|
|
|
* @member {Number} visibility
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.visibility = null;
|
|
|
|
|
2022-04-29 19:41:43 +03:00
|
|
|
/**
|
|
|
|
* The transparency indicator of this tile.
|
|
|
|
* @member {Boolean} true if tile contains transparency for correct rendering
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
|
|
|
this.hasTransparency = false;
|
|
|
|
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* Whether this tile is currently being drawn.
|
|
|
|
* @member {Boolean} beingDrawn
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.beingDrawn = false;
|
2017-09-09 00:03:40 +03:00
|
|
|
|
2013-11-25 20:48:44 +04:00
|
|
|
/**
|
|
|
|
* Timestamp the tile was last touched.
|
|
|
|
* @member {Number} lastTouchTime
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
2012-02-01 00:59:09 +04:00
|
|
|
this.lastTouchTime = 0;
|
2017-09-09 00:03:40 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether this tile is in the right-most column for its level.
|
|
|
|
* @member {Boolean} isRightMost
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
|
|
|
this.isRightMost = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether this tile is in the bottom-most row for its level.
|
|
|
|
* @member {Boolean} isBottomMost
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
*/
|
|
|
|
this.isBottomMost = false;
|
2011-12-06 07:50:25 +04:00
|
|
|
};
|
|
|
|
|
2016-01-25 00:09:18 +03:00
|
|
|
/** @lends OpenSeadragon.Tile.prototype */
|
|
|
|
$.Tile.prototype = {
|
2013-06-19 21:33:25 +04:00
|
|
|
|
2012-02-01 00:59:09 +04:00
|
|
|
/**
|
2013-06-19 21:33:25 +04:00
|
|
|
* Provides a string representation of this tiles level and (x,y)
|
2012-02-01 00:59:09 +04:00
|
|
|
* components.
|
|
|
|
* @function
|
|
|
|
* @returns {String}
|
|
|
|
*/
|
2011-12-06 07:50:25 +04:00
|
|
|
toString: function() {
|
|
|
|
return this.level + "/" + this.x + "_" + this.y;
|
|
|
|
},
|
2012-01-12 03:22:13 +04:00
|
|
|
|
2016-02-24 03:37:41 +03:00
|
|
|
// private
|
|
|
|
_hasTransparencyChannel: function() {
|
2022-04-29 19:41:43 +03:00
|
|
|
console.warn("Tile.prototype._hasTransparencyChannel() has been " +
|
|
|
|
"deprecated and will be removed in the future. Use TileSource.prototype.hasTransparency() instead.");
|
2016-04-27 18:08:44 +03:00
|
|
|
return !!this.context2D || this.url.match('.png');
|
2016-02-24 03:37:41 +03:00
|
|
|
},
|
|
|
|
|
2012-02-01 00:59:09 +04:00
|
|
|
/**
|
|
|
|
* Renders the tile in an html container.
|
|
|
|
* @function
|
|
|
|
* @param {Element} container
|
|
|
|
*/
|
2012-01-12 03:22:13 +04:00
|
|
|
drawHTML: function( container ) {
|
2015-05-29 18:49:58 +03:00
|
|
|
if (!this.cacheImageRecord) {
|
|
|
|
$.console.warn(
|
|
|
|
'[Tile.drawHTML] attempting to draw tile %s when it\'s not cached',
|
|
|
|
this.toString());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !this.loaded ) {
|
2012-01-25 23:14:02 +04:00
|
|
|
$.console.warn(
|
2012-01-24 07:48:45 +04:00
|
|
|
"Attempting to draw tile %s when it's not yet loaded.",
|
|
|
|
this.toString()
|
2012-01-12 03:22:13 +04:00
|
|
|
);
|
2011-12-06 07:50:25 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-01-31 05:23:45 +04:00
|
|
|
//EXPERIMENTAL - trying to figure out how to scale the container
|
|
|
|
// content during animation of the container size.
|
2013-06-03 22:09:42 +04:00
|
|
|
|
2013-01-31 05:23:45 +04:00
|
|
|
if ( !this.element ) {
|
2022-04-29 19:41:43 +03:00
|
|
|
var image = this.image;
|
|
|
|
if (!this.image) return;
|
|
|
|
|
2013-10-28 23:36:29 +04:00
|
|
|
this.element = $.makeNeutralElement( "div" );
|
2022-04-29 19:41:43 +03:00
|
|
|
this.imgElement = image.cloneNode();
|
2013-10-28 23:36:29 +04:00
|
|
|
this.imgElement.style.msInterpolationMode = "nearest-neighbor";
|
|
|
|
this.imgElement.style.width = "100%";
|
|
|
|
this.imgElement.style.height = "100%";
|
2013-01-31 05:23:45 +04:00
|
|
|
|
|
|
|
this.style = this.element.style;
|
|
|
|
this.style.position = "absolute";
|
|
|
|
}
|
2020-06-26 02:01:14 +03:00
|
|
|
if ( this.element.parentNode !== container ) {
|
2013-01-31 21:30:13 +04:00
|
|
|
container.appendChild( this.element );
|
|
|
|
}
|
2020-06-26 02:01:14 +03:00
|
|
|
if ( this.imgElement.parentNode !== this.element ) {
|
2013-10-28 23:36:29 +04:00
|
|
|
this.element.appendChild( this.imgElement );
|
|
|
|
}
|
2013-01-31 21:30:13 +04:00
|
|
|
|
2013-06-03 22:09:42 +04:00
|
|
|
this.style.top = this.position.y + "px";
|
|
|
|
this.style.left = this.position.x + "px";
|
|
|
|
this.style.height = this.size.y + "px";
|
|
|
|
this.style.width = this.size.x + "px";
|
2013-01-31 05:23:45 +04:00
|
|
|
|
2020-10-29 23:02:35 +03:00
|
|
|
if (this.flipped) {
|
|
|
|
this.style.transform = "scaleX(-1)";
|
|
|
|
}
|
|
|
|
|
2013-06-03 22:09:42 +04:00
|
|
|
$.setElementOpacity( this.element, this.opacity );
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
2012-01-12 03:22:13 +04:00
|
|
|
|
2022-04-16 22:19:54 +03:00
|
|
|
/**
|
2022-04-29 19:41:43 +03:00
|
|
|
* The Image object for this tile.
|
|
|
|
* @member {Object} image
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
* @return {Image}
|
2022-04-16 22:19:54 +03:00
|
|
|
*/
|
2022-04-29 19:41:43 +03:00
|
|
|
get image() {
|
|
|
|
this.cacheImageRecord.getImage();
|
2022-04-16 22:19:54 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2022-04-29 19:41:43 +03:00
|
|
|
* The CanvasRenderingContext2D instance for tile image data drawn
|
|
|
|
* onto Canvas if enabled and available
|
|
|
|
* @member {CanvasRenderingContext2D} canvasContext
|
|
|
|
* @memberof OpenSeadragon.Tile#
|
|
|
|
* @return {CanvasRenderingContext2D}
|
2022-04-16 22:19:54 +03:00
|
|
|
*/
|
2022-04-29 19:41:43 +03:00
|
|
|
get canvasContext() {
|
2022-04-16 22:19:54 +03:00
|
|
|
return this.context2D || this.cacheImageRecord.getRenderedContext();
|
|
|
|
},
|
|
|
|
|
2012-02-01 00:59:09 +04:00
|
|
|
/**
|
|
|
|
* Renders the tile in a canvas-based context.
|
|
|
|
* @function
|
|
|
|
* @param {Canvas} context
|
2014-11-25 00:25:20 +03:00
|
|
|
* @param {Function} drawingHandler - Method for firing the drawing event.
|
|
|
|
* drawingHandler({context, tile, rendered})
|
2014-02-28 01:39:18 +04:00
|
|
|
* where <code>rendered</code> is the context with the pre-drawn image.
|
2015-11-06 09:55:30 +03:00
|
|
|
* @param {Number} [scale=1] - Apply a scale to position and size
|
|
|
|
* @param {OpenSeadragon.Point} [translate] - A translation vector
|
2021-12-13 08:20:11 +03:00
|
|
|
* @param {Boolean} [shouldRoundPositionAndSize] - Tells whether to round
|
|
|
|
* position and size of tiles supporting alpha channel in non-transparency
|
|
|
|
* context.
|
2022-04-16 22:19:54 +03:00
|
|
|
* @param {OpenSeadragon.TileSource} source - The source specification of the tile.
|
2012-02-01 00:59:09 +04:00
|
|
|
*/
|
2022-04-16 22:19:54 +03:00
|
|
|
drawCanvas: function( context, drawingHandler, scale, translate, shouldRoundPositionAndSize, source) {
|
2012-01-24 07:48:45 +04:00
|
|
|
|
2015-11-04 18:04:50 +03:00
|
|
|
var position = this.position.times($.pixelDensityRatio),
|
|
|
|
size = this.size.times($.pixelDensityRatio),
|
2022-04-16 22:19:54 +03:00
|
|
|
rendered,
|
|
|
|
hasTransparency;
|
2012-01-24 07:48:45 +04:00
|
|
|
|
2015-11-03 03:42:14 +03:00
|
|
|
if (!this.context2D && !this.cacheImageRecord) {
|
2015-05-29 18:49:58 +03:00
|
|
|
$.console.warn(
|
|
|
|
'[Tile.drawCanvas] attempting to draw tile %s when it\'s not cached',
|
|
|
|
this.toString());
|
2014-11-06 00:48:27 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 19:41:43 +03:00
|
|
|
rendered = this.canvasContext;
|
2014-11-06 00:48:27 +03:00
|
|
|
|
2015-05-29 18:49:58 +03:00
|
|
|
if ( !this.loaded || !rendered ){
|
2012-01-25 23:14:02 +04:00
|
|
|
$.console.warn(
|
2012-01-24 07:48:45 +04:00
|
|
|
"Attempting to draw tile %s when it's not yet loaded.",
|
|
|
|
this.toString()
|
2012-01-12 03:22:13 +04:00
|
|
|
);
|
2014-11-06 00:48:27 +03:00
|
|
|
|
2011-12-06 07:50:25 +04:00
|
|
|
return;
|
|
|
|
}
|
2013-01-31 01:51:37 +04:00
|
|
|
|
2015-09-16 06:52:44 +03:00
|
|
|
context.save();
|
2014-11-06 00:48:27 +03:00
|
|
|
context.globalAlpha = this.opacity;
|
2013-01-31 05:23:45 +04:00
|
|
|
|
2016-02-23 21:49:11 +03:00
|
|
|
if (typeof scale === 'number' && scale !== 1) {
|
|
|
|
// draw tile at a different scale
|
|
|
|
position = position.times(scale);
|
|
|
|
size = size.times(scale);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (translate instanceof $.Point) {
|
|
|
|
// shift tile position slightly
|
|
|
|
position = position.plus(translate);
|
|
|
|
}
|
|
|
|
|
2013-03-01 17:14:35 +04:00
|
|
|
//if we are supposed to be rendering fully opaque rectangle,
|
2013-01-31 21:30:13 +04:00
|
|
|
//ie its done fading or fading is turned off, and if we are drawing
|
|
|
|
//an image with an alpha channel, then the only way
|
|
|
|
//to avoid seeing the tile underneath is to clear the rectangle
|
2022-04-29 19:41:43 +03:00
|
|
|
if (context.globalAlpha === 1 && this.hasTransparency) {
|
2021-12-13 08:20:11 +03:00
|
|
|
if (shouldRoundPositionAndSize) {
|
|
|
|
// Round to the nearest whole pixel so we don't get seams from overlap.
|
|
|
|
position.x = Math.round(position.x);
|
|
|
|
position.y = Math.round(position.y);
|
|
|
|
size.x = Math.round(size.x);
|
|
|
|
size.y = Math.round(size.y);
|
|
|
|
}
|
|
|
|
|
2013-01-31 21:30:13 +04:00
|
|
|
//clearing only the inside of the rectangle occupied
|
|
|
|
//by the png prevents edge flikering
|
2013-06-19 21:33:25 +04:00
|
|
|
context.clearRect(
|
2018-06-04 12:16:23 +03:00
|
|
|
position.x,
|
|
|
|
position.y,
|
|
|
|
size.x,
|
|
|
|
size.y
|
2013-01-31 01:51:37 +04:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2015-05-29 18:49:58 +03:00
|
|
|
// This gives the application a chance to make image manipulation
|
|
|
|
// changes as we are rendering the image
|
2014-02-28 01:39:18 +04:00
|
|
|
drawingHandler({context: context, tile: this, rendered: rendered});
|
|
|
|
|
2018-04-02 21:09:23 +03:00
|
|
|
var sourceWidth, sourceHeight;
|
|
|
|
if (this.sourceBounds) {
|
|
|
|
sourceWidth = Math.min(this.sourceBounds.width, rendered.canvas.width);
|
|
|
|
sourceHeight = Math.min(this.sourceBounds.height, rendered.canvas.height);
|
|
|
|
} else {
|
|
|
|
sourceWidth = rendered.canvas.width;
|
|
|
|
sourceHeight = rendered.canvas.height;
|
2018-03-22 00:07:00 +03:00
|
|
|
}
|
|
|
|
|
2020-10-29 23:02:35 +03:00
|
|
|
context.translate(position.x + size.x / 2, 0);
|
|
|
|
if (this.flipped) {
|
|
|
|
context.scale(-1, 1);
|
|
|
|
}
|
2013-06-19 21:33:25 +04:00
|
|
|
context.drawImage(
|
|
|
|
rendered.canvas,
|
2018-04-02 21:09:23 +03:00
|
|
|
0,
|
|
|
|
0,
|
|
|
|
sourceWidth,
|
|
|
|
sourceHeight,
|
2020-10-29 23:02:35 +03:00
|
|
|
-size.x / 2,
|
2015-11-04 18:04:50 +03:00
|
|
|
position.y,
|
|
|
|
size.x,
|
|
|
|
size.y
|
2013-03-01 17:14:35 +04:00
|
|
|
);
|
2015-09-16 06:52:44 +03:00
|
|
|
|
|
|
|
context.restore();
|
2011-12-06 07:50:25 +04:00
|
|
|
},
|
2012-01-18 03:30:41 +04:00
|
|
|
|
2015-11-05 17:19:56 +03:00
|
|
|
/**
|
|
|
|
* Get the ratio between current and original size.
|
|
|
|
* @function
|
|
|
|
* @return {Float}
|
|
|
|
*/
|
|
|
|
getScaleForEdgeSmoothing: function() {
|
2016-04-21 17:31:49 +03:00
|
|
|
var context;
|
|
|
|
if (this.cacheImageRecord) {
|
|
|
|
context = this.cacheImageRecord.getRenderedContext();
|
|
|
|
} else if (this.context2D) {
|
|
|
|
context = this.context2D;
|
|
|
|
} else {
|
2015-11-05 17:19:56 +03:00
|
|
|
$.console.warn(
|
|
|
|
'[Tile.drawCanvas] attempting to get tile scale %s when tile\'s not cached',
|
|
|
|
this.toString());
|
|
|
|
return 1;
|
|
|
|
}
|
2016-04-21 17:31:49 +03:00
|
|
|
return context.canvas.width / (this.size.x * $.pixelDensityRatio);
|
2015-11-05 17:19:56 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a translation vector that when applied to the tile position produces integer coordinates.
|
|
|
|
* Needed to avoid swimming and twitching.
|
|
|
|
* @function
|
2015-11-06 09:55:30 +03:00
|
|
|
* @param {Number} [scale=1] - Scale to be applied to position.
|
2015-11-05 17:19:56 +03:00
|
|
|
* @return {OpenSeadragon.Point}
|
|
|
|
*/
|
2016-01-24 02:40:53 +03:00
|
|
|
getTranslationForEdgeSmoothing: function(scale, canvasSize, sketchCanvasSize) {
|
2015-11-05 17:19:56 +03:00
|
|
|
// The translation vector must have positive values, otherwise the image goes a bit off
|
|
|
|
// the sketch canvas to the top and left and we must use negative coordinates to repaint it
|
2016-01-26 23:59:10 +03:00
|
|
|
// to the main canvas. In that case, some browsers throw:
|
|
|
|
// INDEX_SIZE_ERR: DOM Exception 1: Index or size was negative, or greater than the allowed value.
|
|
|
|
var x = Math.max(1, Math.ceil((sketchCanvasSize.x - canvasSize.x) / 2));
|
|
|
|
var y = Math.max(1, Math.ceil((sketchCanvasSize.y - canvasSize.y) / 2));
|
|
|
|
return new $.Point(x, y).minus(
|
2015-11-05 17:19:56 +03:00
|
|
|
this.position
|
2015-11-19 11:06:43 +03:00
|
|
|
.times($.pixelDensityRatio)
|
2015-11-05 17:19:56 +03:00
|
|
|
.times(scale || 1)
|
|
|
|
.apply(function(x) {
|
|
|
|
return x % 1;
|
|
|
|
})
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
2012-02-01 00:59:09 +04:00
|
|
|
/**
|
2013-12-14 01:12:35 +04:00
|
|
|
* Removes tile from its container.
|
2012-02-01 00:59:09 +04:00
|
|
|
* @function
|
|
|
|
*/
|
2011-12-06 07:50:25 +04:00
|
|
|
unload: function() {
|
2013-10-28 23:36:29 +04:00
|
|
|
if ( this.imgElement && this.imgElement.parentNode ) {
|
|
|
|
this.imgElement.parentNode.removeChild( this.imgElement );
|
|
|
|
}
|
2012-02-02 01:56:04 +04:00
|
|
|
if ( this.element && this.element.parentNode ) {
|
|
|
|
this.element.parentNode.removeChild( this.element );
|
2013-06-19 21:33:25 +04:00
|
|
|
}
|
2011-12-06 07:50:25 +04:00
|
|
|
|
2013-10-28 23:38:17 +04:00
|
|
|
this.element = null;
|
2013-10-28 23:36:29 +04:00
|
|
|
this.imgElement = null;
|
2013-10-28 23:38:17 +04:00
|
|
|
this.loaded = false;
|
|
|
|
this.loading = false;
|
2011-12-06 07:50:25 +04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}( OpenSeadragon ));
|