mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 14:46:10 +03:00
Merge pull request #825 from avandecreme/rotation
Fix edge smoothing with rotation.
This commit is contained in:
commit
a244d7ef86
@ -250,8 +250,9 @@ $.Drawer.prototype = {
|
||||
this.canvas.width = viewportSize.x;
|
||||
this.canvas.height = viewportSize.y;
|
||||
if ( this.sketchCanvas !== null ) {
|
||||
this.sketchCanvas.width = this.canvas.width;
|
||||
this.sketchCanvas.height = this.canvas.height;
|
||||
var sketchCanvasSize = this._calculateSketchCanvasSize();
|
||||
this.sketchCanvas.width = sketchCanvasSize.x;
|
||||
this.sketchCanvas.height = sketchCanvasSize.y;
|
||||
}
|
||||
}
|
||||
this._clear();
|
||||
@ -313,9 +314,23 @@ $.Drawer.prototype = {
|
||||
if ( useSketch ) {
|
||||
if (this.sketchCanvas === null) {
|
||||
this.sketchCanvas = document.createElement( "canvas" );
|
||||
this.sketchCanvas.width = this.canvas.width;
|
||||
this.sketchCanvas.height = this.canvas.height;
|
||||
var sketchCanvasSize = this._calculateSketchCanvasSize();
|
||||
this.sketchCanvas.width = sketchCanvasSize.x;
|
||||
this.sketchCanvas.height = sketchCanvasSize.y;
|
||||
this.sketchContext = this.sketchCanvas.getContext( "2d" );
|
||||
|
||||
// If the viewport is not currently rotated, the sketchCanvas
|
||||
// will have the same size as the main canvas. However, if
|
||||
// the viewport get rotated later on, we will need to resize it.
|
||||
if (this.viewport.getRotation() === 0) {
|
||||
var self = this;
|
||||
this.viewer.addHandler('rotate', function resizeSketchCanvas() {
|
||||
self.viewer.removeHandler('rotate', resizeSketchCanvas);
|
||||
var sketchCanvasSize = self._calculateSketchCanvasSize();
|
||||
self.sketchCanvas.width = sketchCanvasSize.x;
|
||||
self.sketchCanvas.height = sketchCanvasSize.y;
|
||||
});
|
||||
}
|
||||
}
|
||||
context = this.sketchContext;
|
||||
}
|
||||
@ -383,6 +398,15 @@ $.Drawer.prototype = {
|
||||
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.save();
|
||||
this.context.globalAlpha = opacity;
|
||||
if (compositeOperation) {
|
||||
@ -390,14 +414,14 @@ $.Drawer.prototype = {
|
||||
}
|
||||
this.context.drawImage(
|
||||
this.sketchCanvas,
|
||||
position.x,
|
||||
position.y,
|
||||
this.sketchCanvas.width * scale,
|
||||
this.sketchCanvas.height * scale,
|
||||
0,
|
||||
0,
|
||||
this.canvas.width,
|
||||
this.canvas.height
|
||||
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();
|
||||
},
|
||||
@ -503,6 +527,16 @@ $.Drawer.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the canvas size
|
||||
* @param {Boolean} sketch If set to true return the size of the sketch canvas
|
||||
* @returns {OpenSeadragon.Point} The size of the canvas
|
||||
*/
|
||||
getCanvasSize: function(sketch) {
|
||||
var canvas = this._getContext(sketch).canvas;
|
||||
return new $.Point(canvas.width, canvas.height);
|
||||
},
|
||||
|
||||
// private
|
||||
_offsetForRotation: function(degrees, useSketch) {
|
||||
var cx = this.canvas.width / 2;
|
||||
@ -530,6 +564,23 @@ $.Drawer.prototype = {
|
||||
x: viewportSize.x * pixelDensityRatio,
|
||||
y: viewportSize.y * pixelDensityRatio
|
||||
};
|
||||
},
|
||||
|
||||
// private
|
||||
_calculateSketchCanvasSize: function() {
|
||||
var canvasSize = this._calculateCanvasSize();
|
||||
if (this.viewport.getRotation() === 0) {
|
||||
return canvasSize;
|
||||
}
|
||||
// If the viewport is rotated, we need a larger sketch canvas in order
|
||||
// to support edge smoothing.
|
||||
var sketchCanvasSize = Math.ceil(Math.sqrt(
|
||||
canvasSize.x * canvasSize.x +
|
||||
canvasSize.y * canvasSize.y));
|
||||
return {
|
||||
x: sketchCanvasSize,
|
||||
y: sketchCanvasSize
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -351,11 +351,14 @@ $.Tile.prototype = {
|
||||
* @param {Number} [scale=1] - Scale to be applied to position.
|
||||
* @return {OpenSeadragon.Point}
|
||||
*/
|
||||
getTranslationForEdgeSmoothing: function(scale) {
|
||||
getTranslationForEdgeSmoothing: function(scale, canvasSize, sketchCanvasSize) {
|
||||
// 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
|
||||
// to the main canvas. And FF does not like it. It crashes the viewer.
|
||||
return new $.Point(1, 1).minus(
|
||||
// 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(
|
||||
this.position
|
||||
.times($.pixelDensityRatio)
|
||||
.times(scale || 1)
|
||||
|
@ -1337,19 +1337,23 @@ function drawTiles( tiledImage, lastDrawn ) {
|
||||
|
||||
var zoom = tiledImage.viewport.getZoom(true);
|
||||
var imageZoom = tiledImage.viewportToImageZoom(zoom);
|
||||
if ( imageZoom > tiledImage.smoothTileEdgesMinZoom && tile) {
|
||||
if (imageZoom > tiledImage.smoothTileEdgesMinZoom && tile) {
|
||||
// When zoomed in a lot (>100%) the tile edges are visible.
|
||||
// So we have to composite them at ~100% and scale them up together.
|
||||
useSketch = true;
|
||||
sketchScale = tile.getScaleForEdgeSmoothing();
|
||||
sketchTranslate = tile.getTranslationForEdgeSmoothing(sketchScale);
|
||||
sketchTranslate = tile.getTranslationForEdgeSmoothing(sketchScale,
|
||||
tiledImage._drawer.getCanvasSize(false),
|
||||
tiledImage._drawer.getCanvasSize(true));
|
||||
}
|
||||
|
||||
if ( useSketch ) {
|
||||
tiledImage._drawer._clear( true );
|
||||
}
|
||||
|
||||
if (tiledImage.viewport.degrees !== 0) {
|
||||
// When scaling, we must rotate only when blending the sketch canvas to avoid
|
||||
// interpolation
|
||||
if (tiledImage.viewport.degrees !== 0 && !sketchScale) {
|
||||
tiledImage._drawer._offsetForRotation(tiledImage.viewport.degrees, useSketch);
|
||||
}
|
||||
|
||||
@ -1418,12 +1422,19 @@ function drawTiles( tiledImage, lastDrawn ) {
|
||||
tiledImage._drawer.restoreContext( useSketch );
|
||||
}
|
||||
|
||||
if (tiledImage.viewport.degrees !== 0) {
|
||||
if (tiledImage.viewport.degrees !== 0 && !sketchScale) {
|
||||
tiledImage._drawer._restoreRotationChanges(useSketch);
|
||||
}
|
||||
|
||||
if ( useSketch ) {
|
||||
tiledImage._drawer.blendSketch( tiledImage.opacity, sketchScale, sketchTranslate, tiledImage.compositeOperation );
|
||||
if (useSketch) {
|
||||
var offsetForRotation = tiledImage.viewport.degrees !== 0 && sketchScale;
|
||||
if (offsetForRotation) {
|
||||
tiledImage._drawer._offsetForRotation(tiledImage.viewport.degrees, false);
|
||||
}
|
||||
tiledImage._drawer.blendSketch(tiledImage.opacity, sketchScale, sketchTranslate, tiledImage.compositeOperation);
|
||||
if (offsetForRotation) {
|
||||
tiledImage._drawer._restoreRotationChanges(false);
|
||||
}
|
||||
}
|
||||
drawDebugInfo( tiledImage, lastDrawn );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user