diff --git a/src/drawer.js b/src/drawer.js index 10281190..dad5c617 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -144,7 +144,7 @@ $.Drawer = function( options ) { for( i = 0; i < this.overlays.length; i++ ){ if( $.isPlainObject( this.overlays[ i ] ) ){ - this.overlays[ i ] = addOverlayFromConfiguration( this, this.overlays[ i ]); + this.overlays[ i ] = addOverlayFromConfiguration( this, this.overlays[ i ], this.source.dimensions); } else if ( $.isFunction( this.overlays[ i ] ) ){ //TODO @@ -168,8 +168,12 @@ $.Drawer.prototype = { * @param {OpenSeadragon.OverlayPlacement} placement - The position of the * viewport which the location coordinates will be treated as relative * to. + * @param {function} onDraw - A callback that is called when the overlay + * needs to be drawn. It is passed position, size and element. + * @param {boolean} useTransform - Overlay will be scaled and moved using + * the SVG transform argument. Overlay should be a SVG g element. */ - addOverlay: function( element, location, placement ) { + addOverlay: function( element, location, placement, onDraw, useTransform ) { element = $.getElement( element ); if ( getOverlayIndex( this.overlays, element ) >= 0 ) { @@ -177,7 +181,14 @@ $.Drawer.prototype = { return; } - this.overlays.push( new $.Overlay( element, location, placement ) ); + this.overlays.push( new $.Overlay({ + element: element, + location: location, + placement: placement, + onDraw: onDraw, + useTransform: useTransform, + imageFullSize: this.source.dimensions + }) ); this.updateAgain = true; if( this.viewer ){ this.viewer.raiseEvent( 'add-overlay', { @@ -390,7 +401,7 @@ $.Drawer.prototype = { * @private * @inner */ - function addOverlayFromConfiguration( drawer, overlay ){ + function addOverlayFromConfiguration( drawer, overlay, dimensions ){ var element = null, rect = ( overlay.height && overlay.width ) ? new $.Rect( @@ -423,17 +434,24 @@ $.Drawer.prototype = { //we need to translate to viewport coordinates rect = drawer.viewport.imageToViewportRectangle( rect ); } + if( overlay.placement ){ - return new $.Overlay( - element, - drawer.viewport.pointFromPixel(rect), - $.OverlayPlacement[overlay.placement.toUpperCase()] - ); + return new $.Overlay({ + element: element, + location: drawer.viewport.pointFromPixel(rect), + placement: $.OverlayPlacement[overlay.placement.toUpperCase()], + onDraw: overlay.onDraw, + useTransform: overlay.useTransform, + imageFullSize: dimensions + }); }else{ - var newOverlay = new $.Overlay(element, rect); - if (overlay.zoomHandler) - newOverlay.zoomHandler = overlay.zoomHandler; - return newOverlay; + return new $.Overlay({ + element: element, + location: rect, + onDraw: overlay.onDraw, + useTransform: overlay.useTransform, + imageFullSize: dimensions + }); } } diff --git a/src/overlay.js b/src/overlay.js index acee3316..a4ae2f9e 100644 --- a/src/overlay.js +++ b/src/overlay.js @@ -57,27 +57,42 @@ * @class */ $.Overlay = function( element, location, placement ) { - this.element = element; - this.scales = location instanceof $.Rect; + + var options; + if( $.isPlainObject( element ) ){ + options = element; + } else{ + options = { + element: element, + location: location, + placement: placement + }; + } + + this.element = options.element; + this.scales = options.location instanceof $.Rect; this.bounds = new $.Rect( - location.x, - location.y, - location.width, - location.height + options.location.x, + options.location.y, + options.location.width, + options.location.height ); this.position = new $.Point( - location.x, - location.y + options.location.x, + options.location.y ); this.size = new $.Point( - location.width, - location.height + options.location.width, + options.location.height ); - this.style = element.style; + this.style = options.element.style; // rects are always top-left - this.placement = location instanceof $.Point ? - placement : + this.placement = options.location instanceof $.Point ? + options.placement : $.OverlayPlacement.TOP_LEFT; + this.onDraw = options.onDraw; + this.useTransform = options.useTransform; + this.imageFullSize = options.imageFullSize; }; $.Overlay.prototype = { @@ -176,27 +191,35 @@ this.size = $.getElementSize( element ); } - if (this.zoomHandler) { - this.zoomHandler(this.position, this.size, element); - return; - } - position = this.position; size = this.size; this.adjust( position, size ); - position = position.apply( Math.floor ); - size = size.apply( Math.ceil ); + if(this.useTransform){ + var scale = Math.min(this.size.x / this.imageFullSize.x, this.size.y / this.imageFullSize.y); - style.left = position.x + "px"; - style.top = position.y + "px"; - style.position = "absolute"; - style.display = 'block'; + var attrValue = 'translate(' + position.x + ', ' + position.y + ') scale(' + scale + ')'; + // we expect the first element to be the g element of the SVG element that we can transform + element.firstElementChild.setAttribute('transform', attrValue); + }else{ + position = position.apply( Math.floor ); + size = size.apply( Math.ceil ); - if ( scales ) { - style.width = size.x + "px"; - style.height = size.y + "px"; + style.left = position.x + "px"; + style.top = position.y + "px"; + style.position = "absolute"; + style.display = 'block'; + + if ( scales ) { + style.width = size.x + "px"; + style.height = size.y + "px"; + } + } + + // call the onDraw callback if there is one to allow them to dping + if (this.onDraw) { + this.onDraw(this.position, this.size, element); } },