From ea833a780c579c95e22c76ec22ffdf47ad4a7ea1 Mon Sep 17 00:00:00 2001 From: Mei-Hui Su Date: Wed, 6 Jan 2016 07:58:36 -0800 Subject: [PATCH] Update to allow setting of globalCompositeOperation when html is used to process multiple tiledImages to blend is a specific way. (special handling, when compositeOperation is 'source-over' and opacity is 1, useSketch is false, otherwise useSketch is true ) Valid values are 'source-atop', 'source-in', 'source-out', 'destination-over', 'destination-atop', 'destination-in', 'destination-out', 'lighter', 'copy' or 'xor' http://www.w3schools.com/tags/canvas_globalcompositeoperation.asp --- src/drawer.js | 3 ++- src/openseadragon.js | 6 ++++++ src/tile.js | 1 + src/tiledimage.js | 25 +++++++++++++++++++++---- src/viewer.js | 5 +++++ 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/drawer.js b/src/drawer.js index 9b74b981..919057d7 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -373,13 +373,14 @@ $.Drawer.prototype = /** @lends OpenSeadragon.Drawer.prototype */{ * @param {Float} opacity The opacity of the blending. * @returns {undefined} */ - blendSketch: function(opacity) { + blendSketch: function(opacity, compositeOperation) { if (!this.useCanvas || !this.sketchCanvas) { return; } this.context.save(); this.context.globalAlpha = opacity; + this.context.globalCompositeOperation = compositeOperation; this.context.drawImage(this.sketchCanvas, 0, 0); this.context.restore(); }, diff --git a/src/openseadragon.js b/src/openseadragon.js index c0111b2b..16e0e86f 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -206,6 +206,11 @@ * @property {Number} [opacity=1] * Default opacity of the tiled images (1=opaque, 0=transparent) * + * @property {String} [compositeOperation='source-over'] + * Valid values are 'source-atop', 'source-in', 'source-out', + * 'destination-over', 'destination-atop', 'destination-in', + * 'destination-out', 'lighter', 'copy' or 'xor'.
+ * * @property {String|CanvasGradient|CanvasPattern|Function} [placeholderFillStyle=null] * Draws a colored rectangle behind the tile if it is not loaded yet. * You can pass a CSS color value like "#FF8800". @@ -1044,6 +1049,7 @@ if (typeof define === 'function' && define.amd) { // APPEARANCE opacity: 1, + compositeOperation: 'source-over', placeholderFillStyle: null, //REFERENCE STRIP SETTINGS diff --git a/src/tile.js b/src/tile.js index ad018ba7..1adbad13 100644 --- a/src/tile.js +++ b/src/tile.js @@ -268,6 +268,7 @@ $.Tile.prototype = /** @lends OpenSeadragon.Tile.prototype */{ context.save(); context.globalAlpha = this.opacity; + context.globalCompositeOperation = this.compositeOperation; //if we are supposed to be rendering fully opaque rectangle, //ie its done fading or fading is turned off, and if we are drawing diff --git a/src/tiledimage.js b/src/tiledimage.js index 1731d472..e858cf56 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -65,6 +65,7 @@ * @param {Boolean} [options.alwaysBlend] - See {@link OpenSeadragon.Options}. * @param {Number} [options.minPixelRatio] - See {@link OpenSeadragon.Options}. * @param {Number} [options.opacity=1] - Opacity the tiled image should be drawn at. + * @param {String} [options.compositeOperation='source-over'] - How a tiled source image are drawn onto an existing image. * @param {Boolean} [options.debugMode] - See {@link OpenSeadragon.Options}. * @param {String|CanvasGradient|CanvasPattern|Function} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}. * @param {String|Boolean} [options.crossOriginPolicy] - See {@link OpenSeadragon.Options}. @@ -131,7 +132,6 @@ $.TiledImage = function( options ) { _midDraw: false, // Is the tiledImage currently updating the viewport? _needsDraw: true, // Does the tiledImage need to update the viewport again? _hasOpaqueTile: false, // Do we have even one fully opaque tile? - //configurable settings springStiffness: $.DEFAULT_SETTINGS.springStiffness, animationTime: $.DEFAULT_SETTINGS.animationTime, @@ -145,7 +145,8 @@ $.TiledImage = function( options ) { debugMode: $.DEFAULT_SETTINGS.debugMode, crossOriginPolicy: $.DEFAULT_SETTINGS.crossOriginPolicy, placeholderFillStyle: $.DEFAULT_SETTINGS.placeholderFillStyle, - opacity: $.DEFAULT_SETTINGS.opacity + opacity: $.DEFAULT_SETTINGS.opacity, + compositeOperation: $.DEFAULT_SETTINGS.compositeOperation }, options ); @@ -583,6 +584,21 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag this._needsDraw = true; }, + /** + * @returns {String} The TiledImage's current compositeOperation. + */ + getCompositeOperation: function() { + return this.compositeOperation; + }, + + /** + * @param {String} compositeOperation the tiled image should be drawn with this globalCompositeOperation. + */ + setCompositeOperation: function(compositeOperation) { + this.compositeOperation = compositeOperation; + this._needsDraw = true; + }, + // private _setScale: function(scale, immediately) { var sameTarget = (this._scaleSpring.target.value === scale); @@ -1301,7 +1317,8 @@ function drawTiles( tiledImage, lastDrawn ) { drawDebugInfo( tiledImage, lastDrawn ); return; } - var useSketch = tiledImage.opacity < 1; + var useSketch = (tiledImage.compositeOperation == 'source-over') ? (tiledImage.opacity < 1):true; + if ( useSketch ) { tiledImage._drawer._clear( true ); } @@ -1360,7 +1377,7 @@ function drawTiles( tiledImage, lastDrawn ) { } if ( useSketch ) { - tiledImage._drawer.blendSketch( tiledImage.opacity ); + tiledImage._drawer.blendSketch( tiledImage.opacity, tiledImage.compositeOperation ); } drawDebugInfo( tiledImage, lastDrawn ); } diff --git a/src/viewer.js b/src/viewer.js index 0890a55d..c916acd6 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1207,6 +1207,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, * (portions of the image outside of this area will not be visible). Only works on * browsers that support the HTML5 canvas. * @param {Number} [options.opacity] Opacity the tiled image should be drawn at by default. + * @param {String} [options.compositeOperation] How a tiled source image are drawn onto an existing image. * @param {Function} [options.success] A function that gets called when the image is * successfully added. It's passed the event object which contains a single property: * "item", the resulting TiledImage. @@ -1239,6 +1240,9 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, if (options.opacity === undefined) { options.opacity = this.opacity; } + if (options.compositeOperation === undefined) { + options.compositeOperation = this.compositeOperation; + } var myQueueItem = { options: options @@ -1335,6 +1339,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, clip: queueItem.options.clip, placeholderFillStyle: queueItem.options.placeholderFillStyle, opacity: queueItem.options.opacity, + compositeOperation: queueItem.options.compositeOperation, springStiffness: _this.springStiffness, animationTime: _this.animationTime, minZoomImageRatio: _this.minZoomImageRatio,