changeset 944:3916303b8f17

"preview" works now also for zoomIn/Out
author robcast
date Wed, 28 Dec 2011 22:04:18 +0100
parents 79cbc4694b14
children d90eb52966be
files webapp/src/main/webapp/jquery/jquery.digilib.birdseye.js webapp/src/main/webapp/jquery/jquery.digilib.geometry.js webapp/src/main/webapp/jquery/jquery.digilib.js
diffstat 3 files changed, 77 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- 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);
--- 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);
--- 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');