Mercurial > hg > digilib-old
diff client/digitallibrary/jquery/jquery.digilib.birdseye.js @ 800:65e70c03870b stream
merge from juqery branch
12f790cb30de0ac42ff62fb9921d7a3215243b7b
author | robcast |
---|---|
date | Sat, 19 Feb 2011 09:56:18 +0100 |
parents | 12f790cb30de |
children | ae8e98c479d5 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/digitallibrary/jquery/jquery.digilib.birdseye.js Sat Feb 19 09:56:18 2011 +0100 @@ -0,0 +1,323 @@ +/** +digilib bird's eye view plugin + */ + +(function($) { + + // affine geometry plugin stub + var geom; + + var FULL_AREA; + + var buttons = { + bird : { + onclick : "showBirdDiv", + tooltip : "show bird's eye view", + icon : "birds-eye.png" + } + }; + + var defaults = { + // is birdView shown? + 'isBirdDivVisible' : false, + // dimensions of bird's eye div + 'birdDivWidth' : 200, + 'birdDivHeight' : 200, + // parameters used by bird's eye div + 'birdDivParams' : ['fn','pn','dw','dh'] + }; + + var actions = { + // event handler: toggles the visibility of the bird's eye window + showBirdDiv : function (data, show) { + var settings = data.settings; + if (data.$birdDiv == null) { + // no bird div -> create + setupBirdDiv(data); + } + var on = digilib.fn.showDiv(settings.isBirdDivVisible, data.$birdDiv, show); + settings.isBirdDivVisible = on; + digilib.fn.highlightButtons(data, 'bird', on); + updateBirdDiv(data); + digilib.fn.storeOptions(data); + } + }; + + // plugin installation called by digilib on plugin object. + var install = function(digilib) { + // import geometry classes + geom = digilib.fn.geometry; + FULL_AREA = geom.rectangle(0,0,1,1); + // add defaults + $.extend(digilib.defaults, defaults); + // add actions + $.extend(digilib.actions, actions); + // add buttons + $.extend(digilib.buttons, buttons); + // insert in button list -- not elegant + digilib.defaults.buttonSettings.fullscreen.standardSet.splice(9, 0, 'bird'); + digilib.defaults.buttonSettings.embedded.standardSet.splice(5, 0, 'bird'); + }; + + // plugin initialization + var init = function (data) { + var $data = $(data); + // install event handler + $data.bind('setup', handleSetup); + $data.bind('update', handleUpdate); + $data.bind('redisplay', handleRedisplay); + $data.bind('dragZoom', handleDragZoom); + }; + + + var handleSetup = function (evt) { + console.debug("birdseye: handleSetup"); + data = this; + // bird's eye view creation + if (data.settings.isBirdDivVisible) { + setupBirdDiv(data); + data.$birdDiv.show(); + } + }; + + var handleUpdate = function (evt) { + console.debug("birdseye: handleUpdate"); + data = this; + if (data.settings.isBirdDivVisible) { + renderBirdArea(data); + setupBirdDrag(data); + } + }; + + var handleRedisplay = function (evt) { + console.debug("birdseye: handleRedisplay"); + data = this; + if (data.settings.isBirdDivVisible) { + updateBirdDiv(data); + } + }; + + var handleDragZoom = function (evt, zoomArea) { + //console.debug("birdseye: handleDragZoom za="+zoomArea); + data = this; + if (data.settings.isBirdDivVisible) { + setBirdZoom(data, zoomArea); + } + }; + + // returns URL for bird's eye view image + var getBirdImgUrl = function (data) { + var settings = data.settings; + var birdDivOptions = { + dw : settings.birdDivWidth, + dh : settings.birdDivHeight + }; + var birdSettings = $.extend({}, settings, birdDivOptions); + // use only the relevant parameters + var params = digilib.fn.getParamString(birdSettings, settings.birdDivParams, digilib.defaults); + var url = settings.scalerBaseUrl + '?' + params; + return url; + }; + + // creates HTML structure for the bird's eye view in elem + var setupBirdDiv = function (data) { + var $elem = data.$elem; + // the bird's eye div + var $birdDiv = $('<div class="birdview" style="display:none"/>'); + // the detail indicator frame + var $birdZoom = $('<div class="birdzoom" style="display:none; background-color:transparent;"/>'); + // the small image + var $birdImg = $('<img class="birdimg"/>'); + data.$birdDiv = $birdDiv; + data.$birdZoom = $birdZoom; + data.$birdImg = $birdImg; + $elem.append($birdDiv); + $birdDiv.append($birdZoom); + $birdDiv.append($birdImg); + // $birdZoom.css(data.settings.birdIndicatorStyle); + var birdUrl = getBirdImgUrl(data); + $birdImg.load(birdImgLoadedHandler(data)); + $birdImg.error(function () {console.error("error loading birdview image");}); + $birdImg.attr('src', birdUrl); + }; + + // update bird's eye view + var updateBirdDiv = function (data) { + if (!data.settings.isBirdDivVisible) return; + var $birdImg = data.$birdImg; + var oldsrc = $birdImg.attr('src'); + var newsrc = getBirdImgUrl(data); + if (oldsrc !== newsrc) { + $birdImg.attr('src', newsrc); + // onload handler re-renders + } else { + // re-render + renderBirdArea(data); + // enable click and drag + setupBirdDrag(data); + } + }; + + // returns function for load event of bird's eye view img + var birdImgLoadedHandler = function (data) { + return function () { + var $birdImg = $(this); + var birdRect = geom.rectangle($birdImg); + console.debug("birdImg loaded!", $birdImg, "rect=", birdRect, "data=", data); + if (birdRect.width === 0) { + // malheureusement IE7 calls load handler when there is no size info yet + setTimeout(function () { $birdImg.triggerHandler('load'); }, 200); + } + // update display (zoom area indicator) + digilib.fn.updateDisplay(data); + }; + }; + + // show zoom area indicator on bird's eye view + var renderBirdArea = function (data) { + if (data.$birdImg == null || ! data.$birdImg.get(0).complete) return; + var $birdZoom = data.$birdZoom; + var zoomArea = data.zoomArea; + var normalSize = digilib.fn.isFullArea(zoomArea); + if (normalSize) { + $birdZoom.hide(); + return; + } else { + $birdZoom.show(); + } + // create Transform from current area and picsize + data.birdTrafo = digilib.fn.getImgTrafo(data.$birdImg, FULL_AREA); + var zoomRect = data.birdTrafo.transform(zoomArea); + console.debug("renderBirdArea:", zoomRect, "zoomArea:", zoomArea, "$birdTrafo:", data.birdTrafo); + // acount for border width + var bw = digilib.fn.getBorderWidth($birdZoom); + zoomRect.addPosition({x : -bw, y : -bw}); + if (data.settings.interactionMode === 'fullscreen') { + // no animation for fullscreen + zoomRect.adjustDiv($birdZoom); + } else { + // nice animation for embedded mode :-) + // 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 + }; + $birdZoom.animate(dest); + } + }; + + // bird's eye view zoom area click and drag handler + var setupBirdDrag = function(data) { + var $birdImg = data.$birdImg; + var $birdZoom = data.$birdZoom; + var $document = $(document); + var $scaler = data.$scaler; + var startPos, newRect, birdImgRect, birdZoomRect, fullRect, scalerPos; + var bw = digilib.fn.getBorderWidth($birdZoom); + + // mousedown handler: start dragging bird zoom to a new position + var birdZoomStartDrag = function(evt) { + startPos = geom.position(evt); + // position may have changed + data.birdTrafo = digilib.fn.getImgTrafo($birdImg, FULL_AREA); + birdImgRect = geom.rectangle($birdImg); + birdZoomRect = geom.rectangle($birdZoom); + scalerPos = geom.position($scaler); + newRect = null; + fullRect = digilib.fn.setZoomBG(data); // setup zoom background image + $document.bind("mousemove.dlBirdMove", birdZoomMove); + $document.bind("mouseup.dlBirdMove", birdZoomEndDrag); + return false; + }; + + // mousemove handler: drag + var birdZoomMove = function(evt) { + var pos = geom.position(evt); + var delta = startPos.delta(pos); + // move birdZoom div, keeping size + newRect = birdZoomRect.copy(); + newRect.addPosition(delta); + 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" + }); + // acount for border width + newRect.addPosition({x : -bw, y : -bw}); + newRect.adjustDiv($birdZoom); + return false; + }; + + // mouseup handler: reload page + var birdZoomEndDrag = function(evt) { + var settings = data.settings; + $document.unbind("mousemove.dlBirdMove", birdZoomMove); + $document.unbind("mouseup.dlBirdMove", birdZoomEndDrag); + if (newRect == null) { + // no movement happened - set center to click position + startPos = birdZoomRect.getCenter(); + birdZoomMove(evt); + } + // ugly, but needed to prevent double border width compensation + newRect.addPosition({x : bw, y : bw}); + var newArea = data.birdTrafo.invtransform(newRect); + data.zoomArea = newArea; + digilib.fn.redisplay(data); + return false; + }; + + // clear old handler + $document.unbind(".dlBirdMove"); + $birdImg.unbind(".dlBirdMove"); + $birdZoom.unbind(".dlBirdMove"); + if (! digilib.fn.isFullArea(data.zoomArea)) { + // set new handler + $birdImg.bind("mousedown.dlBirdMove", birdZoomStartDrag); + $birdZoom.bind("mousedown.dlBirdMove", birdZoomStartDrag); + } + }; + + // move bird zoom indicator to reflect zoomed detail area + var setBirdZoom = function(data, rect) { + var part = data.imgTrafo.invtransform(rect); + // area = FULL_AREA.fit(part); // no, we want to see where we transcend the borders + birdTrafo = digilib.fn.getImgTrafo(data.$birdImg, FULL_AREA); + var birdRect = birdTrafo.transform(part); + var $birdZoom = data.$birdZoom; + // acount for border width + var bw = digilib.fn.getBorderWidth($birdZoom); + birdRect.addPosition({x : -bw, y : -bw}); + birdRect.adjustDiv(data.$birdZoom); + }; + + // plugin object with name and init + // shared objects filled by digilib on registration + var digilib = { + name : 'birdseye', + install : install, + init : init, + buttons : {}, + actions : {}, + fn : {}, + plugins : {} + }; + + if ($.fn.digilib == null) { + $.error("jquery.digilib.birdview must be loaded after jquery.digilib!"); + } else { + $.fn.digilib('plugin', digilib); + } +})(jQuery);