# HG changeset patch # User robcast # Date 1325106258 -3600 # Node ID 3916303b8f1727870278d66685a0ae9b32a1d2e1 # Parent 79cbc4694b14ccbe4c746e7485558e62fcf967c3 "preview" works now also for zoomIn/Out diff -r 79cbc4694b14 -r 3916303b8f17 webapp/src/main/webapp/jquery/jquery.digilib.birdseye.js --- a/webapp/src/main/webapp/jquery/jquery.digilib.birdseye.js Wed Dec 28 11:47:18 2011 +0100 +++ b/webapp/src/main/webapp/jquery/jquery.digilib.birdseye.js Wed Dec 28 22:04:18 2011 +0100 @@ -14,9 +14,9 @@ var buttons = { bird : { - onclick : "showBirdDiv", - tooltip : "show bird's eye view", - icon : "birds-eye.png" + 'onclick' : "showBirdDiv", + 'tooltip' : "show bird's eye view", + 'icon' : "birds-eye.png" } }; @@ -206,10 +206,10 @@ // correct offsetParent because animate doesn't use offset var ppos = $birdZoom.offsetParent().offset(); var dest = { - left : (zoomRect.x - ppos.left) + 'px', - top : (zoomRect.y - ppos.top) + 'px', - width : zoomRect.width, - height : zoomRect.height + 'left' : (zoomRect.x - ppos.left) + 'px', + 'top' : (zoomRect.y - ppos.top) + 'px', + 'width' : zoomRect.width, + 'height' : zoomRect.height }; $birdZoom.animate(dest); } @@ -221,7 +221,7 @@ var $birdZoom = data.$birdZoom; var $document = $(document); var $scaler = data.$scaler; - var startPos, newRect, birdImgRect, birdZoomRect, fullRect, scalerPos; + var startPos, newRect, birdImgRect, birdZoomRect; var bw = digilib.fn.getBorderWidth($birdZoom); // mousedown handler: start dragging bird zoom to a new position @@ -231,10 +231,8 @@ data.birdTrafo = digilib.fn.getImgTrafo($birdImg, FULL_AREA); birdImgRect = geom.rectangle($birdImg); birdZoomRect = geom.rectangle($birdZoom); - scalerPos = geom.position($scaler); newRect = null; data.$elem.find(".overlay").hide(); // hide all overlays (marks/regions) - fullRect = digilib.fn.setZoomBg(data); // setup zoom background image $document.on("mousemove.dlBirdMove", birdZoomMove); $document.on("mouseup.dlBirdMove", birdZoomEndDrag); return false; @@ -250,18 +248,7 @@ newRect.stayInside(birdImgRect); // reflect birdview zoom position in scaler image var area = data.birdTrafo.invtransform(newRect); - var imgArea = data.imgTrafo.transform(area); - var offset = imgArea.getPosition().neg(); - offset.add(scalerPos); - if (fullRect) { - var bgPos = fullRect.getPosition().add(offset); - } else { - var bgPos = offset; - } - // move the background image to the new position - data.$scaler.css({ - 'background-position' : bgPos.x + "px " + bgPos.y + "px" - }); + $(data).trigger('changeZoomArea', area); // acount for border width newRect.addPosition({x : -bw, y : -bw}); newRect.adjustDiv($birdZoom); diff -r 79cbc4694b14 -r 3916303b8f17 webapp/src/main/webapp/jquery/jquery.digilib.geometry.js --- a/webapp/src/main/webapp/jquery/jquery.digilib.geometry.js Wed Dec 28 11:47:18 2011 +0100 +++ b/webapp/src/main/webapp/jquery/jquery.digilib.geometry.js Wed Dec 28 22:04:18 2011 +0100 @@ -87,7 +87,7 @@ y : other.y - this.y }); }; - // adjusts position $elem to this position + // adjusts CSS position of $elem to this position that.adjustDiv = function($elem) { $elem.offset({ left : this.x, @@ -210,11 +210,16 @@ this.y = pos.y - this.height / 2; return this; }; - // returns true if both rectangles have equal position and proportion + // returns true if both rectangles have equal position and size that.equals = function(other) { var eq = (this.x === other.x && this.y === other.y && this.width === other.width); return eq; }; + // returns a rectangle with the difference width, height and position + that.delta = function(other) { + return rectangle(other.x - this.x, other.y - this.y, + other.width - this.width, other.height - this.height); + }; // returns the area of this Rectangle that.getArea = function() { return (this.width * this.height); diff -r 79cbc4694b14 -r 3916303b8f17 webapp/src/main/webapp/jquery/jquery.digilib.js --- a/webapp/src/main/webapp/jquery/jquery.digilib.js Wed Dec 28 11:47:18 2011 +0100 +++ b/webapp/src/main/webapp/jquery/jquery.digilib.js Wed Dec 28 22:04:18 2011 +0100 @@ -285,8 +285,10 @@ var fn; // affine geometry plugin stub var geom; - + // rectangle with maximum zoom area var FULL_AREA; + // limit for float comparison + var EPSILON = 0.000001; var actions = { // init: digilib initialization @@ -349,8 +351,6 @@ settings : elemSettings, // and of the URL query parameters queryParams : params, - // TODO: move plugins reference out of data - plugins : plugins }; // store in jQuery data element $elem.data('digilib', data); @@ -364,6 +364,7 @@ break; } } + data.hasPreviewBg = false; // check if browser supports AJAX-like URL-replace without reload data.hasAsyncReload = (typeof history.replaceState === 'function'); // check digilib base URL @@ -500,18 +501,15 @@ // move zoomed area moveZoomArea : function (data, dx, dy) { - var fullBgRect = setZoomBg(data); - var za = data.zoomArea; + var za = data.zoomArea.copy(); var factor = data.settings.zoomArrowMoveFactor; var deltaX = dx * factor * za.width; var deltaY = dy * factor * za.height; var delta = geom.position(deltaX, deltaY); za.addPosition(delta); - data.zoomArea = FULL_AREA.fit(za); + za = FULL_AREA.fit(za); $(data).trigger('changeZoomArea', za); - // TODO: improve this calculation - var deltapix = geom.position(-dx*factor*data.imgRect.width,-dy*factor*data.imgRect.height); - moveZoomBg(data, fullBgRect, deltapix); + data.zoomArea = za; redisplay(data); }, @@ -980,7 +978,7 @@ } highlightButtons(data); // TODO: better solution // invalidate background - data.hasPreviewBg = null; + data.hasPreviewBg = false; // send event $(data).trigger('redisplay'); } catch (e) { @@ -1007,7 +1005,7 @@ } highlightButtons(data); // TODO: better solution // invalidate background - data.hasPreviewBg = null; + data.hasPreviewBg = false; // send event $(data).trigger('redisplay'); } @@ -1499,16 +1497,27 @@ var handleChangeZoomArea = function (evt, newZa) { console.debug("handleChangeZoomArea:", newZa); var data = this; - if (data.hasPreviewBg == null) { - // no background yet - setZoomBg(data); - } else { + var delta = data.zoomArea.delta(newZa); + if (Math.abs(delta.width) > EPSILON || Math.abs(delta.height) > EPSILON) { + // zoom changed -- set new background + console.debug("zoom level changed!"); + var dw = data.zoomArea.width / newZa.width; + var dh = data.zoomArea.height / newZa.height; + var deltapix = geom.size(dw, dh); + setZoomBg(data, deltapix); + } else if (Math.abs(delta.x) > EPSILON || Math.abs(delta.y) > EPSILON) { // move background - // TODO: improve this calculation - var deltapix = geom.position(-dx*factor*data.imgRect.width,-dy*factor*data.imgRect.height); - moveZoomBg(data, fullBgRect, deltapix); + console.debug("zoom area moved:", delta); + var opx = data.imgTrafo.transform(data.zoomArea.getPosition()); + var npx = data.imgTrafo.transform(newZa.getPosition()); + var deltapix = npx.delta(opx); + if (data.hasPreviewBg) { + moveZoomBg(data, deltapix); + } else { + // no background yet + setZoomBg(data, deltapix); + } } - }; @@ -1546,6 +1555,7 @@ newarea.x -= 0.5 * (newarea.width - area.width); newarea.y -= 0.5 * (newarea.height - area.height); newarea = FULL_AREA.fit(newarea); + $(data).trigger('changeZoomArea', newarea); data.zoomArea = newarea; redisplay(data); }; @@ -1634,7 +1644,7 @@ }; // set zoom background (returns rectangle with fullsize backgroud coordinates) - var setZoomBg = function(data) { + var setZoomBg = function(data, delta) { var $scaler = data.$scaler; var $img = data.$img; var fullRect = null; @@ -1649,6 +1659,17 @@ 'cursor' : 'move' }; if (data.hasBgSize) { + if (delta != null && delta.width != null) { + // scale background by delta + var nw = Math.round(data.imgRect.width * delta.width); + var nh = Math.round(data.imgRect.height * delta.height); + scalerCss[data.bgSizeName] = nw + 'px ' + nh + 'px'; + // correct offset + scalerCss['background-position'] = Math.round((data.imgRect.width - nw) / 2) + 'px ' + + Math.round((data.imgRect.height - nh) / 2) + 'px'; + } else { + scalerCss[data.bgSizeName] = 'auto'; + } // additional full-size background using CSS3-background-size fullRect = data.imgTrafo.transform(FULL_AREA); if (fullRect.height < data.settings.maxBgSize && fullRect.width < data.settings.maxBgSize) { @@ -1658,8 +1679,19 @@ var url = getBgImgUrl(data); // add second background url, size and position (CSS3) scalerCss['background-image'] += ', url(' + url + ')'; - scalerCss[data.bgSizeName] = 'auto, ' + fullRect.width + 'px ' + fullRect.height + 'px'; - scalerCss['background-position'] += ', ' + fullRect.x + 'px '+ fullRect.y + 'px'; + if (delta != null && delta.width != null) { + // scale second background by delta + var nw = Math.round(fullRect.width * delta.width); + var nh = Math.round(fullRect.height * delta.height); + scalerCss[data.bgSizeName] += ', ' + nw + 'px ' + nh + 'px'; + // and correct position + var nx = Math.round(fullRect.x + (fullRect.width - nw) / 2); + var ny = Math.round(fullRect.y + (fullRect.height - nh) / 2); + scalerCss['background-position'] += ', ' + nx + 'px '+ ny + 'px'; + } else { + scalerCss[data.bgSizeName] += ', ' + fullRect.width + 'px ' + fullRect.height + 'px'; + scalerCss['background-position'] += ', ' + fullRect.x + 'px '+ fullRect.y + 'px'; + } } else { // scaled full-size background image too big fullRect = null; @@ -1668,6 +1700,9 @@ $scaler.css(scalerCss); data.hasPreviewBg = true; data.fullBgRect = fullRect; + if (delta != null && delta.x != null) { + moveZoomBg(data, delta); + } return fullRect; }; @@ -1677,7 +1712,7 @@ var bgPos = delta.x + "px " + delta.y + "px"; if (data.fullBgRect != null) { // add full-size background position - var bp = fullRect.getPosition().add(delta); + var bp = data.fullBgRect.getPosition().add(delta); bgPos += ', ' + bp.x + "px " + bp.y + "px"; } // move the background image to the new position @@ -1695,6 +1730,8 @@ // drag the image and load a new detail on mouse up var dragStart = function (evt) { + // cancel if not left-click + if (evt.which != 1) return; console.debug("dragstart at=", evt); // don't start dragging if not zoomed if (isFullArea(data.zoomArea)) return false; @@ -1730,7 +1767,7 @@ // no movement $img.css('visibility', 'visible'); $scaler.css({'opacity' : '1', 'background-image' : 'none'}); - data.hasPreviewBg = null; + data.hasPreviewBg = false; // unhide marks data.$elem.find('div.mark').show(); $(data).trigger('redisplay');