From 44347fb2d00e58402cded849341ff9f732105c83 Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Tue, 18 Jun 2024 10:57:55 +0100 Subject: [PATCH 1/8] Fixed: Invert overlay scale and rotate on flip --- src/overlay.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/overlay.js b/src/overlay.js index bc25a051..b942409a 100644 --- a/src/overlay.js +++ b/src/overlay.js @@ -259,7 +259,16 @@ var position = positionAndSize.position; var size = this.size = positionAndSize.size; - var rotate = positionAndSize.rotate; + var rotate; + var scale = ""; + + if (viewport.flipped){ + rotate = -positionAndSize.rotate; + scale = " scaleX(-1)"; + } + else { + rotate = positionAndSize.rotate; + } // call the onDraw callback if it exists to allow one to overwrite // the drawing/positioning/sizing of the overlay @@ -282,7 +291,10 @@ if (transformOriginProp && transformProp) { if (rotate) { style[transformOriginProp] = this._getTransformOrigin(); - style[transformProp] = "rotate(" + rotate + "deg)"; + style[transformProp] = "rotate(" + rotate + "deg)" + scale; + } else if (!rotate && viewport.flipped) { + style[transformOriginProp] = this._getTransformOrigin(); + style[transformProp] = "scaleX(-1)"; } else { style[transformOriginProp] = ""; style[transformProp] = ""; @@ -308,12 +320,21 @@ var rect = new $.Rect(position.x, position.y, size.x, size.y); var boundingBox = this._getBoundingBox(rect, viewport.getRotation(true)); position = boundingBox.getTopLeft(); + position = boundingBox.getTopLeft(); + + if (viewport.flipped){ + position.x = (viewport.getContainerSize().x - position.x); + } + size = boundingBox.getSize(); } else { rotate = viewport.getRotation(true); } } + if (viewport.flipped) { + position.x = (viewport.getContainerSize().x - position.x); + } return { position: position, size: size, From 79eecdcc7602aa85efe68aaaa7b67f69f24a315d Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Tue, 18 Jun 2024 11:10:11 +0100 Subject: [PATCH 2/8] Fixed: Remove duplicate line --- src/overlay.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/overlay.js b/src/overlay.js index b942409a..5676769d 100644 --- a/src/overlay.js +++ b/src/overlay.js @@ -320,8 +320,7 @@ var rect = new $.Rect(position.x, position.y, size.x, size.y); var boundingBox = this._getBoundingBox(rect, viewport.getRotation(true)); position = boundingBox.getTopLeft(); - position = boundingBox.getTopLeft(); - + if (viewport.flipped){ position.x = (viewport.getContainerSize().x - position.x); } From 263dc85fbd4816266c8042ce624befe91a711b15 Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Tue, 18 Jun 2024 11:22:23 +0100 Subject: [PATCH 3/8] Fixed: Remove trailing spaces --- src/overlay.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/overlay.js b/src/overlay.js index 5676769d..c77be16d 100644 --- a/src/overlay.js +++ b/src/overlay.js @@ -261,7 +261,7 @@ var size = this.size = positionAndSize.size; var rotate; var scale = ""; - + if (viewport.flipped){ rotate = -positionAndSize.rotate; scale = " scaleX(-1)"; @@ -269,7 +269,6 @@ else { rotate = positionAndSize.rotate; } - // call the onDraw callback if it exists to allow one to overwrite // the drawing/positioning/sizing of the overlay if (this.onDraw) { @@ -320,11 +319,9 @@ var rect = new $.Rect(position.x, position.y, size.x, size.y); var boundingBox = this._getBoundingBox(rect, viewport.getRotation(true)); position = boundingBox.getTopLeft(); - if (viewport.flipped){ position.x = (viewport.getContainerSize().x - position.x); } - size = boundingBox.getSize(); } else { rotate = viewport.getRotation(true); From 2c6b970f29a758fabbab0db09c6f614133a0cd83 Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Tue, 18 Jun 2024 11:28:29 +0100 Subject: [PATCH 4/8] Fixed: Remove trailing space --- src/overlay.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/overlay.js b/src/overlay.js index c77be16d..42c8ec73 100644 --- a/src/overlay.js +++ b/src/overlay.js @@ -261,7 +261,6 @@ var size = this.size = positionAndSize.size; var rotate; var scale = ""; - if (viewport.flipped){ rotate = -positionAndSize.rotate; scale = " scaleX(-1)"; From 176fae11e5f4c6f12626331cd24d1b6cfdfc6b5b Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Tue, 9 Jul 2024 14:08:58 +0100 Subject: [PATCH 5/8] Fixed: Add inner div if text and invert x --- src/overlay.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/overlay.js b/src/overlay.js index b5330d58..6d355c7a 100644 --- a/src/overlay.js +++ b/src/overlay.js @@ -2,7 +2,7 @@ * OpenSeadragon - Overlay * * Copyright (C) 2009 CodePlex Foundation - * Copyright (C) 2010-2023 OpenSeadragon contributors + * Copyright (C) 2010-2024 OpenSeadragon contributors * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -242,6 +242,9 @@ */ drawHTML: function(container, viewport) { var element = this.element; + var text = document.createElement('div'); + text.textContent = element.textContent; + element.textContent = ""; if (element.parentNode !== container) { //save the source parent for later if we need it element.prevElementParent = element.parentNode; @@ -274,6 +277,7 @@ this.onDraw(position, size, this.element); } else { var style = this.style; + var textStyle = text.style; style.left = position.x + "px"; style.top = position.y + "px"; if (this.width !== null) { @@ -291,9 +295,11 @@ style[transformOriginProp] = this._getTransformOrigin(); style[transformProp] = "rotate(" + rotate + "deg)"; } else if (!rotate && viewport.flipped) { + textStyle[transformProp] = "scaleX(-1)"; style[transformOriginProp] = this._getTransformOrigin(); style[transformProp] = scale; } else if (rotate && viewport.flipped){ + textStyle[transformProp] = "scaleX(-1)"; style[transformOriginProp] = this._getTransformOrigin(); style[transformProp] = "rotate(" + rotate + "deg)" + scale; } else { @@ -302,6 +308,7 @@ } } style.display = 'block'; + element.appendChild(text); } }, From 396fcb33a516e8eca591a713d85fd07306863060 Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Thu, 11 Jul 2024 22:08:37 +0100 Subject: [PATCH 6/8] Fixed: Outer div added to element to allow independent flipping An outer div has been added to the internal HTML of the overlay element to allow for independent flipping of the content. Flipping will invert the `scaleX` value of the transform property for the style of the element. By setting the value `overlayContentFlipped: true` in the OSD config we can flip the content in the opposite direction to the overlay, but by setting this to false we can flip the content along with the overlay. This allows for some people who are using images in their overlay to flip the images along with the overlay. --- src/openseadragon.js | 4 ++++ src/overlay.js | 29 ++++++++++++----------------- src/viewer.js | 1 + test/demo/overlay.html | 16 +++++++++++++++- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/openseadragon.js b/src/openseadragon.js index 2cb2ac0d..a907d84c 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -230,6 +230,9 @@ * @property {Boolean} [flipped=false] * Initial flip state. * + * @property {Boolean} [overlayContentFlipped=false] + * Initial overlay content flip state. + * * @property {Number} [minZoomLevel=null] * * @property {Number} [maxZoomLevel=null] @@ -1337,6 +1340,7 @@ function OpenSeadragon( options ){ // INITIAL FLIP STATE flipped: false, + overlayContentFlipped: false, // APPEARANCE opacity: 1, diff --git a/src/overlay.js b/src/overlay.js index 6d355c7a..bed6b4c5 100644 --- a/src/overlay.js +++ b/src/overlay.js @@ -129,6 +129,7 @@ } this.element = options.element; + this.element.innerHTML = "
" + this.element.innerHTML + "
"; this.style = options.element.style; this._init(options); }; @@ -242,9 +243,6 @@ */ drawHTML: function(container, viewport) { var element = this.element; - var text = document.createElement('div'); - text.textContent = element.textContent; - element.textContent = ""; if (element.parentNode !== container) { //save the source parent for later if we need it element.prevElementParent = element.parentNode; @@ -257,27 +255,23 @@ // least one direction when this.checkResize is set to false. this.size = $.getElementSize(element); } - var positionAndSize = this._getOverlayPositionAndSize(viewport); - var position = positionAndSize.position; var size = this.size = positionAndSize.size; - var rotate; - var scale = ""; - if (viewport.flipped){ - rotate = -positionAndSize.rotate; - scale = " scaleX(-1)"; - } - else { - rotate = positionAndSize.rotate; + var outerScale = ""; + if (viewport.overlayContentFlipped) { + outerScale = viewport.flipped ? " scaleX(-1)" : " scaleX(1)"; } + var rotate = viewport.flipped ? -positionAndSize.rotate : positionAndSize.rotate; + var scale = viewport.flipped ? " scaleX(-1)" : ""; // call the onDraw callback if it exists to allow one to overwrite // the drawing/positioning/sizing of the overlay if (this.onDraw) { this.onDraw(position, size, this.element); } else { var style = this.style; - var textStyle = text.style; + var outerElement = element.firstChild; + var outerStyle = outerElement.style; style.left = position.x + "px"; style.top = position.y + "px"; if (this.width !== null) { @@ -292,23 +286,24 @@ 'transform'); if (transformOriginProp && transformProp) { if (rotate && !viewport.flipped) { + outerStyle[transformProp] = ""; style[transformOriginProp] = this._getTransformOrigin(); style[transformProp] = "rotate(" + rotate + "deg)"; } else if (!rotate && viewport.flipped) { - textStyle[transformProp] = "scaleX(-1)"; + outerStyle[transformProp] = outerScale; style[transformOriginProp] = this._getTransformOrigin(); style[transformProp] = scale; } else if (rotate && viewport.flipped){ - textStyle[transformProp] = "scaleX(-1)"; + outerStyle[transformProp] = outerScale; style[transformOriginProp] = this._getTransformOrigin(); style[transformProp] = "rotate(" + rotate + "deg)" + scale; } else { + outerStyle[transformProp] = ""; style[transformOriginProp] = ""; style[transformProp] = ""; } } style.display = 'block'; - element.appendChild(text); } }, diff --git a/src/viewer.js b/src/viewer.js index d82a2d77..b918fab3 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -397,6 +397,7 @@ $.Viewer = function( options ) { viewer: this, degrees: this.degrees, flipped: this.flipped, + overlayContentFlipped: this.overlayContentFlipped, navigatorRotate: this.navigatorRotate, homeFillsViewer: this.homeFillsViewer, margins: this.viewportMargins, diff --git a/test/demo/overlay.html b/test/demo/overlay.html index 527ebef3..bf5e3548 100644 --- a/test/demo/overlay.html +++ b/test/demo/overlay.html @@ -26,7 +26,8 @@ prefixUrl: "../../build/openseadragon/images/", tileSources: "../data/testpattern.dzi", minZoomImageRatio: 0, - maxZoomPixelRatio: 10 + maxZoomPixelRatio: 10, + overlayContentFlipped: true // change this to true to test overlay content flipping }); viewer.addHandler("open", function(event) { @@ -42,6 +43,19 @@ rotationMode: OpenSeadragon.OverlayRotationMode.BOUNDING_BOX }); + // test with image of letter B to see that images flip too + elt = document.createElement("div"); + elt.className = "runtime-overlay"; + elt.style.outline = "1px solid blue"; + elt.style.height = "100px"; + elt.innerHTML = "
" + viewer.addOverlay({ + element: elt, + location: new OpenSeadragon.Point(0.0, 0.0), + width: 0.1, + height: 0.1 + }); + elt = document.createElement("div"); elt.className = "runtime-overlay"; elt.style.background = "white"; From 2c5d2eb7c6159228a32527d6e9bdbd2876fc50c1 Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Fri, 12 Jul 2024 20:36:11 +0100 Subject: [PATCH 7/8] Fixed: More meaning full variable and help text, innerStyle not outer --- src/openseadragon.js | 8 +++++--- src/overlay.js | 12 ++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/openseadragon.js b/src/openseadragon.js index a907d84c..5207de83 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -230,8 +230,10 @@ * @property {Boolean} [flipped=false] * Initial flip state. * - * @property {Boolean} [overlayContentFlipped=false] - * Initial overlay content flip state. + * @property {Boolean} [overlayFlipReversal=true] + * When the viewport is flipped (by pressing 'f'), the overlay is flipped using ScaleX. + * Normally, this setting (default true) keeps the overlay's content readable by flipping it back. + * To make the content flip with the overlay, set overlayFlipReversal to false. * * @property {Number} [minZoomLevel=null] * @@ -1340,7 +1342,7 @@ function OpenSeadragon( options ){ // INITIAL FLIP STATE flipped: false, - overlayContentFlipped: false, + overlayFlipReversal: true, // APPEARANCE opacity: 1, diff --git a/src/overlay.js b/src/overlay.js index bed6b4c5..f555d6b9 100644 --- a/src/overlay.js +++ b/src/overlay.js @@ -270,8 +270,8 @@ this.onDraw(position, size, this.element); } else { var style = this.style; - var outerElement = element.firstChild; - var outerStyle = outerElement.style; + var innerElement = element.firstChild; + var innerStyle = innerElement.style; style.left = position.x + "px"; style.top = position.y + "px"; if (this.width !== null) { @@ -286,19 +286,19 @@ 'transform'); if (transformOriginProp && transformProp) { if (rotate && !viewport.flipped) { - outerStyle[transformProp] = ""; + innerStyle[transformProp] = ""; style[transformOriginProp] = this._getTransformOrigin(); style[transformProp] = "rotate(" + rotate + "deg)"; } else if (!rotate && viewport.flipped) { - outerStyle[transformProp] = outerScale; + innerStyle[transformProp] = outerScale; style[transformOriginProp] = this._getTransformOrigin(); style[transformProp] = scale; } else if (rotate && viewport.flipped){ - outerStyle[transformProp] = outerScale; + innerStyle[transformProp] = outerScale; style[transformOriginProp] = this._getTransformOrigin(); style[transformProp] = "rotate(" + rotate + "deg)" + scale; } else { - outerStyle[transformProp] = ""; + innerStyle[transformProp] = ""; style[transformOriginProp] = ""; style[transformProp] = ""; } From c1c1d480dd9e61c81cf3960ed166a78faf2325b2 Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Tue, 16 Jul 2024 08:38:39 +0100 Subject: [PATCH 8/8] Fixed: Try renaming to something more descriptive --- src/openseadragon.js | 8 ++++---- src/overlay.js | 2 +- src/viewer.js | 38 +++++++++++++++++++------------------- test/demo/overlay.html | 2 +- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/openseadragon.js b/src/openseadragon.js index 5207de83..1510883a 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -230,10 +230,10 @@ * @property {Boolean} [flipped=false] * Initial flip state. * - * @property {Boolean} [overlayFlipReversal=true] + * @property {Boolean} [overlayPreserveContentDirection=true] * When the viewport is flipped (by pressing 'f'), the overlay is flipped using ScaleX. * Normally, this setting (default true) keeps the overlay's content readable by flipping it back. - * To make the content flip with the overlay, set overlayFlipReversal to false. + * To make the content flip with the overlay, set overlayPreserveContentDirection to false. * * @property {Number} [minZoomLevel=null] * @@ -1341,8 +1341,8 @@ function OpenSeadragon( options ){ degrees: 0, // INITIAL FLIP STATE - flipped: false, - overlayFlipReversal: true, + flipped: false, + overlayPreserveContentDirection: true, // APPEARANCE opacity: 1, diff --git a/src/overlay.js b/src/overlay.js index f555d6b9..7d485d42 100644 --- a/src/overlay.js +++ b/src/overlay.js @@ -259,7 +259,7 @@ var position = positionAndSize.position; var size = this.size = positionAndSize.size; var outerScale = ""; - if (viewport.overlayContentFlipped) { + if (viewport.overlayPreserveContentDirection) { outerScale = viewport.flipped ? " scaleX(-1)" : " scaleX(1)"; } var rotate = viewport.flipped ? -positionAndSize.rotate : positionAndSize.rotate; diff --git a/src/viewer.js b/src/viewer.js index b918fab3..97645294 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -383,25 +383,25 @@ $.Viewer = function( options ) { // Create the viewport this.viewport = new $.Viewport({ - containerSize: THIS[ this.hash ].prevContainerSize, - springStiffness: this.springStiffness, - animationTime: this.animationTime, - minZoomImageRatio: this.minZoomImageRatio, - maxZoomPixelRatio: this.maxZoomPixelRatio, - visibilityRatio: this.visibilityRatio, - wrapHorizontal: this.wrapHorizontal, - wrapVertical: this.wrapVertical, - defaultZoomLevel: this.defaultZoomLevel, - minZoomLevel: this.minZoomLevel, - maxZoomLevel: this.maxZoomLevel, - viewer: this, - degrees: this.degrees, - flipped: this.flipped, - overlayContentFlipped: this.overlayContentFlipped, - navigatorRotate: this.navigatorRotate, - homeFillsViewer: this.homeFillsViewer, - margins: this.viewportMargins, - silenceMultiImageWarnings: this.silenceMultiImageWarnings + containerSize: THIS[ this.hash ].prevContainerSize, + springStiffness: this.springStiffness, + animationTime: this.animationTime, + minZoomImageRatio: this.minZoomImageRatio, + maxZoomPixelRatio: this.maxZoomPixelRatio, + visibilityRatio: this.visibilityRatio, + wrapHorizontal: this.wrapHorizontal, + wrapVertical: this.wrapVertical, + defaultZoomLevel: this.defaultZoomLevel, + minZoomLevel: this.minZoomLevel, + maxZoomLevel: this.maxZoomLevel, + viewer: this, + degrees: this.degrees, + flipped: this.flipped, + overlayPreserveContentDirection: this.overlayPreserveContentDirection, + navigatorRotate: this.navigatorRotate, + homeFillsViewer: this.homeFillsViewer, + margins: this.viewportMargins, + silenceMultiImageWarnings: this.silenceMultiImageWarnings }); this.viewport._setContentBounds(this.world.getHomeBounds(), this.world.getContentFactor()); diff --git a/test/demo/overlay.html b/test/demo/overlay.html index bf5e3548..92140f8b 100644 --- a/test/demo/overlay.html +++ b/test/demo/overlay.html @@ -27,7 +27,7 @@ tileSources: "../data/testpattern.dzi", minZoomImageRatio: 0, maxZoomPixelRatio: 10, - overlayContentFlipped: true // change this to true to test overlay content flipping + overlayPreserveContentDirection: true // change this to true to test overlay content flipping }); viewer.addHandler("open", function(event) {