mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-21 20:56:09 +03:00
Merge pull request #927 from avandecreme/perf
Optimize sketch canvas clearing and blending.
This commit is contained in:
commit
07429f5890
107
src/drawer.js
107
src/drawer.js
@ -259,13 +259,17 @@ $.Drawer.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_clear: function ( useSketch ) {
|
||||
if ( !this.useCanvas ) {
|
||||
_clear: function (useSketch, bounds) {
|
||||
if (!this.useCanvas) {
|
||||
return;
|
||||
}
|
||||
var context = this._getContext( useSketch );
|
||||
var canvas = context.canvas;
|
||||
context.clearRect( 0, 0, canvas.width, canvas.height );
|
||||
var context = this._getContext(useSketch);
|
||||
if (bounds) {
|
||||
context.clearRect(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
} else {
|
||||
var canvas = context.canvas;
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -382,47 +386,80 @@ $.Drawer.prototype = {
|
||||
|
||||
/**
|
||||
* Blends the sketch canvas in the main canvas.
|
||||
* @param {Float} opacity The opacity of the blending.
|
||||
* @param {Float} [scale=1] The scale at which tiles were drawn on the sketch. Default is 1.
|
||||
* Use scale to draw at a lower scale and then enlarge onto the main canvas.
|
||||
* @param {OpenSeadragon.Point} [translate] A translation vector that was used to draw the tiles
|
||||
* @param {String} [options.compositeOperation] - How the image is composited onto other images; see compositeOperation in {@link OpenSeadragon.Options} for possible values.
|
||||
* @returns {undefined}
|
||||
* @param {Object} options The options
|
||||
* @param {Float} options.opacity The opacity of the blending.
|
||||
* @param {Float} [options.scale=1] The scale at which tiles were drawn on
|
||||
* the sketch. Default is 1.
|
||||
* Use scale to draw at a lower scale and then enlarge onto the main canvas.
|
||||
* @param {OpenSeadragon.Point} [options.translate] A translation vector
|
||||
* that was used to draw the tiles
|
||||
* @param {String} [options.compositeOperation] - How the image is
|
||||
* composited onto other images; see compositeOperation in
|
||||
* {@link OpenSeadragon.Options} for possible values.
|
||||
* @param {OpenSeadragon.Rect} [options.bounds] The part of the sketch
|
||||
* canvas to blend in the main canvas. If specified, options.scale and
|
||||
* options.translate get ignored.
|
||||
*/
|
||||
blendSketch: function(opacity, scale, translate, compositeOperation) {
|
||||
var options = opacity;
|
||||
if (!$.isPlainObject(options)) {
|
||||
options = {
|
||||
opacity: opacity,
|
||||
scale: scale,
|
||||
translate: translate,
|
||||
compositeOperation: compositeOperation
|
||||
};
|
||||
}
|
||||
if (!this.useCanvas || !this.sketchCanvas) {
|
||||
return;
|
||||
}
|
||||
scale = scale || 1;
|
||||
var position = translate instanceof $.Point ?
|
||||
translate :
|
||||
new $.Point(0, 0);
|
||||
|
||||
var widthExt = 0;
|
||||
var heightExt = 0;
|
||||
if (translate) {
|
||||
var widthDiff = this.sketchCanvas.width - this.canvas.width;
|
||||
var heightDiff = this.sketchCanvas.height - this.canvas.height;
|
||||
widthExt = Math.round(widthDiff / 2);
|
||||
heightExt = Math.round(heightDiff / 2);
|
||||
}
|
||||
opacity = options.opacity;
|
||||
compositeOperation = options.compositeOperation;
|
||||
var bounds = options.bounds;
|
||||
|
||||
this.context.save();
|
||||
this.context.globalAlpha = opacity;
|
||||
if (compositeOperation) {
|
||||
this.context.globalCompositeOperation = compositeOperation;
|
||||
}
|
||||
this.context.drawImage(
|
||||
this.sketchCanvas,
|
||||
position.x - widthExt * scale,
|
||||
position.y - heightExt * scale,
|
||||
(this.canvas.width + 2 * widthExt) * scale,
|
||||
(this.canvas.height + 2 * heightExt) * scale,
|
||||
-widthExt,
|
||||
-heightExt,
|
||||
this.canvas.width + 2 * widthExt,
|
||||
this.canvas.height + 2 * heightExt
|
||||
);
|
||||
if (bounds) {
|
||||
this.context.drawImage(
|
||||
this.sketchCanvas,
|
||||
bounds.x,
|
||||
bounds.y,
|
||||
bounds.width,
|
||||
bounds.height,
|
||||
bounds.x,
|
||||
bounds.y,
|
||||
bounds.width,
|
||||
bounds.height
|
||||
);
|
||||
} else {
|
||||
scale = options.scale || 1;
|
||||
translate = options.translate;
|
||||
var position = translate instanceof $.Point ?
|
||||
translate : new $.Point(0, 0);
|
||||
|
||||
var widthExt = 0;
|
||||
var heightExt = 0;
|
||||
if (translate) {
|
||||
var widthDiff = this.sketchCanvas.width - this.canvas.width;
|
||||
var heightDiff = this.sketchCanvas.height - this.canvas.height;
|
||||
widthExt = Math.round(widthDiff / 2);
|
||||
heightExt = Math.round(heightDiff / 2);
|
||||
}
|
||||
this.context.drawImage(
|
||||
this.sketchCanvas,
|
||||
position.x - widthExt * scale,
|
||||
position.y - heightExt * scale,
|
||||
(this.canvas.width + 2 * widthExt) * scale,
|
||||
(this.canvas.height + 2 * heightExt) * scale,
|
||||
-widthExt,
|
||||
-heightExt,
|
||||
this.canvas.width + 2 * widthExt,
|
||||
this.canvas.height + 2 * heightExt
|
||||
);
|
||||
}
|
||||
this.context.restore();
|
||||
},
|
||||
|
||||
|
@ -367,6 +367,20 @@ $.Rect.prototype = {
|
||||
maxY - minY);
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the smallest horizontal (degrees=0) rectangle which contains
|
||||
* this rectangle and has integers x, y, width and height
|
||||
* @returns {OpenSeadragon.Rect}
|
||||
*/
|
||||
getIntegerBoundingBox: function() {
|
||||
var boundingBox = this.getBoundingBox();
|
||||
var x = Math.floor(boundingBox.x);
|
||||
var y = Math.floor(boundingBox.y);
|
||||
var width = Math.ceil(boundingBox.width + boundingBox.x - x);
|
||||
var height = Math.ceil(boundingBox.height + boundingBox.y - y);
|
||||
return new $.Rect(x, y, width, height);
|
||||
},
|
||||
|
||||
/**
|
||||
* Provides a string representation of the rectangle which is useful for
|
||||
* debugging.
|
||||
|
@ -195,7 +195,7 @@ $.Tile.prototype = {
|
||||
|
||||
// private
|
||||
_hasTransparencyChannel: function() {
|
||||
return this.context2D || this.url.match('.png');
|
||||
return !!this.context2D || this.url.match('.png');
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1448,8 +1448,17 @@ function drawTiles( tiledImage, lastDrawn ) {
|
||||
tiledImage._drawer.getCanvasSize(true));
|
||||
}
|
||||
|
||||
if ( useSketch ) {
|
||||
tiledImage._drawer._clear( true );
|
||||
var bounds;
|
||||
if (useSketch) {
|
||||
if (!sketchScale) {
|
||||
// Except when edge smoothing, we only clean the part of the
|
||||
// sketch canvas we are going to use for performance reasons.
|
||||
bounds = tiledImage.viewport.viewportToViewerElementRectangle(
|
||||
tiledImage.getClippedBounds(true))
|
||||
.getIntegerBoundingBox()
|
||||
.times($.pixelDensityRatio);
|
||||
}
|
||||
tiledImage._drawer._clear(true, bounds);
|
||||
}
|
||||
|
||||
// When scaling, we must rotate only when blending the sketch canvas to avoid
|
||||
@ -1532,7 +1541,13 @@ function drawTiles( tiledImage, lastDrawn ) {
|
||||
if (offsetForRotation) {
|
||||
tiledImage._drawer._offsetForRotation(tiledImage.viewport.degrees, false);
|
||||
}
|
||||
tiledImage._drawer.blendSketch(tiledImage.opacity, sketchScale, sketchTranslate, tiledImage.compositeOperation);
|
||||
tiledImage._drawer.blendSketch({
|
||||
opacity: tiledImage.opacity,
|
||||
scale: sketchScale,
|
||||
translate: sketchTranslate,
|
||||
compositeOperation: tiledImage.compositeOperation,
|
||||
bounds: bounds
|
||||
});
|
||||
if (offsetForRotation) {
|
||||
tiledImage._drawer._restoreRotationChanges(false);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user