fix canvas drawer when viewport is flipped and tiled image is rotated. fix webgl drawer debug info when viewport is flipped.

This commit is contained in:
Tom 2024-04-10 16:42:15 -04:00
parent 49e2d7a987
commit f7c8e4cf33
2 changed files with 117 additions and 128 deletions

View File

@ -80,6 +80,7 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
// Canvas default is "true", so this will only be changed if user specifies "false" in the options or via setImageSmoothinEnabled. // Canvas default is "true", so this will only be changed if user specifies "false" in the options or via setImageSmoothinEnabled.
this._imageSmoothingEnabled = true; this._imageSmoothingEnabled = true;
this._viewportFlipped = false;
// Since the tile-drawn and tile-drawing events are fired by this drawer, make sure handlers can be added for them // Since the tile-drawn and tile-drawing events are fired by this drawer, make sure handlers can be added for them
this.viewer.allowEventHandler("tile-drawn"); this.viewer.allowEventHandler("tile-drawn");
@ -115,7 +116,10 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
*/ */
draw(tiledImages) { draw(tiledImages) {
this._prepareNewFrame(); // prepare to draw a new frame this._prepareNewFrame(); // prepare to draw a new frame
if(this.viewer.viewport.getFlip() !== this._viewportFlipped){
this._flip();
this._viewportFlipped = !this._viewportFlipped;
}
for(const tiledImage of tiledImages){ for(const tiledImage of tiledImages){
if (tiledImage.opacity !== 0) { if (tiledImage.opacity !== 0) {
this._drawTiles(tiledImage); this._drawTiles(tiledImage);
@ -300,13 +304,6 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
tiledImage.getClippedBounds(true)) tiledImage.getClippedBounds(true))
.getIntegerBoundingBox(); .getIntegerBoundingBox();
if(this.viewer.viewport.getFlip()) {
if (this.viewport.getRotation(true) % 360 !== 0 ||
tiledImage.getRotation(true) % 360 !== 0) {
bounds.x = this.viewer.container.clientWidth - (bounds.x + bounds.width);
}
}
bounds = bounds.times($.pixelDensityRatio); bounds = bounds.times($.pixelDensityRatio);
} }
this._clear(true, bounds); this._clear(true, bounds);
@ -315,27 +312,7 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
// When scaling, we must rotate only when blending the sketch canvas to // When scaling, we must rotate only when blending the sketch canvas to
// avoid interpolation // avoid interpolation
if (!sketchScale) { if (!sketchScale) {
if (this.viewport.getRotation(true) % 360 !== 0) { this._setRotations(tiledImage, useSketch);
this._offsetForRotation({
degrees: this.viewport.getRotation(true),
useSketch: useSketch
});
}
if (tiledImage.getRotation(true) % 360 !== 0) {
this._offsetForRotation({
degrees: tiledImage.getRotation(true),
point: this.viewport.pixelFromPointNoRotate(
tiledImage._getRotationPoint(true), true),
useSketch: useSketch
});
}
if (this.viewport.getRotation(true) % 360 === 0 &&
tiledImage.getRotation(true) % 360 === 0) {
if(this.viewer.viewport.getFlip()) {
this._flip();
}
}
} }
var usedClip = false; var usedClip = false;
@ -456,20 +433,7 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
if (useSketch) { if (useSketch) {
if (sketchScale) { if (sketchScale) {
if (this.viewport.getRotation(true) % 360 !== 0) { this._setRotations(tiledImage);
this._offsetForRotation({
degrees: this.viewport.getRotation(true),
useSketch: false
});
}
if (tiledImage.getRotation(true) % 360 !== 0) {
this._offsetForRotation({
degrees: tiledImage.getRotation(true),
point: this.viewport.pixelFromPointNoRotate(
tiledImage._getRotationPoint(true), true),
useSketch: false
});
}
} }
this.blendSketch({ this.blendSketch({
opacity: tiledImage.opacity, opacity: tiledImage.opacity,
@ -488,15 +452,6 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
} }
} }
if (!sketchScale) {
if (this.viewport.getRotation(true) % 360 === 0 &&
tiledImage.getRotation(true) % 360 === 0) {
if(this.viewer.viewport.getFlip()) {
this._flip();
}
}
}
this._drawDebugInfo( tiledImage, lastDrawn ); this._drawDebugInfo( tiledImage, lastDrawn );
// Fire tiled-image-drawn event. // Fire tiled-image-drawn event.
@ -607,7 +562,6 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
} }
context.save(); context.save();
// context.globalAlpha = this.options.opacity; // this was deprecated previously and should not be applied as it is set per TiledImage
if (typeof scale === 'number' && scale !== 1) { if (typeof scale === 'number' && scale !== 1) {
// draw tile at a different scale // draw tile at a different scale
@ -853,21 +807,10 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
context.strokeStyle = this.debugGridColor[colorIndex]; context.strokeStyle = this.debugGridColor[colorIndex];
context.fillStyle = this.debugGridColor[colorIndex]; context.fillStyle = this.debugGridColor[colorIndex];
if (this.viewport.getRotation(true) % 360 !== 0 ) { this._setRotations(tiledImage);
this._offsetForRotation({degrees: this.viewport.getRotation(true)});
} if(this._viewportFlipped){
if (tiledImage.getRotation(true) % 360 !== 0) { this._flip({point: tile.position.plus(tile.size.divide(2))});
this._offsetForRotation({
degrees: tiledImage.getRotation(true),
point: tiledImage.viewport.pixelFromPointNoRotate(
tiledImage._getRotationPoint(true), true)
});
}
if (tiledImage.viewport.getRotation(true) % 360 === 0 &&
tiledImage.getRotation(true) % 360 === 0) {
if(tiledImage._drawer.viewer.viewport.getFlip()) {
tiledImage._drawer._flip();
}
} }
context.strokeRect( context.strokeRect(
@ -882,7 +825,8 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
// Rotate the text the right way around. // Rotate the text the right way around.
context.translate( tileCenterX, tileCenterY ); context.translate( tileCenterX, tileCenterY );
context.rotate( Math.PI / 180 * -this.viewport.getRotation(true) ); const angleInDegrees = this.viewport.getRotation(true);
context.rotate( Math.PI / 180 * -angleInDegrees );
context.translate( -tileCenterX, -tileCenterY ); context.translate( -tileCenterX, -tileCenterY );
if( tile.x === 0 && tile.y === 0 ){ if( tile.x === 0 && tile.y === 0 ){
@ -935,13 +879,6 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
this._restoreRotationChanges(); this._restoreRotationChanges();
} }
if (tiledImage.viewport.getRotation(true) % 360 === 0 &&
tiledImage.getRotation(true) % 360 === 0) {
if(tiledImage._drawer.viewer.viewport.getFlip()) {
tiledImage._drawer._flip();
}
}
context.restore(); context.restore();
} }
@ -972,6 +909,33 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
return new $.Point(this.canvas.width / 2, this.canvas.height / 2); return new $.Point(this.canvas.width / 2, this.canvas.height / 2);
} }
/**
* Set rotations for viewport & tiledImage
* @private
* @param {OpenSeadragon.TiledImage} tiledImage
* @param {Boolean} [useSketch=false]
*/
_setRotations(tiledImage, useSketch = false) {
var saveContext = false;
if (this.viewport.getRotation(true) % 360 !== 0) {
this._offsetForRotation({
degrees: this.viewport.getRotation(true),
useSketch: useSketch,
saveContext: saveContext
});
saveContext = false;
}
if (tiledImage.getRotation(true) % 360 !== 0) {
this._offsetForRotation({
degrees: tiledImage.getRotation(true),
point: this.viewport.pixelFromPointNoRotate(
tiledImage._getRotationPoint(true), true),
useSketch: useSketch,
saveContext: saveContext
});
}
}
// private // private
_offsetForRotation(options) { _offsetForRotation(options) {
var point = options.point ? var point = options.point ?
@ -982,26 +946,21 @@ class CanvasDrawer extends OpenSeadragon.DrawerBase{
context.save(); context.save();
context.translate(point.x, point.y); context.translate(point.x, point.y);
if(this.viewer.viewport.flipped){ context.rotate(Math.PI / 180 * options.degrees);
context.rotate(Math.PI / 180 * -options.degrees);
context.scale(-1, 1);
} else{
context.rotate(Math.PI / 180 * options.degrees);
}
context.translate(-point.x, -point.y); context.translate(-point.x, -point.y);
} }
// private // private
_flip(options) { _flip(options) {
options = options || {}; options = options || {};
var point = options.point ? var point = options.point ?
options.point.times($.pixelDensityRatio) : options.point.times($.pixelDensityRatio) :
this._getCanvasCenter(); this._getCanvasCenter();
var context = this._getContext(options.useSketch); var context = this._getContext(options.useSketch);
context.translate(point.x, 0); context.translate(point.x, 0);
context.scale(-1, 1); context.scale(-1, 1);
context.translate(-point.x, 0); context.translate(-point.x, 0);
} }
// private // private

View File

@ -529,10 +529,14 @@
} }
this._outputContext.restore(); this._outputContext.restore();
if(tiledImage.debugMode){ if(tiledImage.debugMode){
let colorIndex = this.viewer.world.getIndexOfItem(tiledImage) % this.debugGridColor.length; const flipped = this.viewer.viewport.getFlip();
let strokeStyle = this.debugGridColor[colorIndex]; if(flipped){
let fillStyle = this.debugGridColor[colorIndex]; this._flip();
this._drawDebugInfo(tilesToDraw, tiledImage, strokeStyle, fillStyle); }
this._drawDebugInfo(tilesToDraw, tiledImage, flipped);
if(flipped){
this._flip();
}
} }
@ -1067,32 +1071,64 @@
this._clippingContext.restore(); this._clippingContext.restore();
} }
/**
* Set rotations for viewport & tiledImage
* @private
* @param {OpenSeadragon.TiledImage} tiledImage
*/
_setRotations(tiledImage) {
var saveContext = false;
if (this.viewport.getRotation(true) % 360 !== 0) {
this._offsetForRotation({
degrees: this.viewport.getRotation(true),
saveContext: saveContext
});
saveContext = false;
}
if (tiledImage.getRotation(true) % 360 !== 0) {
this._offsetForRotation({
degrees: tiledImage.getRotation(true),
point: this.viewport.pixelFromPointNoRotate(
tiledImage._getRotationPoint(true), true),
saveContext: saveContext
});
}
}
// private // private
_offsetForRotation(options) { _offsetForRotation(options) {
var point = options.point ? var point = options.point ?
options.point.times($.pixelDensityRatio) : options.point.times($.pixelDensityRatio) :
new $.Point(this._outputCanvas.width / 2, this._outputCanvas.height / 2); this._getCanvasCenter();
var context = this._outputContext; var context = this._outputContext;
context.save(); context.save();
context.translate(point.x, point.y); context.translate(point.x, point.y);
if(this.viewport.flipped){ context.rotate(Math.PI / 180 * options.degrees);
context.rotate(Math.PI / 180 * -options.degrees);
context.scale(-1, 1);
} else{
context.rotate(Math.PI / 180 * options.degrees);
}
context.translate(-point.x, -point.y); context.translate(-point.x, -point.y);
} }
// private // private
_drawDebugInfo( tilesToDraw, tiledImage, stroke, fill ) { _flip(options) {
options = options || {};
var point = options.point ?
options.point.times($.pixelDensityRatio) :
this._getCanvasCenter();
var context = this._outputContext;
context.translate(point.x, 0);
context.scale(-1, 1);
context.translate(-point.x, 0);
}
// private
_drawDebugInfo( tilesToDraw, tiledImage, flipped ) {
for ( var i = tilesToDraw.length - 1; i >= 0; i-- ) { for ( var i = tilesToDraw.length - 1; i >= 0; i-- ) {
var tile = tilesToDraw[ i ].tile; var tile = tilesToDraw[ i ].tile;
try { try {
this._drawDebugInfoOnTile(tile, tilesToDraw.length, i, tiledImage, stroke, fill); this._drawDebugInfoOnTile(tile, tilesToDraw.length, i, tiledImage, flipped);
} catch(e) { } catch(e) {
$.console.error(e); $.console.error(e);
} }
@ -1100,30 +1136,20 @@
} }
// private // private
_drawDebugInfoOnTile(tile, count, i, tiledImage, stroke, fill) { _drawDebugInfoOnTile(tile, count, i, tiledImage, flipped) {
var context = this._outputContext; var colorIndex = this.viewer.world.getIndexOfItem(tiledImage) % this.debugGridColor.length;
var context = this.context;
context.save(); context.save();
context.lineWidth = 2 * $.pixelDensityRatio; context.lineWidth = 2 * $.pixelDensityRatio;
context.font = 'small-caps bold ' + (13 * $.pixelDensityRatio) + 'px arial'; context.font = 'small-caps bold ' + (13 * $.pixelDensityRatio) + 'px arial';
context.strokeStyle = stroke; context.strokeStyle = this.debugGridColor[colorIndex];
context.fillStyle = fill; context.fillStyle = this.debugGridColor[colorIndex];
if (this.viewport.getRotation(true) % 360 !== 0 ) { this._setRotations(tiledImage);
this._offsetForRotation({degrees: this.viewport.getRotation(true)});
} if(flipped){
if (tiledImage.getRotation(true) % 360 !== 0) { this._flip({point: tile.position.plus(tile.size.divide(2))});
this._offsetForRotation({
degrees: tiledImage.getRotation(true),
point: tiledImage.viewport.pixelFromPointNoRotate(
tiledImage._getRotationPoint(true), true)
});
}
if (tiledImage.viewport.getRotation(true) % 360 === 0 &&
tiledImage.getRotation(true) % 360 === 0) {
if(tiledImage._drawer.viewer.viewport.getFlip()) {
tiledImage._drawer._flip();
}
} }
context.strokeRect( context.strokeRect(
@ -1138,7 +1164,8 @@
// Rotate the text the right way around. // Rotate the text the right way around.
context.translate( tileCenterX, tileCenterY ); context.translate( tileCenterX, tileCenterY );
context.rotate( Math.PI / 180 * -this.viewport.getRotation(true) ); const angleInDegrees = this.viewport.getRotation(true);
context.rotate( Math.PI / 180 * -angleInDegrees );
context.translate( -tileCenterX, -tileCenterY ); context.translate( -tileCenterX, -tileCenterY );
if( tile.x === 0 && tile.y === 0 ){ if( tile.x === 0 && tile.y === 0 ){
@ -1191,13 +1218,6 @@
this._restoreRotationChanges(); this._restoreRotationChanges();
} }
if (tiledImage.viewport.getRotation(true) % 360 === 0 &&
tiledImage.getRotation(true) % 360 === 0) {
if(tiledImage._drawer.viewer.viewport.getFlip()) {
tiledImage._drawer._flip();
}
}
context.restore(); context.restore();
} }
@ -1225,6 +1245,16 @@
} }
/**
* Get the canvas center
* @private
* @param {Boolean} sketch If set to true return the center point of the sketch canvas
* @returns {OpenSeadragon.Point} The center point of the canvas
*/
_getCanvasCenter() {
return new $.Point(this.canvas.width / 2, this.canvas.height / 2);
}
// private // private
_restoreRotationChanges() { _restoreRotationChanges() {
var context = this._outputContext; var context = this._outputContext;