Fix comments on #2148: hasTransparency as a property. Move '.image' tile property to be a getter instead. Rename 'ImageJob' data property from 'image' to 'data'. Repair comments related to #2148.

This commit is contained in:
Jirka 2022-04-29 18:41:43 +02:00
parent 92ad2c5552
commit 45a7a4aaf3
5 changed files with 81 additions and 62 deletions

View File

@ -58,11 +58,11 @@ function ImageJob (options) {
}, options);
/**
* Image object which will contain downloaded image.
* @member {Image|*} image element (default) or other form of image data (depends on TileSource)
* Data object which will contain downloaded image data.
* @member {Image|*} image data object, by default an Image object (depends on TileSource)
* @memberof OpenSeadragon.ImageJob#
*/
this.image = null;
this.data = null;
}
ImageJob.prototype = {
@ -77,12 +77,11 @@ ImageJob.prototype = {
var selfAbort = this.abort;
this.jobId = window.setTimeout(function () {
self.errorMsg = "Image load exceeded timeout (" + self.timeout + " ms)";
self.finish(false);
self.finish(false, "Image load exceeded timeout (" + self.timeout + " ms)");
}, this.timeout);
this.abort = function() {
self.request.abort();
self.source.downloadTileAbort(self);
if (typeof selfAbort === "function") {
selfAbort();
}
@ -93,8 +92,7 @@ ImageJob.prototype = {
finish: function(successful, errorMessage) {
this.errorMsg = errorMessage;
//consider deprecation of .image attribute
this.image = this.source.downloadTileFinish(this, successful);
this.data = this.source.downloadTileFinish(this, successful);
if (this.jobId) {
window.clearTimeout(this.jobId);
@ -145,6 +143,17 @@ $.ImageLoader.prototype = {
* @param {Function} [options.abort] - Called when this image job is aborted.
*/
addJob: function(options) {
if (!options.source) {
$.console.error('ImageLoader.prototype.addJob() requires [options.source]. ' +
'TileSource since new API defines how images are fetched. Creating a dummy TileSource.');
let implementation = $.TileSource.prototype;
options.source = {
downloadTileStart: implementation.downloadTileStart,
downloadTileAbort: implementation.downloadTileAbort,
downloadTileFinish: implementation.downloadTileFinish
};
}
var _this = this,
complete = function(job) {
completeJob(_this, job, options.callback);
@ -207,7 +216,7 @@ function completeJob(loader, job, callback) {
loader.jobsInProgress++;
}
callback(job.image, job.errorMsg, job.request);
callback(job.data, job.errorMsg, job.request); //todo job.request might not exist
}
}(OpenSeadragon));

View File

@ -164,12 +164,6 @@ $.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, aja
* @memberof OpenSeadragon.Tile#
*/
this.imgElement = null;
/**
* The Image object for this tile.
* @member {Object} image
* @memberof OpenSeadragon.Tile#
*/
this.image = null;
/**
* The alias of this.element.style.
@ -222,6 +216,13 @@ $.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, aja
*/
this.visibility = null;
/**
* The transparency indicator of this tile.
* @member {Boolean} true if tile contains transparency for correct rendering
* @memberof OpenSeadragon.Tile#
*/
this.hasTransparency = false;
/**
* Whether this tile is currently being drawn.
* @member {Boolean} beingDrawn
@ -266,8 +267,8 @@ $.Tile.prototype = {
// private
_hasTransparencyChannel: function() {
console.warn("Tile.prototype._hasTransparencyChannel has been " +
"deprecated and will be removed in the future.");
console.warn("Tile.prototype._hasTransparencyChannel() has been " +
"deprecated and will be removed in the future. Use TileSource.prototype.hasTransparency() instead.");
return !!this.context2D || this.url.match('.png');
},
@ -296,8 +297,11 @@ $.Tile.prototype = {
// content during animation of the container size.
if ( !this.element ) {
var image = this.image;
if (!this.image) return;
this.element = $.makeNeutralElement( "div" );
this.imgElement = this.imageData();
this.imgElement = image.cloneNode();
this.imgElement.style.msInterpolationMode = "nearest-neighbor";
this.imgElement.style.width = "100%";
this.imgElement.style.height = "100%";
@ -325,22 +329,23 @@ $.Tile.prototype = {
},
/**
* Get the tile image data as <img> element if
* supported
*
* @return {Image || undefined}
* The Image object for this tile.
* @member {Object} image
* @memberof OpenSeadragon.Tile#
* @return {Image}
*/
imageData: function() {
return this.image || this.cacheImageRecord.getImage();
get image() {
this.cacheImageRecord.getImage();
},
/**
* Get the CanvasRenderingContext2D instance for tile image data drawn
* onto Canvas if supported
*
* @return {CanvasRenderingContext2D || undefined}
* The CanvasRenderingContext2D instance for tile image data drawn
* onto Canvas if enabled and available
* @member {CanvasRenderingContext2D} canvasContext
* @memberof OpenSeadragon.Tile#
* @return {CanvasRenderingContext2D}
*/
canvasContext: function() {
get canvasContext() {
return this.context2D || this.cacheImageRecord.getRenderedContext();
},
@ -372,7 +377,7 @@ $.Tile.prototype = {
return;
}
rendered = this.canvasContext();
rendered = this.canvasContext;
if ( !this.loaded || !rendered ){
$.console.warn(
@ -384,7 +389,6 @@ $.Tile.prototype = {
}
context.save();
context.globalAlpha = this.opacity;
if (typeof scale === 'number' && scale !== 1) {
@ -398,19 +402,11 @@ $.Tile.prototype = {
position = position.plus(translate);
}
if (source === undefined) {
$.console.warn('[Tile.drawCanvas] deprecated call without argument \'hasTransparency\'.');
hasTransparency = context.globalAlpha === 1 && this._hasTransparencyChannel();
} else {
hasTransparency = context.globalAlpha === 1 &&
source.hasTransparency(this.context2D, this.url, this.ajaxHeaders, this.postData);
}
//if we are supposed to be rendering fully opaque rectangle,
//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
if (hasTransparency) {
if (context.globalAlpha === 1 && this.hasTransparency) {
if (shouldRoundPositionAndSize) {
// Round to the nearest whole pixel so we don't get seams from overlap.
position.x = Math.round(position.x);

View File

@ -45,7 +45,6 @@ var TileRecord = function( options ) {
// private class
var ImageRecord = function(options) {
//private scope: changed image -> data
$.console.assert( options, "[ImageRecord] options is required" );
$.console.assert( options.data, "[ImageRecord] options.data is required" );
this._tiles = [];
@ -63,14 +62,6 @@ ImageRecord.prototype = {
this._tiles = null;
},
// Removed (left as a comment so that it stands out)
// setRenderedContext: function(renderedContext) {
// $.console.error("ImageRecord.setRenderedContext is deprecated. " +
// "The rendered context should be created by the ImageRecord " +
// "itself when calling ImageRecord.getRenderedContext.");
// this._renderedContext = renderedContext;
// },
addTile: function(tile) {
$.console.assert(tile, '[ImageRecord.addTile] tile is required');
this._tiles.push(tile);
@ -146,9 +137,16 @@ $.TileCache.prototype = {
var imageRecord = this._imagesLoaded[options.tile.cacheKey];
if (!imageRecord) {
$.console.assert( options.image, "[TileCache.cacheTile] options.image is required to create an ImageRecord" );
if (!options.data) {
$.console.error("[TileCache.cacheTile] options.image was renamed to options.data. '.image' attribute "
+ "has been deprecated and will be removed in the future.");
options.data = options.image;
}
$.console.assert( options.data, "[TileCache.cacheTile] options.data is required to create an ImageRecord" );
imageRecord = this._imagesLoaded[options.tile.cacheKey] = new ImageRecord({
data: options.image,
data: options.data,
ownerTile: options.tile,
create: options.tiledImage.source.createTileCache,
destroy: options.tiledImage.source.destroyTileCache,

View File

@ -1576,8 +1576,8 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
ajaxHeaders: tile.ajaxHeaders,
crossOriginPolicy: this.crossOriginPolicy,
ajaxWithCredentials: this.ajaxWithCredentials,
callback: function( image, errorMsg, tileRequest ){
_this._onTileLoad( tile, time, image, errorMsg, tileRequest );
callback: function( data, errorMsg, tileRequest ){
_this._onTileLoad( tile, time, data, errorMsg, tileRequest );
},
abort: function() {
tile.loading = false;
@ -1591,12 +1591,12 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
* Callback fired when a Tile's Image finished downloading.
* @param {OpenSeadragon.Tile} tile
* @param {Number} time
* @param {Image} image
* @param {*} data image data
* @param {String} errorMsg
* @param {XMLHttpRequest} tileRequest
*/
_onTileLoad: function( tile, time, image, errorMsg, tileRequest ) {
if ( !image ) {
_onTileLoad: function( tile, time, data, errorMsg, tileRequest ) {
if ( !data ) {
$.console.error( "Tile %s failed to load: %s - error: %s", tile, tile.url, errorMsg );
/**
* Triggered when a tile fails to load.
@ -1632,7 +1632,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
finish = function() {
var ccc = _this.source;
var cutoff = ccc.getClosestLevel();
_this._setTileLoaded(tile, image, cutoff, tileRequest);
_this._setTileLoaded(tile, data, cutoff, tileRequest);
};
// Check if we're mid-update; this can happen on IE8 because image load events for
@ -1649,11 +1649,11 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
* @private
* @inner
* @param {OpenSeadragon.Tile} tile
* @param {Image|* || undefined} image
* @param {*} data image data
* @param {Number || undefined} cutoff
* @param {XMLHttpRequest || undefined} tileRequest
*/
_setTileLoaded: function(tile, image, cutoff, tileRequest) {
_setTileLoaded: function(tile, data, cutoff, tileRequest) {
var increment = 0,
_this = this;
@ -1667,9 +1667,12 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
if (increment === 0) {
tile.loading = false;
tile.loaded = true;
tile.hasTransparency = this.source.hasTransparency(
tile.context2D, tile.url, tile.ajaxHeaders, tile.postData
);
if (!tile.context2D) {
_this._tileCache.cacheTile({
image: image,
data: data,
tile: tile,
cutoff: cutoff,
tiledImage: _this
@ -1687,6 +1690,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
* @memberof OpenSeadragon.Viewer
* @type {object}
* @property {Image|*} image - The image (data) of the tile.
* @property {*} data - image data
* @property {OpenSeadragon.TiledImage} tiledImage - The tiled image of the loaded tile.
* @property {OpenSeadragon.Tile} tile - The tile which has been loaded.
* @property {XMLHttpRequest} tileRequest - The AJAX request that loaded this tile (if applicable).
@ -1699,7 +1703,11 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
tile: tile,
tiledImage: this,
tileRequest: tileRequest,
image: image,
get image() {
$.console.error("[tile-loaded] event property 'image' has been deprecated and will be removed in the future");
return data;
},
data: data,
getCompletionCallback: getCompletionCallback
});
// In case the completion callback is never called, we at least force it once.

View File

@ -712,7 +712,7 @@ $.TileSource.prototype = {
},
/**
* Decide whether tiles have transparency: this is crucial for
* Decide whether tiles have transparency: this is crucial for correct images blending.
* @return {boolean} true if the image has transparency
*/
hasTransparency: function(context2D, url, ajaxHeaders, post) {
@ -794,6 +794,14 @@ $.TileSource.prototype = {
}
},
/**
* Provide means of aborting the execution.
* @param {object} context job, the same object as with downloadTileStart(..)
*/
downloadTileAbort: function (context) {
context.request.abort();
},
/**
* @param {object} context job, the same object as with downloadTileStart(..)
* @param successful true if successful