comparison client/digitallibrary/jquery/jquery.digilib.js @ 668:ad4a2edcbdbc jquery

make zoomarea and birdview work in embedded mode
author hertzhaft
date Mon, 24 Jan 2011 09:48:27 +0100
parents 3de056c96bcf
children b93241aa017c
comparison
equal deleted inserted replaced
667:48e5b9608091 668:ad4a2edcbdbc
181 // fullscreen = take parameters from page URL, keep state in page URL 181 // fullscreen = take parameters from page URL, keep state in page URL
182 // embedded = take parameters from Javascript options, keep state inside object 182 // embedded = take parameters from Javascript options, keep state inside object
183 'interactionMode' : 'fullscreen', 183 'interactionMode' : 'fullscreen',
184 // buttons 184 // buttons
185 'buttons' : buttons, 185 'buttons' : buttons,
186 // defaults for digilib buttons
186 'buttonSettings' : { 187 'buttonSettings' : {
187 // path to button images (must end with a slash)
188 'fullscreen' : { 188 'fullscreen' : {
189 // path to button images (must end with a slash)
189 'imagePath' : 'img/fullscreen/', 190 'imagePath' : 'img/fullscreen/',
190 //'standardSet' : ["reference","zoomin","zoomout","zoomarea","zoomfull","pagewidth","back","fwd","page","bird","SEP","help","reset","options"], 191 //'standardSet' : ["reference","zoomin","zoomout","zoomarea","zoomfull","pagewidth","back","fwd","page","bird","SEP","help","reset","options"],
191 'standardSet' : ["reference","zoomin","zoomout","zoomarea","zoomfull","pagewidth","mark","delmark","hmir","vmir","back","fwd","page","rot","brgt","cont","rgb","quality","size","calibrationx","scale","bird","help","options"], 192 'standardSet' : ["reference","zoomin","zoomout","zoomarea","zoomfull","pagewidth","mark","delmark","hmir","vmir","back","fwd","page","rot","brgt","cont","rgb","quality","size","calibrationx","scale","bird","help","options"],
192 'specialSet' : ["mark","delmark","hmir","vmir","rot","brgt","cont","rgb","quality","size","calibrationx","scale","SEP","options"], 193 'specialSet' : ["mark","delmark","hmir","vmir","rot","brgt","cont","rgb","quality","size","calibrationx","scale","SEP","options"],
193 'customSet' : [] 194 'customSet' : []
200 } 201 }
201 }, 202 },
202 // button groups 203 // button groups
203 // is birdView shown? 204 // is birdView shown?
204 'isBirdDivVisible' : false, 205 'isBirdDivVisible' : false,
205 // dimensions of bird's eye window 206 // dimensions of bird's eye div
206 'birdDivOptions' : {'dw' : 200, 'dh' : 200}, 207 'birdDivOptions' : {'dw' : 200, 'dh' : 200},
207 // style of bird's eye window 208 // style of the zoom area indicator in the bird's eye div
208 'birdIndicatorStyle' : {'border' : '2px solid #ff0000' }, 209 'birdIndicatorStyle' : {'border' : '2px solid #ff0000' },
210 // style of zoom area "rubber band"
211 'zoomrectStyle' : {'border' : '2px solid #ff0000' },
209 // is the "about" window shown? 212 // is the "about" window shown?
210 'isAboutDivVisible' : false 213 'isAboutDivVisible' : false
211 214
212 }; 215 };
213 216
215 var geom = dlGeometry(); 218 var geom = dlGeometry();
216 219
217 var MAX_ZOOMAREA = geom.rectangle(0, 0, 1, 1); 220 var MAX_ZOOMAREA = geom.rectangle(0, 0, 1, 1);
218 221
219 var actions = { 222 var actions = {
220 // init: digilib initialization 223 // init: digilib initialization
221 init : function(options) { 224 init : function(options) {
222 // settings for this digilib instance are merged from defaults and options 225 // settings for this digilib instance are merged from defaults and options
223 var settings = $.extend({}, defaults, options); 226 var settings = $.extend({}, defaults, options);
224 var isFullscreen = settings.interactionMode === 'fullscreen'; 227 var isFullscreen = settings.interactionMode === 'fullscreen';
225 var queryParams = {}; 228 var queryParams = {};
226 if (isFullscreen) { 229 if (isFullscreen) {
227 queryParams = parseQueryParams(); 230 queryParams = parseQueryParams();
228 // check scalerBaseUrl 231 // check scalerBaseUrl
229 if (settings.scalerBaseUrl == null) { 232 if (settings.scalerBaseUrl == null) {
230 // try the host this came from 233 // try the host this came from
231 var h = window.location.host; 234 var h = window.location.host;
232 if (window.location.host) { 235 if (window.location.host) {
233 var url = window.location.href; 236 var url = window.location.href;
234 // assume the page lives in [webapp]/jquery/ 237 // assume the page lives in [webapp]/jquery/
235 var pos = url.indexOf('jquery/'); 238 var pos = url.indexOf('jquery/');
236 if (pos > 0) { 239 if (pos > 0) {
237 settings.scalerBaseUrl = url.substring(0, pos) + 'servlet/Scaler'; 240 settings.scalerBaseUrl = url.substring(0, pos) + 'servlet/Scaler';
238 }
239 } 241 }
240 } 242 }
241 } 243 }
242 return this.each(function() { 244 }
243 var $elem = $(this); 245 return this.each(function() {
244 var data = $elem.data('digilib'); 246 var $elem = $(this);
245 var elemSettings; 247 var data = $elem.data('digilib');
246 // if the plugin hasn't been initialized yet 248 var elemSettings;
247 if (!data) { 249 // if the plugin hasn't been initialized yet
248 // merge query parameters 250 if (!data) {
249 if (isFullscreen) { 251 // merge query parameters
250 elemSettings = $.extend({}, settings, queryParams); 252 if (isFullscreen) {
251 } else { 253 elemSettings = $.extend({}, settings, queryParams);
252 elemSettings = $.extend({}, settings, parseImgParams($elem)); 254 } else {
253 } 255 elemSettings = $.extend({}, settings, parseImgParams($elem));
254 // store $(this) element in the settings
255 data = {
256 $elem : $elem,
257 settings : elemSettings,
258 queryParams : queryParams
259 };
260 // store in data element
261 $elem.data('digilib', data);
262 } 256 }
263 unpackParams(data); 257 // store $(this) element in the settings
264 // create HTML structure 258 data = {
265 setupScalerDiv(data); 259 $elem : $elem,
266 setupButtons(data, 'standardSet'); 260 settings : elemSettings,
267 // bird's eye view creation 261 queryParams : queryParams
268 if (elemSettings.isBirdDivVisible) { 262 };
269 setupBirdDiv(data); 263 // store in data element
270 } 264 $elem.data('digilib', data);
271 // about window creation - TODO: could be deferred? restrict to only one item? 265 }
272 setupAboutDiv(data); 266 unpackParams(data);
273 }); 267 // create HTML structure
274 }, 268 setupScalerDiv(data);
275 269 setupButtons(data, 'standardSet');
276 // destroy: clean up digilib 270 // bird's eye view creation
277 destroy : function(data) { 271 if (elemSettings.isBirdDivVisible) {
278 return this.each(function(){
279 var $elem = $(this);
280 $(window).unbind('.digilib'); // unbind all digilibs(?)
281 data.digilib.remove();
282 $elem.removeData('digilib');
283 });
284 },
285
286 // show or hide the 'about' window
287 showAboutDiv : function(data, show) {
288 data.settings.isAboutDivVisible = showDiv(data.settings.isAboutDivVisible, data.$aboutDiv, show);
289 },
290
291 // event handler: toggles the visibility of the bird's eye window
292 showBirdDiv : function (data, show) {
293 if (data.$birdDiv == null) {
294 // no bird div -> create
295 setupBirdDiv(data); 272 setupBirdDiv(data);
296 } 273 }
297 // TODO: keep bird view visible after reload (parameter, cookie?) 274 // about window creation - TODO: could be deferred? restrict to only one item?
298 data.settings.isBirdDivVisible = showDiv(data.settings.isBirdDivVisible, data.$birdDiv, show); 275 setupAboutDiv(data);
299 }, 276 });
300 277 },
301 // goto given page nr (+/-: relative) 278
302 gotoPage : function (data, pageNr) { 279 // destroy: clean up digilib
303 var settings = data.settings; 280 destroy : function(data) {
304 var oldpn = settings.pn; 281 return this.each(function(){
305 var pn = setNumValue(settings, "pn", pageNr); 282 var $elem = $(this);
306 if (pn == null) return false; // nothing happened 283 $(window).unbind('.digilib'); // unbind all digilibs(?)
307 if (pn < 1) { 284 data.digilib.remove();
308 alert("no such page (page number too low)"); 285 $elem.removeData('digilib');
286 });
287 },
288
289 // show or hide the 'about' window
290 showAboutDiv : function(data, show) {
291 data.settings.isAboutDivVisible = showDiv(data.settings.isAboutDivVisible, data.$aboutDiv, show);
292 },
293
294 // event handler: toggles the visibility of the bird's eye window
295 showBirdDiv : function (data, show) {
296 if (data.$birdDiv == null) {
297 // no bird div -> create
298 setupBirdDiv(data);
299 }
300 // TODO: keep bird view visible after reload (parameter, cookie?)
301 data.settings.isBirdDivVisible = showDiv(data.settings.isBirdDivVisible, data.$birdDiv, show);
302 },
303
304 // goto given page nr (+/-: relative)
305 gotoPage : function (data, pageNr) {
306 var settings = data.settings;
307 var oldpn = settings.pn;
308 var pn = setNumValue(settings, "pn", pageNr);
309 if (pn == null) return false; // nothing happened
310 if (pn < 1) {
311 alert("no such page (page number too low)");
312 settings.pn = oldpn;
313 return false;
314 }
315 if (settings.pt) {
316 if (pn > settings.pt) {
317 alert("no such page (page number too high)");
309 settings.pn = oldpn; 318 settings.pn = oldpn;
310 return false; 319 return false;
311 } 320 }
312 if (settings.pt) { 321 }
313 if (pn > settings.pt) { 322 // reset mk and others(?)
314 alert("no such page (page number too high)"); 323 data.marks = [];
315 settings.pn = oldpn; 324 data.zoomArea = MAX_ZOOMAREA;
316 return false; 325 // then reload
317 } 326 redisplay(data);
318 } 327 },
319 // reset mk and others(?) 328
320 data.marks = []; 329 // zoom by a given factor
321 data.zoomArea = MAX_ZOOMAREA; 330 zoomBy : function (data, factor) {
322 // then reload 331 zoomBy(data, factor);
332 },
333
334 // zoom interactively
335 zoomArea : function (data) {
336 zoomArea(data);
337 },
338
339 // zoom out to full page
340 zoomFull : function (data, mode) {
341 data.zoomArea = MAX_ZOOMAREA;
342 if (mode === 'width') {
343 data.dlOpts.fitwidth = 1;
344 delete data.dlOpts.fitheight;
345 } else if (mode === 'height') {
346 data.dlOpts.fitheight = 1;
347 delete data.dlOpts.fitwidth;
348 } else {
349 delete data.dlOpts.fitwidth;
350 delete data.dlOpts.fitheight;
351 }
352 redisplay(data);
353 },
354
355 // set a mark by clicking (or giving a position)
356 setMark : function (data, mpos) {
357 if (mpos == null) {
358 // interactive
359 setMark(data);
360 } else {
361 // use position
362 data.marks.push(pos);
323 redisplay(data); 363 redisplay(data);
324 }, 364 }
325 365 },
326 // zoom by a given factor 366
327 zoomBy : function (data, factor) { 367 // remove the last mark
328 zoomBy(data, factor); 368 removeMark : function (data) {
329 }, 369 data.marks.pop();
330 370 redisplay(data);
331 // zoom interactively 371 },
332 zoomArea : function (data) { 372
333 zoomArea(data); 373 // mirror the image
334 }, 374 mirror : function (data, mode) {
335 375 var flags = data.scalerFlags;
336 // zoom out to full page 376 if (mode === 'h') {
337 zoomFull : function (data, mode) { 377 if (flags.hmir) {
338 data.zoomArea = MAX_ZOOMAREA; 378 delete flags.hmir;
339 if (mode === 'width') {
340 data.dlOpts.fitwidth = 1;
341 delete data.dlOpts.fitheight;
342 } else if (mode === 'height') {
343 data.dlOpts.fitheight = 1;
344 delete data.dlOpts.fitwidth;
345 } else { 379 } else {
346 delete data.dlOpts.fitwidth; 380 flags.hmir = 1;
347 delete data.dlOpts.fitheight; 381 }
348 } 382 } else {
349 redisplay(data); 383 if (flags.vmir) {
350 }, 384 delete flags.vmir;
351
352 // set a mark by clicking (or giving a position)
353 setMark : function (data, mpos) {
354 if (mpos == null) {
355 // interactive
356 setMark(data);
357 } else { 385 } else {
358 // use position 386 flags.vmir = 1;
359 data.marks.push(pos); 387 }
360 redisplay(data); 388 }
361 } 389 redisplay(data);
362 }, 390 },
363 391
364 // remove the last mark 392 // rotate the image
365 removeMark : function (data) { 393 rotate : function (data, angle) {
366 data.marks.pop(); 394 var rot = data.settings.rot;
367 redisplay(data); 395 if (angle == null) {
368 }, 396 angle = window.prompt("Rotation angle:", rot);
369 397 }
370 // mirror the image 398 data.settings.rot = angle;
371 mirror : function (data, mode) { 399 redisplay(data);
372 var flags = data.scalerFlags; 400 },
373 if (mode === 'h') { 401
374 if (flags.hmir) { 402 // change brightness
375 delete flags.hmir; 403 brightness : function (data, factor) {
376 } else { 404 var brgt = data.settings.brgt;
377 flags.hmir = 1; 405 if (factor == null) {
378 } 406 factor = window.prompt("Brightness (-255..255)", brgt);
379 } else { 407 }
380 if (flags.vmir) { 408 data.settings.brgt = factor;
381 delete flags.vmir; 409 redisplay(data);
382 } else { 410 },
383 flags.vmir = 1; 411
384 } 412 // change contrast
385 } 413 contrast : function (data, factor) {
386 redisplay(data); 414 var cont = data.settings.cont;
387 }, 415 if (factor == null) {
388 416 factor = window.prompt("Contrast (-8, 8)", cont);
389 // rotate the image 417 }
390 rotate : function (data, angle) { 418 data.settings.cont = factor;
391 var rot = data.settings.rot; 419 redisplay(data);
392 if (angle == null) { 420 }
393 angle = window.prompt("Rotation angle:", rot);
394 }
395 data.settings.rot = angle;
396 redisplay(data);
397 },
398
399 // change brightness
400 brightness : function (data, factor) {
401 var brgt = data.settings.brgt;
402 if (factor == null) {
403 factor = window.prompt("Brightness (-255..255)", brgt);
404 }
405 data.settings.brgt = factor;
406 redisplay(data);
407 },
408
409 // change contrast
410 contrast : function (data, factor) {
411 var cont = data.settings.cont;
412 if (factor == null) {
413 factor = window.prompt("Contrast (-8, 8)", cont);
414 }
415 data.settings.cont = factor;
416 redisplay(data);
417 }
418
419
420 }; 421 };
421 422
422 // returns parameters from page url 423 // returns parameters from page url
423 var parseQueryParams = function() { 424 var parseQueryParams = function() {
424 return parseQueryString(window.location.search.slice(1)); 425 return parseQueryString(window.location.search.slice(1));
450 //keys.push(pair[0]); 451 //keys.push(pair[0]);
451 } 452 }
452 } 453 }
453 return params; 454 return params;
454 }; 455 };
455 456
456 // returns a query string from key names from a parameter hash (ignoring if the same value is in defaults) 457 // returns a query string from key names from a parameter hash (ignoring if the same value is in defaults)
457 var getParamString = function (settings, keys, defaults) { 458 var getParamString = function (settings, keys, defaults) {
458 var paramString = ''; 459 var paramString = '';
459 var nx = false; 460 var nx = false;
460 for (i = 0; i < keys.length; ++i) { 461 for (i = 0; i < keys.length; ++i) {
608 window.location = url; 609 window.location = url;
609 } else { 610 } else {
610 // embedded mode -- just change img src 611 // embedded mode -- just change img src
611 var url = getScalerUrl(data); 612 var url = getScalerUrl(data);
612 data.$img.attr('src', url); 613 data.$img.attr('src', url);
614 // TODO: doesn't work yet
615 var $birdImg = data.$birdImg;
616 if ($birdImg) {
617 $birdImg.triggerHandler('load');
618 };
613 } 619 }
614 }; 620 };
615 621
616 // returns maximum size for scaler img in fullscreen mode 622 // returns maximum size for scaler img in fullscreen mode
617 var getFullscreenImgSize = function($elem) { 623 var getFullscreenImgSize = function($elem) {
828 834
829 // returns function for load event of bird's eye view img 835 // returns function for load event of bird's eye view img
830 var birdImgLoadedHandler = function (data) { 836 var birdImgLoadedHandler = function (data) {
831 var $img = data.$birdImg; 837 var $img = data.$birdImg;
832 return function () { 838 return function () {
839 if (!$img) return;
833 console.debug("birdimg loaded! this=", this, " data=", data); 840 console.debug("birdimg loaded! this=", this, " data=", data);
834 // create Transform from current area and picsize 841 // create Transform from current area and picsize
835 data.birdTrafo = getImgTrafo($img, MAX_ZOOMAREA); 842 data.birdTrafo = getImgTrafo($img, MAX_ZOOMAREA);
836 // display marks 843 // display red indicator around zoomarea
837 renderBirdArea(data); 844 renderBirdArea(data);
838 }; 845 };
839 }; 846 };
840 847
841 // place marks on the image 848 // place marks on the image
898 data.marks.push(pos); 905 data.marks.push(pos);
899 redisplay(data); 906 redisplay(data);
900 return false; // do we even get here? 907 return false; // do we even get here?
901 }); 908 });
902 }; 909 };
903 910
904 var zoomArea = function(data) { 911 var zoomArea = function(data) {
905 $elem = data.$elem; 912 $elem = data.$elem;
906 $scaler = data.$scaler; 913 $scaler = data.$scaler;
907 var pt1, pt2; 914 var pt1, pt2;
908 var $zoomDiv = $('<div class="zoomrect" style="display:none"/>'); 915 var $zoomDiv = $('<div class="zoomrect" style="display:none"/>');
909 $elem.append($zoomDiv); 916 $elem.append($zoomDiv);
917 $zoomDiv.css(data.settings.zoomrectStyle);
910 //var overlay = getElement("overlay"); 918 //var overlay = getElement("overlay");
911 // use overlay div to avoid <img> mousemove problems 919 // use overlay div to avoid <img> mousemove problems
912 var picRect = geom.rectangle($scaler); 920 var picRect = geom.rectangle($scaler);
913 // FIX ME: is there a way to query the border width from CSS info? 921 // FIX ME: is there a way to query the border width from CSS info?
914 // rect.x -= 2; // account for overlay borders 922 // rect.x -= 2; // account for overlay borders
922 var zoomStart = function (evt) { 930 var zoomStart = function (evt) {
923 pt1 = geom.position(evt); 931 pt1 = geom.position(evt);
924 // setup and show zoom div 932 // setup and show zoom div
925 //moveElement(zoomdiv, Rectangle(pt1.x, pt1.y, 0, 0)); 933 //moveElement(zoomdiv, Rectangle(pt1.x, pt1.y, 0, 0));
926 $zoomDiv.offset({left : pt1.x, top : pt1.y}); 934 $zoomDiv.offset({left : pt1.x, top : pt1.y});
935 $zoomDiv.width(0).height(0);
927 $zoomDiv.show(); 936 $zoomDiv.show();
928 // register events 937 // register events
929 $elem.bind("mousemove.digilib", zoomMove); 938 $elem.bind("mousemove.digilib", zoomMove);
930 $elem.bind("mouseup.digilib", zoomEnd); 939 $elem.bind("mouseup.digilib", zoomEnd);
931 return false; 940 return false;
932 }; 941 };
933 942
934 // mouseup handler: end moving 943 // mouseup handler: end moving
935 var zoomEnd = function (evt) { 944 var zoomEnd = function (evt) {
936 pt2 = geom.position(evt); 945 pt2 = geom.position(evt);
937 // assume a click and continue if the area is too small 946 // assume a click and continue if the area is too small
938 var clickRect = geom.rectangle(pt1, pt2); 947 var clickRect = geom.rectangle(pt1, pt2);
953 // zoomed is always fit 962 // zoomed is always fit
954 data.settings.ws = 1; 963 data.settings.ws = 1;
955 redisplay(data); 964 redisplay(data);
956 return false; 965 return false;
957 }; 966 };
958 967
959 // mouse move handler 968 // mouse move handler
960 var zoomMove = function (evt) { 969 var zoomMove = function (evt) {
961 pt2 = geom.position(evt); 970 pt2 = geom.position(evt);
962 var rect = geom.rectangle(pt1, pt2); 971 var rect = geom.rectangle(pt1, pt2);
963 rect.normalize(); 972 rect.normalize();
965 // update zoom div 974 // update zoom div
966 $zoomDiv.offset({left : rect.x, top : rect.y}); 975 $zoomDiv.offset({left : rect.x, top : rect.y});
967 $zoomDiv.width(rect.width).height(rect.height); 976 $zoomDiv.width(rect.width).height(rect.height);
968 return false; 977 return false;
969 }; 978 };
970 979
971 // bind start zoom handler 980 // bind start zoom handler
972 $scaler.one('mousedown.digilib', zoomStart); 981 $scaler.one('mousedown.digilib', zoomStart);
973 }; 982 };
974 983
975 // sets a key to a value (relative values with +/- if relative=true) 984 // sets a key to a value (relative values with +/- if relative=true)