diff --git a/src/openseadragon.js b/src/openseadragon.js index 33ccf20c..ce95b5a5 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -240,6 +240,11 @@ * @property {Boolean} [flipped=false] * 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} [maxZoomLevel=null] @@ -1356,7 +1361,8 @@ function OpenSeadragon( options ){ degrees: 0, // INITIAL FLIP STATE - flipped: false, + flipped: false, + overlayPreserveContentDirection: true, // APPEARANCE opacity: 1, // to be passed into each TiledImage diff --git a/src/overlay.js b/src/overlay.js index 7dec6a6b..7d485d42 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); }; @@ -254,19 +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 = 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 // the drawing/positioning/sizing of the overlay if (this.onDraw) { this.onDraw(position, size, this.element); } else { var style = this.style; + var innerElement = element.firstChild; + var innerStyle = innerElement.style; style.left = position.x + "px"; style.top = position.y + "px"; if (this.width !== null) { @@ -280,10 +285,20 @@ var transformProp = $.getCssPropertyWithVendorPrefix( 'transform'); if (transformOriginProp && transformProp) { - if (rotate) { + if (rotate && !viewport.flipped) { + innerStyle[transformProp] = ""; style[transformOriginProp] = this._getTransformOrigin(); 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 { + innerStyle[transformProp] = ""; style[transformOriginProp] = ""; style[transformProp] = ""; } @@ -314,6 +329,9 @@ } } + if (viewport.flipped) { + position.x = (viewport.getContainerSize().x - position.x); + } return { position: position, size: size, diff --git a/src/viewer.js b/src/viewer.js index 9da4cd9f..a5ad1921 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -399,24 +399,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, - 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 43c0f804..790b04d1 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, + overlayPreserveContentDirection: 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";