mirror of
https://github.com/openseadragon/openseadragon.git
synced 2025-02-18 07:43:13 +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.width = viewportSize.x;
|
||||||
this.canvas.height = viewportSize.y;
|
this.canvas.height = viewportSize.y;
|
||||||
if ( this.sketchCanvas !== null ) {
|
if ( this.sketchCanvas !== null ) {
|
||||||
this.sketchCanvas.width = this.canvas.width;
|
var sketchCanvasSize = this._calculateSketchCanvasSize();
|
||||||
this.sketchCanvas.height = this.canvas.height;
|
this.sketchCanvas.width = sketchCanvasSize.x;
|
||||||
|
this.sketchCanvas.height = sketchCanvasSize.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._clear();
|
this._clear();
|
||||||
@ -313,9 +314,23 @@ $.Drawer.prototype = {
|
|||||||
if ( useSketch ) {
|
if ( useSketch ) {
|
||||||
if (this.sketchCanvas === null) {
|
if (this.sketchCanvas === null) {
|
||||||
this.sketchCanvas = document.createElement( "canvas" );
|
this.sketchCanvas = document.createElement( "canvas" );
|
||||||
this.sketchCanvas.width = this.canvas.width;
|
var sketchCanvasSize = this._calculateSketchCanvasSize();
|
||||||
this.sketchCanvas.height = this.canvas.height;
|
this.sketchCanvas.width = sketchCanvasSize.x;
|
||||||
|
this.sketchCanvas.height = sketchCanvasSize.y;
|
||||||
this.sketchContext = this.sketchCanvas.getContext( "2d" );
|
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;
|
context = this.sketchContext;
|
||||||
}
|
}
|
||||||
@ -383,6 +398,15 @@ $.Drawer.prototype = {
|
|||||||
translate :
|
translate :
|
||||||
new $.Point(0, 0);
|
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.save();
|
||||||
this.context.globalAlpha = opacity;
|
this.context.globalAlpha = opacity;
|
||||||
if (compositeOperation) {
|
if (compositeOperation) {
|
||||||
@ -390,14 +414,14 @@ $.Drawer.prototype = {
|
|||||||
}
|
}
|
||||||
this.context.drawImage(
|
this.context.drawImage(
|
||||||
this.sketchCanvas,
|
this.sketchCanvas,
|
||||||
position.x,
|
position.x - widthExt * scale,
|
||||||
position.y,
|
position.y - heightExt * scale,
|
||||||
this.sketchCanvas.width * scale,
|
(this.canvas.width + 2 * widthExt) * scale,
|
||||||
this.sketchCanvas.height * scale,
|
(this.canvas.height + 2 * heightExt) * scale,
|
||||||
0,
|
-widthExt,
|
||||||
0,
|
-heightExt,
|
||||||
this.canvas.width,
|
this.canvas.width + 2 * widthExt,
|
||||||
this.canvas.height
|
this.canvas.height + 2 * heightExt
|
||||||
);
|
);
|
||||||
this.context.restore();
|
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
|
// private
|
||||||
_offsetForRotation: function(degrees, useSketch) {
|
_offsetForRotation: function(degrees, useSketch) {
|
||||||
var cx = this.canvas.width / 2;
|
var cx = this.canvas.width / 2;
|
||||||
@ -530,6 +564,23 @@ $.Drawer.prototype = {
|
|||||||
x: viewportSize.x * pixelDensityRatio,
|
x: viewportSize.x * pixelDensityRatio,
|
||||||
y: viewportSize.y * 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.
|
* @param {Number} [scale=1] - Scale to be applied to position.
|
||||||
* @return {OpenSeadragon.Point}
|
* @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 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
|
// 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.
|
// to the main canvas. In that case, some browsers throw:
|
||||||
return new $.Point(1, 1).minus(
|
// 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
|
this.position
|
||||||
.times($.pixelDensityRatio)
|
.times($.pixelDensityRatio)
|
||||||
.times(scale || 1)
|
.times(scale || 1)
|
||||||
|
@ -1337,19 +1337,23 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|||||||
|
|
||||||
var zoom = tiledImage.viewport.getZoom(true);
|
var zoom = tiledImage.viewport.getZoom(true);
|
||||||
var imageZoom = tiledImage.viewportToImageZoom(zoom);
|
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.
|
// When zoomed in a lot (>100%) the tile edges are visible.
|
||||||
// So we have to composite them at ~100% and scale them up together.
|
// So we have to composite them at ~100% and scale them up together.
|
||||||
useSketch = true;
|
useSketch = true;
|
||||||
sketchScale = tile.getScaleForEdgeSmoothing();
|
sketchScale = tile.getScaleForEdgeSmoothing();
|
||||||
sketchTranslate = tile.getTranslationForEdgeSmoothing(sketchScale);
|
sketchTranslate = tile.getTranslationForEdgeSmoothing(sketchScale,
|
||||||
|
tiledImage._drawer.getCanvasSize(false),
|
||||||
|
tiledImage._drawer.getCanvasSize(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( useSketch ) {
|
if ( useSketch ) {
|
||||||
tiledImage._drawer._clear( true );
|
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);
|
tiledImage._drawer._offsetForRotation(tiledImage.viewport.degrees, useSketch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1418,12 +1422,19 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|||||||
tiledImage._drawer.restoreContext( useSketch );
|
tiledImage._drawer.restoreContext( useSketch );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tiledImage.viewport.degrees !== 0) {
|
if (tiledImage.viewport.degrees !== 0 && !sketchScale) {
|
||||||
tiledImage._drawer._restoreRotationChanges(useSketch);
|
tiledImage._drawer._restoreRotationChanges(useSketch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( useSketch ) {
|
if (useSketch) {
|
||||||
tiledImage._drawer.blendSketch( tiledImage.opacity, sketchScale, sketchTranslate, tiledImage.compositeOperation );
|
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 );
|
drawDebugInfo( tiledImage, lastDrawn );
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user