Merge pull request #2546 from BeebBenjamin/flip-overlay

Fixed: Invert overlay scale and rotate on flip
This commit is contained in:
Ian Gilman 2024-07-16 09:30:02 -07:00 committed by GitHub
commit 819d4cb20c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 64 additions and 25 deletions

View File

@ -240,6 +240,11 @@
* @property {Boolean} [flipped=false] * @property {Boolean} [flipped=false]
* Initial flip state. * Initial flip state.
* *
* @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 overlayPreserveContentDirection to false.
*
* @property {Number} [minZoomLevel=null] * @property {Number} [minZoomLevel=null]
* *
* @property {Number} [maxZoomLevel=null] * @property {Number} [maxZoomLevel=null]
@ -1356,7 +1361,8 @@ function OpenSeadragon( options ){
degrees: 0, degrees: 0,
// INITIAL FLIP STATE // INITIAL FLIP STATE
flipped: false, flipped: false,
overlayPreserveContentDirection: true,
// APPEARANCE // APPEARANCE
opacity: 1, // to be passed into each TiledImage opacity: 1, // to be passed into each TiledImage

View File

@ -129,6 +129,7 @@
} }
this.element = options.element; this.element = options.element;
this.element.innerHTML = "<div>" + this.element.innerHTML + "</div>";
this.style = options.element.style; this.style = options.element.style;
this._init(options); this._init(options);
}; };
@ -254,19 +255,23 @@
// least one direction when this.checkResize is set to false. // least one direction when this.checkResize is set to false.
this.size = $.getElementSize(element); this.size = $.getElementSize(element);
} }
var positionAndSize = this._getOverlayPositionAndSize(viewport); var positionAndSize = this._getOverlayPositionAndSize(viewport);
var position = positionAndSize.position; var position = positionAndSize.position;
var size = this.size = positionAndSize.size; var size = this.size = positionAndSize.size;
var rotate = positionAndSize.rotate; var outerScale = "";
if (viewport.overlayPreserveContentDirection) {
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 // call the onDraw callback if it exists to allow one to overwrite
// the drawing/positioning/sizing of the overlay // the drawing/positioning/sizing of the overlay
if (this.onDraw) { if (this.onDraw) {
this.onDraw(position, size, this.element); this.onDraw(position, size, this.element);
} else { } else {
var style = this.style; var style = this.style;
var innerElement = element.firstChild;
var innerStyle = innerElement.style;
style.left = position.x + "px"; style.left = position.x + "px";
style.top = position.y + "px"; style.top = position.y + "px";
if (this.width !== null) { if (this.width !== null) {
@ -280,10 +285,20 @@
var transformProp = $.getCssPropertyWithVendorPrefix( var transformProp = $.getCssPropertyWithVendorPrefix(
'transform'); 'transform');
if (transformOriginProp && transformProp) { if (transformOriginProp && transformProp) {
if (rotate) { if (rotate && !viewport.flipped) {
innerStyle[transformProp] = "";
style[transformOriginProp] = this._getTransformOrigin(); style[transformOriginProp] = this._getTransformOrigin();
style[transformProp] = "rotate(" + rotate + "deg)"; style[transformProp] = "rotate(" + rotate + "deg)";
} else if (!rotate && viewport.flipped) {
innerStyle[transformProp] = outerScale;
style[transformOriginProp] = this._getTransformOrigin();
style[transformProp] = scale;
} else if (rotate && viewport.flipped){
innerStyle[transformProp] = outerScale;
style[transformOriginProp] = this._getTransformOrigin();
style[transformProp] = "rotate(" + rotate + "deg)" + scale;
} else { } else {
innerStyle[transformProp] = "";
style[transformOriginProp] = ""; style[transformOriginProp] = "";
style[transformProp] = ""; style[transformProp] = "";
} }
@ -314,6 +329,9 @@
} }
} }
if (viewport.flipped) {
position.x = (viewport.getContainerSize().x - position.x);
}
return { return {
position: position, position: position,
size: size, size: size,

View File

@ -399,24 +399,25 @@ $.Viewer = function( options ) {
// Create the viewport // Create the viewport
this.viewport = new $.Viewport({ this.viewport = new $.Viewport({
containerSize: THIS[ this.hash ].prevContainerSize, containerSize: THIS[ this.hash ].prevContainerSize,
springStiffness: this.springStiffness, springStiffness: this.springStiffness,
animationTime: this.animationTime, animationTime: this.animationTime,
minZoomImageRatio: this.minZoomImageRatio, minZoomImageRatio: this.minZoomImageRatio,
maxZoomPixelRatio: this.maxZoomPixelRatio, maxZoomPixelRatio: this.maxZoomPixelRatio,
visibilityRatio: this.visibilityRatio, visibilityRatio: this.visibilityRatio,
wrapHorizontal: this.wrapHorizontal, wrapHorizontal: this.wrapHorizontal,
wrapVertical: this.wrapVertical, wrapVertical: this.wrapVertical,
defaultZoomLevel: this.defaultZoomLevel, defaultZoomLevel: this.defaultZoomLevel,
minZoomLevel: this.minZoomLevel, minZoomLevel: this.minZoomLevel,
maxZoomLevel: this.maxZoomLevel, maxZoomLevel: this.maxZoomLevel,
viewer: this, viewer: this,
degrees: this.degrees, degrees: this.degrees,
flipped: this.flipped, flipped: this.flipped,
navigatorRotate: this.navigatorRotate, overlayPreserveContentDirection: this.overlayPreserveContentDirection,
homeFillsViewer: this.homeFillsViewer, navigatorRotate: this.navigatorRotate,
margins: this.viewportMargins, homeFillsViewer: this.homeFillsViewer,
silenceMultiImageWarnings: this.silenceMultiImageWarnings margins: this.viewportMargins,
silenceMultiImageWarnings: this.silenceMultiImageWarnings
}); });
this.viewport._setContentBounds(this.world.getHomeBounds(), this.world.getContentFactor()); this.viewport._setContentBounds(this.world.getHomeBounds(), this.world.getContentFactor());

View File

@ -26,7 +26,8 @@
prefixUrl: "../../build/openseadragon/images/", prefixUrl: "../../build/openseadragon/images/",
tileSources: "../data/testpattern.dzi", tileSources: "../data/testpattern.dzi",
minZoomImageRatio: 0, minZoomImageRatio: 0,
maxZoomPixelRatio: 10 maxZoomPixelRatio: 10,
overlayPreserveContentDirection: true // change this to true to test overlay content flipping
}); });
viewer.addHandler("open", function(event) { viewer.addHandler("open", function(event) {
@ -42,6 +43,19 @@
rotationMode: OpenSeadragon.OverlayRotationMode.BOUNDING_BOX 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 = "<div><img src='../data/BBlue.png' width='100%' height='100%'/></div>"
viewer.addOverlay({
element: elt,
location: new OpenSeadragon.Point(0.0, 0.0),
width: 0.1,
height: 0.1
});
elt = document.createElement("div"); elt = document.createElement("div");
elt.className = "runtime-overlay"; elt.className = "runtime-overlay";
elt.style.background = "white"; elt.style.background = "white";