1
|
1 /* Copyright (C) 2003,2004 IT-Group MPIWG, WTWG Uni Bern and others
|
|
2
|
|
3 This program is free software; you can redistribute it and/or
|
|
4 modify it under the terms of the GNU General Public License
|
|
5 as published by the Free Software Foundation; either version 2
|
|
6 of the License, or (at your option) any later version.
|
|
7
|
|
8 This program is distributed in the hope that it will be useful,
|
|
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11 GNU General Public License for more details.
|
|
12
|
|
13 You should have received a copy of the GNU General Public License
|
|
14 along with this program; if not, write to the Free Software
|
|
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
16
|
|
17 Authors:
|
|
18 Christian Luginbuehl, 01.05.2003 (first version)
|
|
19 DW 24.03.2004 (Changed for digiLib in Zope)
|
|
20 Robert Casties, 8.11.2005
|
|
21 Martin Raspe <hertzhaft@biblhertz.it>, 12.12.2005
|
|
22 Robert Casties, 4.9.2009
|
|
23
|
|
24 ! Requires baselib.js !
|
|
25 */
|
|
26 digilibVersion = "Digilib NG";
|
|
27 dllibVersion = "2.042";
|
|
28
|
|
29 function identify() {
|
|
30 // used for identifying a digilib instance
|
|
31 // Relato uses that function - lugi
|
|
32 return digilibVersion;
|
|
33 }
|
|
34
|
|
35 function createMarkDiv(index) {
|
|
36 var div = document.createElement("div");
|
|
37 div.className = "mark";
|
|
38 div.id = "mark" + index;
|
|
39 div.innerHTML = index + 1;
|
|
40 document.body.appendChild(div);
|
|
41 return div;
|
|
42 }
|
|
43
|
|
44 function bestPicSize(elem, inset) {
|
|
45 // returns a Size with the best image size for the given element
|
|
46 if (! defined(inset)) {
|
|
47 inset = 0;
|
|
48 // original value was 25
|
|
49 // digilib seems to use the available space better without inset
|
|
50 }
|
|
51 var ws = getWinSize();
|
|
52 var es = getElementPosition(elem);
|
|
53 if (es) {
|
|
54 ws.width = ws.width - es.x - inset;
|
|
55 ws.height = ws.height - es.y - inset;
|
|
56 }
|
|
57 return ws;
|
|
58 }
|
|
59
|
|
60
|
|
61 /****************************************************
|
|
62 * digilib specific classes (must be defined first)
|
|
63 ****************************************************/
|
|
64
|
|
65 /*
|
|
66 * Marks class
|
|
67 */
|
|
68 function Marks() {
|
|
69 return this;
|
|
70 }
|
|
71 // Marks inherits from Array
|
|
72 Marks.prototype = new Array();
|
|
73 Marks.prototype.parse = function(query) {
|
|
74 this.length = 0;
|
|
75 if (query.indexOf(";") >= 0) {
|
|
76 var pa = query.split(";"); // old format with ";"
|
|
77 } else {
|
|
78 var pa = query.split(","); // new format
|
|
79 }
|
|
80 for (var i = 0; i < pa.length ; i++) {
|
|
81 var pos = pa[i].split("/");
|
|
82 if (pos.length > 1) this.push(new Position(pos[0], pos[1]));
|
|
83 }
|
|
84 }
|
|
85 Marks.prototype.getAll = function() {
|
|
86 var ma = new Array();
|
|
87 for (var i = 0; i < this.length; i++) {
|
|
88 ma.push(cropFloat(this[i].x) + "/" + cropFloat(this[i].y));
|
|
89 }
|
|
90 return ma.join(",");
|
|
91 }
|
|
92 Marks.prototype.addEvent = function(evt, digilib) {
|
|
93 // add a mark from a screen event
|
|
94 if (!digilib) digilib = dl;
|
|
95 var pos = digilib.trafo.invtransform(evtPosition(evt));
|
|
96 this.push(pos);
|
|
97 }
|
|
98
|
|
99 /*
|
|
100 * DLParameters -- digilib parameter class
|
|
101 */
|
|
102 function DLParameters() {
|
|
103 // flags for parameter sets
|
|
104 this.PARAM_FILE = 1;
|
|
105 this.PARAM_MODE = 2;
|
|
106 this.PARAM_DIM = 4;
|
|
107 this.PARAM_IMAGE = 8;
|
|
108 this.PARAM_DPI = 16;
|
|
109 this.PARAM_SIZE = 32;
|
|
110 this.PARAM_MARK = 64;
|
|
111 this.PARAM_PAGES = 128;
|
|
112 this.PARAM_CLIENT = 256;
|
|
113 /* request parameters */
|
|
114 with (this) {
|
|
115 // file
|
|
116 define('fn', '', PARAM_FILE);
|
|
117 define('pn', '1', PARAM_FILE);
|
|
118 // mode
|
|
119 define('mo', '', PARAM_MODE);
|
|
120 // relative dimensions of zoomed image
|
|
121 define('wx', '0.0', PARAM_DIM);
|
|
122 define('wy', '0.0', PARAM_DIM);
|
|
123 define('ww', '1.0', PARAM_DIM);
|
|
124 define('wh', '1.0', PARAM_DIM);
|
|
125 // image manipulation
|
|
126 define('brgt', '0.0', PARAM_IMAGE);
|
|
127 define('cont', '0.0', PARAM_IMAGE);
|
|
128 define('rot', '0.0', PARAM_IMAGE);
|
|
129 define('rgba', '', PARAM_IMAGE);
|
|
130 define('rgbm', '', PARAM_IMAGE);
|
|
131 // resolution
|
|
132 define('ddpi', '', PARAM_DPI);
|
|
133 define('ddpix', '', PARAM_DPI);
|
|
134 define('ddpiy', '', PARAM_DPI);
|
|
135 // marks
|
|
136 define('mk', '', PARAM_MARK);
|
|
137 // pages total
|
|
138 define('pt', '0', PARAM_PAGES);
|
|
139 // size
|
|
140 define('ws', '1.0', PARAM_SIZE);
|
|
141 // client side options
|
|
142 define('clop', '', PARAM_CLIENT);
|
|
143 }
|
|
144 return this;
|
|
145 }
|
|
146 DLParameters.prototype = new Parameters();
|
|
147 // move the inherited getAll because we need it later
|
|
148 DLParameters.prototype._getAll = Parameters.prototype.getAll;
|
|
149 DLParameters.prototype.getAll = function(paDetail, moDetail, digilib) {
|
|
150 if (!digilib) digilib = dl;
|
|
151 // get Flags and Marks first
|
|
152 var mo = digilib.flags.getAll(moDetail);
|
|
153 this.set("mo", mo);
|
|
154 var clop = digilib.opts.getAll();
|
|
155 this.set("clop", clop);
|
|
156 var mk = digilib.marks.getAll();
|
|
157 this.set("mk", mk);
|
|
158 var ret = this._getAll(paDetail);
|
|
159 return ret;
|
|
160 }
|
|
161
|
|
162 /*
|
|
163 * DLModes -- digilib flags class
|
|
164 */
|
|
165 function DLFlags() {
|
|
166 // flags for mode sets
|
|
167 this.MODE_QUAL = 1;
|
|
168 this.MODE_SIZE = 2;
|
|
169 this.MODE_MIR = 4;
|
|
170 this.MODE_OTHER = 128;
|
|
171 this.MODE_ALL = 255;
|
|
172 /* mode flags */
|
|
173 with (this) {
|
|
174 define('q0', MODE_QUAL);
|
|
175 define('q1', MODE_QUAL);
|
|
176 define('q2', MODE_QUAL);
|
|
177 define('fit', MODE_SIZE);
|
|
178 define('clip', MODE_SIZE);
|
|
179 define('osize', MODE_SIZE);
|
|
180 define('vmir', MODE_MIR);
|
|
181 define('hmir', MODE_MIR);
|
|
182 }
|
|
183 return this;
|
|
184 }
|
|
185 // inherits from Flags
|
|
186 DLFlags.prototype = new Flags();
|
|
187
|
|
188
|
|
189 /*
|
|
190 * Digilib -- digilib base class
|
|
191 */
|
|
192 function Digilib() {
|
|
193 if (!baseLibVersion) alert("ERROR: baselib.js not loaded!");
|
|
194 /* constants */
|
|
195 this.MAX_AREA = new Rectangle(0.0, 0.0, 1.0, 1.0);
|
|
196 // default inset (for scalerImg relativ to scalerDiv
|
|
197 this.INSET = 40; // because of scrollbars of main window and scaler [Firefox bug?]
|
|
198 // mouse drag area that counts as one click
|
|
199 this.MIN_AREA_SIZE = 3 * 3 + 1;
|
|
200 // standard zoom factor
|
|
201 this.ZOOMFACTOR = Math.sqrt(2);
|
|
202 // bird's eye view dimensions
|
|
203 this.BIRD_MAXX = 200;
|
|
204 this.BIRD_MAXY = 200;
|
|
205 // witdh of arrow bars
|
|
206 this.ARROW_WIDTH = 32;
|
|
207 // width of calibration bar
|
|
208 this.CALIBRATION_WIDTH = 64;
|
|
209 /* variables */
|
|
210 this.fitOnlyWidth = false;
|
|
211 this.fitOnlyHeight = false;
|
|
212 this.trafo = null;
|
|
213 // page elements
|
|
214 this.scalerDiv = null;
|
|
215 this.scalerImg = null;
|
|
216 this.buttons1Div = null;
|
|
217 this.buttons2Div = null;
|
|
218 /* parse parameters */
|
|
219 this.params = new DLParameters();
|
|
220 // put the query parameters (sans "?") in the parameters array
|
|
221 this.params.parse(location.search.slice(1));
|
|
222 // treat special parameters
|
|
223 this.area = this.parseArea();
|
|
224 this.marks = new Marks();
|
|
225 this.marks.parse(this.params.get("mk"));
|
|
226 this.flags = new DLFlags();
|
|
227 this.flags.parse(this.params.get("mo"));
|
|
228 this.opts = new Flags();
|
|
229 this.opts.parse(this.params.get("clop"));
|
|
230 return this;
|
|
231 }
|
|
232 Digilib.prototype.setDLParam = function(e, s, relative) {
|
|
233 // sets parameter based on HTML event
|
|
234 var nam;
|
|
235 var val;
|
|
236 if (s.type && (s.type == "select-one")) {
|
|
237 nam = s.name;
|
|
238 val = s.options[s.selectedIndex].value;
|
|
239 } else if (s.name && s.value) {
|
|
240 nam = s.name;
|
|
241 val = s.value;
|
|
242 }
|
|
243 if (nam && val) {
|
|
244 dl.params.set(nam, val, relative);
|
|
245 display();
|
|
246 } else {
|
|
247 alert("ERROR: unable to process event!");
|
|
248 }
|
|
249 return true;
|
|
250 }
|
|
251 Digilib.prototype.parseArea = function() {
|
|
252 // returns area Rectangle from current parameters
|
|
253 return new Rectangle(
|
|
254 this.params.get("wx"),
|
|
255 this.params.get("wy"),
|
|
256 this.params.get("ww"),
|
|
257 this.params.get("wh"));
|
|
258 }
|
|
259 Digilib.prototype.setParamFromArea = function(rect) {
|
|
260 // sets digilib wx etc. from rect
|
|
261 this.params.set("wx", cropFloat(rect.x));
|
|
262 this.params.set("wy", cropFloat(rect.y));
|
|
263 this.params.set("ww", cropFloat(rect.width));
|
|
264 this.params.set("wh", cropFloat(rect.height));
|
|
265 return true;
|
|
266 }
|
|
267
|
|
268 Digilib.prototype.parseTrafo = function(elem) {
|
|
269 // returns Transform from current dlArea and picsize
|
|
270 var picsize = getElementRect(elem);
|
|
271 var trafo = new Transform();
|
|
272 // subtract area offset and size
|
|
273 trafo.concat(trafo.getTranslation(new Position(-this.area.x, -this.area.y)));
|
|
274 trafo.concat(trafo.getScale(new Size(1/this.area.width, 1/this.area.height)));
|
|
275 // scale to screen size
|
|
276 trafo.concat(trafo.getScale(picsize));
|
|
277 trafo.concat(trafo.getTranslation(picsize));
|
|
278 // FIX ME: Robert, kannst Du mal nachsehen, ob das folgende tut, was es soll?
|
|
279 // oder gibt es dafuer neuen Code? -- ROC: Bisher funktioniert es nicht!
|
|
280 // rotate
|
|
281 //var rot = getRotation(- dl.params.get("rot"), new Position(0.5*picsize.width, 0.5*picsize.height));
|
|
282 //trafo.concat(rot);
|
|
283 // mirror
|
|
284 //if (hasFlag("hmir")) trafo.m00 = - trafo.m00; // ??
|
|
285 //if (hasFlag("vmir")) trafo.m11 = - trafo.m11; // ??
|
|
286 return trafo;
|
|
287 }
|
|
288
|
|
289 Digilib.prototype.onLoad = function() {
|
|
290 // initialize digilib; called by body.onload
|
|
291 this.scalerDiv = getElement("scaler", true);
|
|
292 this.scalerImg = getElement("pic", true);
|
|
293 this.buttons1Div = getElement("buttons", true);
|
|
294 this.buttons2Div = getElement("options", true);
|
|
295 /*
|
|
296 * if (this.scalerImg == null && this.scalerDiv) { // in N4 pic is in the
|
|
297 * scaler layer this.scalerImg = this.scalerDiv.document.images[0]; }
|
|
298 */
|
|
299 if ((!this.scalerImg)||(!this.scalerDiv)) {
|
|
300 alert("Sorry, digilib doesn't work here!");
|
|
301 return false;
|
|
302 }
|
|
303 // fix fixed menus
|
|
304 var ms1 = getElementSize(this.buttons1Div);
|
|
305 var ms2 = getElementSize(this.buttons2Div);
|
|
306 var maxh = (ms1.height > ms2.height) ? ms1.height : ms2.height;
|
|
307 var wins = getWinSize();
|
|
308 if ((wins.height <= maxh) || (browserType.isIE && (browserType.versIE < 7))) {
|
|
309 // unlock fixed menus to absolute if window is too small or IE
|
|
310 this.buttons1Div.style.position = "absolute";
|
|
311 this.buttons2Div.style.position = "absolute";
|
|
312 }
|
|
313 this.setScalerImage(); // setzt auch onImgLoad
|
|
314 this.setBirdImage(); // laedt das Bird's Eye Bild
|
|
315 }
|
|
316
|
|
317 Digilib.prototype.setScalerImage = function() {
|
|
318 // set the scaler image source (needs the browser size)
|
|
319 var picsize = bestPicSize(this.scalerDiv);
|
|
320 var menusize = getElementSize(this.buttons1Div);
|
|
321 // subtract menu width
|
|
322 picsize.width -= menusize.width;
|
|
323 picsize.height -= this.INSET;
|
|
324 // compose Scaler URL
|
|
325 var src = "../servlet/Scaler?"
|
|
326 + this.params.getAll(this.params.PARAM_ALL & ~(this.params.PARAM_MARK | this.params.PARAM_PAGES));
|
|
327 if (this.opts.get('fitwidth')) {
|
|
328 src += "&dw=" + picsize.width;
|
|
329 } else if (this.opts.get('fitheight')) {
|
|
330 src += "&dh=" + picsize.height;
|
|
331 } else {
|
|
332 src += "&dw=" + picsize.width + "&dh=" + picsize.height;
|
|
333 }
|
|
334 // debug(src);
|
|
335 this.scalerImg.onload = onImgLoad;
|
|
336 this.scalerImg.src = src;
|
|
337
|
|
338 var digilib = this;
|
|
339 // this is a local callback function that can use the current scope
|
|
340
|
|
341 function onImgLoad() {
|
|
342 if (! digilib)
|
|
343 return;
|
|
344 // make sure the image is loaded so we know its size
|
|
345 /* this test seems to have problems sometimes :-(
|
|
346 if (defined(digilib.scalerImg.complete) && !digilib.scalerImg.complete) {
|
|
347 alert("ERROR: the image seems not to be complete in onImgLoad!?");
|
|
348 } */
|
|
349 digilib.trafo = digilib.parseTrafo(digilib.scalerImg);
|
|
350 // display marks
|
|
351 digilib.renderMarks();
|
|
352 digilib.showBirdDiv(isBirdDivVisible);
|
|
353 digilib.showArrows(); // show arrow overlays for zoom navigation
|
|
354 //digilib.moveCenter(true); // click to move point to center
|
|
355 // new Slider("sizes", 1, 5, 2);
|
|
356
|
|
357 //Drag Image (8.9.2009)
|
|
358 if (!digilib.isFullArea())
|
|
359 registerEvent("mousedown", digilib.scalerDiv, dragImage);
|
|
360
|
|
361 focus();
|
|
362 }
|
|
363 }
|
|
364
|
|
365 Digilib.prototype.renderMarks = function() {
|
|
366 // make sure the image is loaded so we know its size
|
|
367 if (!this.trafo) {
|
|
368 alert("ERROR: trafo missing, cannot render marks!");
|
|
369 return;
|
|
370 }
|
|
371 // debugProps(dlArea, "dlArea");
|
|
372 for (var i = 0; i < this.marks.length; i++) {
|
|
373 var div = getElement("mark" + i, true) || createMarkDiv(i);
|
|
374 var mark = this.marks[i];
|
|
375 // debugProps(mark, "mark");
|
|
376 if (this.area.containsPosition(mark)) {
|
|
377 var mpos = this.trafo.transform(mark);
|
|
378 // debugProps(mark, "mpos");
|
|
379 // better not hide the marked spot (MR)
|
|
380 // suboptimal to place -5 pixels and not half size of mark-image
|
|
381 // mpos.x = mpos.x -5;
|
|
382 // mpos.y = mpos.y -5;
|
|
383 moveElement(div, mpos);
|
|
384 showElement(div, true);
|
|
385 } else {
|
|
386 // hide the other marks
|
|
387 showElement(div, false);
|
|
388 }
|
|
389 }
|
|
390 }
|
|
391
|
|
392 Digilib.prototype.display = function(detail, moDetail) {
|
|
393 // redisplay the page
|
|
394 var queryString = this.params.getAll(detail, moDetail);
|
|
395 location.href
|
|
396 = location.protocol + "//"
|
|
397 + location.host
|
|
398 + location.pathname
|
|
399 + "?" + queryString;
|
|
400 }
|
|
401
|
|
402 /* **********************************************
|
|
403 * interactive digilib functions
|
|
404 * ******************************************** */
|
|
405
|
|
406 Digilib.prototype.setMark = function() {
|
|
407 // add a mark where clicked
|
|
408 window.focus();
|
|
409 this.moveCenter(false);
|
|
410
|
|
411 // start event capturing
|
|
412 registerEvent("mousedown", this.scalerDiv, markEvent);
|
|
413
|
|
414 // our own reference to this for the local function
|
|
415 var digilib = this;
|
|
416
|
|
417 function markEvent(evt) {
|
|
418 // event handler adding a new mark
|
|
419 unregisterEvent("mousedown", digilib.scalerDiv, markEvent);
|
|
420 digilib.marks.addEvent(evt);
|
|
421 digilib.display();
|
|
422 return stopEvent(evt);
|
|
423 }
|
|
424
|
|
425 }
|
|
426
|
|
427 Digilib.prototype.removeMark = function() {
|
|
428 // remove the last mark
|
|
429 this.marks.pop();
|
|
430 this.display();
|
|
431 }
|
|
432
|
|
433 Digilib.prototype.resetImage = function() {
|
|
434 // reset the image to its original state
|
|
435 this.display(this.params.PARAM_FILE); // keep only fn/pn
|
|
436 }
|
|
437
|
|
438 Digilib.prototype.dragImage = function(evt) {
|
|
439 // drag the image and load a new detail on mouse up
|
|
440 // makes sense only when zoomed
|
|
441 if (this.isFullArea())
|
|
442 return;
|
|
443 if(evt.preventDefault) evt.preventDefault(); // no Firefox drag and drop
|
|
444 var digilib = this; // our own reference to this for the local function
|
|
445 var startPos = evtPosition(evt);
|
|
446 var pic = this.scalerImg;
|
|
447 var picRect = getElementRect(pic);
|
|
448 // fit the grey div to the scaler image
|
|
449 var div = getElement("bg");
|
|
450 var dx = 0;
|
|
451 var dy = 0;
|
|
452 moveElement(div, picRect);
|
|
453 // hide the scaler image, show it as background of div instead
|
|
454 showElement(pic, false);
|
|
455 showElement(div, true);
|
|
456 div.style.backgroundImage = "url(" + pic.src + ")";
|
|
457 div.style.cursor = "move";
|
|
458 // start event capturing
|
|
459 registerEvent("mousemove", document, moveDragEvent);
|
|
460 registerEvent("mouseup", document, moveEndEvent);
|
|
461 window.focus();
|
|
462
|
|
463 function moveDragEvent(evt) {
|
|
464 // mousemove handler: drag
|
|
465 var pos = evtPosition(evt);
|
|
466 // don't use Firefox Drag and Drop feature
|
|
467 if(evt.preventDefault) evt.preventDefault();
|
|
468 dx = pos.x - startPos.x;
|
|
469 dy = pos.y - startPos.y;
|
|
470 // move the background image to the new position
|
|
471 div.style.backgroundPosition = dx + "px " + dy + "px";
|
|
472 return stopEvent(evt);
|
|
473 }
|
|
474
|
|
475 function moveEndEvent(evt) {
|
|
476 // mouseup handler: reload digilib
|
|
477 div.style.cursor = "default";
|
|
478 unregisterEvent("mousemove", document, moveDragEvent);
|
|
479 unregisterEvent("mouseup", document, moveEndEvent);
|
|
480 // calculate relative offset
|
|
481 var x = -dx / pic.width;
|
|
482 var y = -dy / pic.height;
|
|
483 stopEvent(evt);
|
|
484 if (dx == 0 && dy == 0)
|
|
485 return // no movement
|
|
486 // reload with scaler image showing the new ausschnitt
|
|
487 return digilib.moveBy(x, y);
|
|
488 }
|
|
489 }
|
|
490
|
|
491 Digilib.prototype.zoomArea = function() {
|
|
492 var pt1, pt2;
|
|
493 var zoomdiv = getElement("zoom");
|
|
494 var overlay = getElement("overlay");
|
|
495 // use overlay div to avoid <img> mousemove problems
|
|
496 var picRect = getElementRect(this.scalerImg);
|
|
497 // FIX ME: is there a way to query the border width from CSS info?
|
|
498 // rect.x -= 2; // account for overlay borders
|
|
499 // rect.y -= 2;
|
|
500 moveElement(overlay, picRect);
|
|
501 showElement(overlay, true);
|
|
502 // start event capturing
|
|
503 registerEvent("mousedown", overlay, zoomStart);
|
|
504 registerEvent("mousedown", this.scalerImg, zoomStart);
|
|
505 window.focus();
|
|
506
|
|
507 // our own reference to "this" for the local functions
|
|
508 var digilib = this;
|
|
509
|
|
510 // mousedown handler: start moving
|
|
511 function zoomStart(evt) {
|
|
512 pt1 = evtPosition(evt);
|
|
513 unregisterEvent("mousedown", overlay, zoomStart);
|
|
514 unregisterEvent("mousedown", digilib.scalerImg, zoomStart);
|
|
515 // setup and show zoom div
|
|
516 moveElement(zoomdiv, Rectangle(pt1.x, pt1.y, 0, 0));
|
|
517 showElement(zoomdiv, true);
|
|
518 // register events
|
|
519 registerEvent("mousemove", document, zoomMove);
|
|
520 registerEvent("mouseup", document, zoomEnd);
|
|
521 return stopEvent(evt);
|
|
522 }
|
|
523
|
|
524 // mouseup handler: end moving
|
|
525 function zoomEnd(evt) {
|
|
526 pt2 = evtPosition(evt);
|
|
527 // assume a click if the area is too small (up to 3 x 3 pixel)
|
|
528 var clickRect = new Rectangle(pt1, pt2);
|
|
529 clickRect.normalize();
|
|
530 if (clickRect.getArea() <= digilib.MIN_AREA_SIZE) {
|
|
531 return stopEvent(evt);
|
|
532 }
|
|
533 // hide zoom div
|
|
534 showElement(zoomdiv, false);
|
|
535 showElement(overlay, false);
|
|
536 // unregister events
|
|
537 unregisterEvent("mousemove", document, zoomMove);
|
|
538 unregisterEvent("mouseup", document, zoomEnd);
|
|
539 // clip and transform
|
|
540 clickRect.clipTo(picRect);
|
|
541 var area = digilib.trafo.invtransform(clickRect);
|
|
542 digilib.setParamFromArea(area);
|
|
543 // zoomed is always fit
|
|
544 digilib.params.set("ws", 1);
|
|
545 digilib.display();
|
|
546 return stopEvent(evt);
|
|
547 }
|
|
548
|
|
549 // mouse move handler
|
|
550 function zoomMove(evt) {
|
|
551 pt2 = evtPosition(evt);
|
|
552 var rect = new Rectangle(pt1, pt2);
|
|
553 rect.normalize();
|
|
554 rect.clipTo(picRect);
|
|
555 // update zoom div
|
|
556 moveElement(zoomdiv, rect);
|
|
557 return stopEvent(evt);
|
|
558 }
|
|
559 }
|
|
560
|
|
561 Digilib.prototype.zoomBy = function(factor) {
|
|
562 // zooms by the given factor
|
|
563 var newarea = this.area.copy();
|
|
564 newarea.width /= factor;
|
|
565 newarea.height /= factor;
|
|
566 newarea.x -= 0.5 * (newarea.width - this.area.width);
|
|
567 newarea.y -= 0.5 * (newarea.height - this.area.height);
|
|
568 newarea = this.MAX_AREA.fit(newarea);
|
|
569 this.setParamFromArea(newarea);
|
|
570 this.display();
|
|
571 }
|
|
572
|
|
573
|
|
574 Digilib.prototype.zoomFullpage = function(fit) {
|
|
575 // zooms out to show the whole image
|
|
576 this.params.set("wx", 0.0);
|
|
577 this.params.set("wy", 0.0);
|
|
578 this.params.set("ww", 1.0);
|
|
579 this.params.set("wh", 1.0);
|
|
580 if (fit == "width") {
|
|
581 this.opts.set('fitwidth');
|
|
582 } else if (fit == "height") {
|
|
583 this.opts.set('fitheight');
|
|
584 } else {
|
|
585 this.opts.reset('fitwidth');
|
|
586 this.opts.reset('fitheight');
|
|
587 }
|
|
588 this.display();
|
|
589 }
|
|
590
|
|
591
|
|
592 Digilib.prototype.moveCenter = function(on) {
|
|
593 // move visible area so that it's centered around the clicked point
|
|
594 if (this.isFullArea()) return; // nothing to do
|
|
595 // starting event capture
|
|
596 if (on) registerEvent("mousedown", this.scalerImg, moveCenterEvent);
|
|
597 else unregisterEvent("mousedown", this.scalerImg, moveCenterEvent);
|
|
598 window.focus();
|
|
599
|
|
600 // our own reference to this for the local function
|
|
601 var digilib = this;
|
|
602
|
|
603 function moveCenterEvent(evt) {
|
|
604 // move to handler
|
|
605 var pt = digilib.trafo.invtransform(evtPosition(evt));
|
|
606 var newarea = digilib.area.copy();
|
|
607 newarea.setCenter(pt);
|
|
608 newarea.stayInside(this.MAX_AREA);
|
|
609 // newarea = dlMaxArea.fit(newarea);
|
|
610 // debugProps(newarea, "newarea");
|
|
611 // debugProps(dlArea, "dlArea");
|
|
612 if (newarea.equals(digilib.area)) return; // keep event handler
|
|
613 unregisterEvent("mousedown", digilib.scalerImg, moveCenterEvent);
|
|
614 // set parameters
|
|
615 digilib.setParamFromArea(newarea);
|
|
616 digilib.display();
|
|
617 }
|
|
618 }
|
|
619
|
|
620 Digilib.prototype.isFullArea = function(area) {
|
|
621 if (!area) area = this.area;
|
|
622 return (area.width == 1.0) && (area.height == 1.0);
|
|
623 }
|
|
624
|
|
625 Digilib.prototype.canMove = function(movx, movy) {
|
|
626 if (this.isFullArea()) return false;
|
|
627 var x2 = this.area.x + this.area.width;
|
|
628 var y2 = this.area.y + this.area.height;
|
|
629 // debugProps(dlArea);
|
|
630 return ((movx < 0) && (this.area.x > 0))
|
|
631 || ((movx > 0) && (x2 < 1.0))
|
|
632 || ((movy < 0) && (this.area.y > 0))
|
|
633 || ((movy > 0) && (y2 < 1.0))
|
|
634 }
|
|
635
|
|
636 Digilib.prototype.moveBy = function(movx, movy) {
|
|
637 // move visible area by movx and movy (in units of ww, wh)
|
|
638 if (!this.canMove(movx, movy)) return; // nothing to do
|
|
639 var newarea = this.area.copy();
|
|
640 newarea.x += parseFloat(movx)*this.area.width;
|
|
641 newarea.y += parseFloat(movy)*this.area.height;
|
|
642 newarea = this.MAX_AREA.fit(newarea);
|
|
643 // set parameters
|
|
644 this.setParamFromArea(newarea);
|
|
645 this.display();
|
|
646 }
|
|
647
|
|
648 Digilib.prototype.getRef = function(baseUrl) {
|
|
649 // returns a reference to the current digilib set
|
|
650 if (!baseUrl) baseUrl
|
|
651 = location.protocol
|
|
652 + "//"
|
|
653 + location.host
|
|
654 + location.pathname;
|
|
655 var hyperlinkRef = baseUrl;
|
|
656 with (this.params) {
|
|
657 // all without ddpi, pt
|
|
658 var ps = getAll(PARAM_ALL & ~(PARAM_DPI | PARAM_PAGES | PARAM_CLIENT));
|
|
659 }
|
|
660 if (ps.length > 0) hyperlinkRef += "?" + ps;
|
|
661 return hyperlinkRef;
|
|
662 }
|
|
663
|
|
664 Digilib.prototype.getRefWin = function(type, msg) {
|
|
665 // shows an alert with a reference to the current digilib set
|
|
666 if (! msg) msg = "URL reference to the current view";
|
|
667 prompt(msg, this.getRef());
|
|
668 }
|
|
669
|
|
670 Digilib.prototype.getQuality = function() {
|
|
671 // returns the current q setting
|
|
672 for (var i = 0; i < 3; i++) {
|
|
673 if (this.flags.get("q"+i)) return i;
|
|
674 }
|
|
675 return 1
|
|
676 }
|
|
677
|
|
678 Digilib.prototype.setQuality = function(qual) {
|
|
679 // set the image quality
|
|
680 if ((qual < 0)||(qual > 2)) return alert("Quality setting not supported");
|
|
681 for (var i = 0; i < 3; i++) this.flags.reset("q" + i);
|
|
682 this.flags.set("q" + qual);
|
|
683 this.display();
|
|
684 }
|
|
685
|
|
686 Digilib.prototype.setQualityWin = function(msg) {
|
|
687 // dialog for setting quality
|
|
688 if (! msg) msg = "Quality (0..2)";
|
|
689 var q = this.getQuality();
|
|
690 var newq = window.prompt(msg, q);
|
|
691 if (newq) this.setQuality(newq);
|
|
692 }
|
|
693
|
|
694 Digilib.prototype.mirror = function(dir) {
|
|
695 // mirror the image horizontally or vertically
|
|
696 if (dir == "h") {
|
|
697 this.flags.toggle("hmir");
|
|
698 } else {
|
|
699 this.flags.toggle("vmir");
|
|
700 }
|
|
701 this.display();
|
|
702 }
|
|
703
|
|
704 Digilib.prototype.gotoPage = function(gopage, keep) {
|
|
705 // goto given page nr (+/-: relative)
|
|
706 var oldpn = parseInt(this.params.get("pn"));
|
|
707 // set with relative=true uses the sign
|
|
708 this.params.set("pn", gopage, true);
|
|
709 // now check the outcome
|
|
710 var pn = parseInt(this.params.get("pn"));
|
|
711 if (pn < 1) {
|
|
712 alert("No such page! (Page number too low)");
|
|
713 this.params.set("pn", oldpn);
|
|
714 return;
|
|
715 }
|
|
716 if (this.params.isSet("pt")) {
|
|
717 pt = parseInt(this.params.get("pt"))
|
|
718 if (pn > pt) {
|
|
719 alert("No such page! (Page number too high)");
|
|
720 this.params.set("pn", oldpn);
|
|
721 return;
|
|
722 }
|
|
723 }
|
|
724 if (keep) {
|
|
725 this.display(this.params.PARAM_ALL & ~this.params.PARAM_MARK); // all, no mark
|
|
726 } else {
|
|
727 this.display(this.params.PARAM_FILE | this.params.PARAM_MODE | this.params.PARAM_PAGES, this.params.MODE_QUAL | this.params.MODE_OTHER); // fn, pn, ws, mo + pt
|
|
728 }
|
|
729 }
|
|
730
|
|
731 Digilib.prototype.gotoPageWin = function() {
|
|
732 // dialog to ask for new page nr
|
|
733 var pn = this.params.get("pn");
|
|
734 var gopage = window.prompt("Go to page", pn);
|
|
735 if (gopage) this.gotoPage(gopage);
|
|
736 }
|
|
737
|
|
738 Digilib.prototype.setParamWin = function(param, text, relative) {
|
|
739 // dialog to ask for new parameter value
|
|
740 var val = this.params.get(param);
|
|
741 var newval = window.prompt(text, val);
|
|
742 if (newval) {
|
|
743 this.params.set(param, newval, relative);
|
|
744 this.display();
|
|
745 }
|
|
746 }
|
|
747
|
|
748 Digilib.prototype.showOptions = function(show) {
|
|
749 // show or hide option div
|
|
750 var elem = getElement("dloptions");
|
|
751 showElement(elem, show);
|
|
752 // FIX ME: get rid of the dotted line around the buttons when focused
|
|
753 }
|
|
754
|
|
755 Digilib.prototype.showAboutDiv = function(show) {
|
|
756 // show or hide "about" div
|
|
757 var elem = getElement("about");
|
|
758 if (elem == null) {
|
|
759 if (show) alert("About Digilib - dialog missing in HTML code!"
|
|
760 + "\nDigilib Version: " + digilibVersion
|
|
761 + "\JSP Version: " + jspVersion
|
|
762 + "\ndlLib Version: " + dllibVersion
|
|
763 + "\nbaseLib Version: " + baseLibVersion);
|
|
764 return;
|
|
765 }
|
|
766 if (show) {
|
|
767 getElement("digilib-version").innerHTML = "Digilib Version: " + digilibVersion;
|
|
768 getElement("jsp-version").innerHTML = "JSP Version: " + jspVersion;
|
|
769 getElement("baselib-version").innerHTML = "baseLib Version: " + baseLibVersion;
|
|
770 getElement("dllib-version").innerHTML = "dlLib Version: " + dllibVersion;
|
|
771 var aboutRect = getElementRect(elem);
|
|
772 aboutRect.setCenter(getWinRect().getCenter());
|
|
773 moveElement(elem, aboutRect);
|
|
774 }
|
|
775 showElement(elem, show);
|
|
776 }
|
|
777
|
|
778 Digilib.prototype.setBirdImage = function() {
|
|
779 var img = getElement("bird-image");
|
|
780 var src = "../servlet/Scaler?"
|
|
781 + this.params.getAll(this.params.PARAM_FILE)
|
|
782 + "&dw=" + this.BIRD_MAXX
|
|
783 + "&dh=" + this.BIRD_MAXY;
|
|
784 img.src = src;
|
|
785 }
|
|
786
|
|
787 Digilib.prototype.showBirdDiv = function(show) {
|
|
788 // show or hide "bird's eye" div
|
|
789 var startPos; // anchor for dragging
|
|
790 var newRect; // position after drag
|
|
791 var birdImg = getElement("bird-image");
|
|
792 var birdArea = getElement("bird-area");
|
|
793 var overlay = getElement("bird-overlay");
|
|
794 showElement(birdImg, show);
|
|
795 // dont show selector if area has full size
|
|
796 if (!show || this.isFullArea()) {
|
|
797 // hide area
|
|
798 showElement(birdArea, false);
|
|
799 showElement(overlay, false);
|
|
800 return;
|
|
801 };
|
|
802 var birdImgRect = getElementRect(birdImg);
|
|
803 var area = this.area;
|
|
804 if (this.flags.get("osize") || this.flags.get("clip")) {
|
|
805 // in original-size and pixel-by-pixel mode the area size is not valid
|
|
806 var birdAreaRect = new Rectangle(
|
|
807 birdImgRect.x + birdImgRect.width * area.x,
|
|
808 birdImgRect.y + birdImgRect.height * area.y,
|
|
809 5,
|
|
810 5);
|
|
811 } else {
|
|
812 // scale area down to img size
|
|
813 var birdAreaRect = new Rectangle(
|
|
814 // what about borders ??
|
|
815 birdImgRect.x + birdImgRect.width * area.x,
|
|
816 birdImgRect.y + birdImgRect.height * area.y,
|
|
817 birdImgRect.width * area.width,
|
|
818 birdImgRect.height * area.height);
|
|
819 }
|
|
820 moveElement(birdArea, birdAreaRect);
|
|
821 showElement(birdArea, true);
|
|
822 moveElement(overlay, birdImgRect);
|
|
823 showElement(overlay, true);
|
|
824 registerEvent("mousedown", overlay, birdAreaStartDrag);
|
|
825 registerEvent("mousedown", birdImg, birdAreaStartDrag);
|
|
826
|
|
827 // our own reference to this for local functions
|
|
828 var digilib = this;
|
|
829
|
|
830 function birdAreaStartDrag(evt) {
|
|
831 // mousedown handler: start drag
|
|
832 startPos = evtPosition(evt);
|
|
833 unregisterEvent("mousedown", overlay, birdAreaStartDrag);
|
|
834 unregisterEvent("mousedown", birdImg, birdAreaStartDrag);
|
|
835 registerEvent("mousemove", document, birdAreaMove);
|
|
836 registerEvent("mouseup", document, birdAreaEndDrag);
|
|
837 // debugProps(getElementRect(bird))
|
|
838 return stopEvent(evt);
|
|
839 }
|
|
840
|
|
841 function birdAreaMove(evt) {
|
|
842 // mousemove handler: drag
|
|
843 var pos = evtPosition(evt);
|
|
844 var dx = pos.x - startPos.x;
|
|
845 var dy = pos.y - startPos.y;
|
|
846 // move birdArea div, keeping size
|
|
847 newRect = new Rectangle(
|
|
848 birdAreaRect.x + dx,
|
|
849 birdAreaRect.y + dy,
|
|
850 birdAreaRect.width,
|
|
851 birdAreaRect.height);
|
|
852 // stay within image
|
|
853 newRect.stayInside(birdImgRect);
|
|
854 moveElement(birdArea, newRect);
|
|
855 showElement(birdArea, true);
|
|
856 return stopEvent(evt);
|
|
857 }
|
|
858
|
|
859 function birdAreaEndDrag(evt) {
|
|
860 // mouseup handler: reload page
|
|
861 unregisterEvent("mousemove", document, birdAreaMove);
|
|
862 unregisterEvent("mouseup", document, birdAreaEndDrag);
|
|
863 showElement(overlay, false);
|
|
864 if (newRect == null) { // no movement happened
|
|
865 startPos = birdAreaRect.getCenter();
|
|
866 birdAreaMove(evt); // set center to click position
|
|
867 }
|
|
868 digilib.params.set("wx", cropFloat((newRect.x - birdImgRect.x) / birdImgRect.width));
|
|
869 digilib.params.set("wy", cropFloat((newRect.y - birdImgRect.y) / birdImgRect.height));
|
|
870 // zoomed is always fit
|
|
871 digilib.params.set("ws", 1);
|
|
872 digilib.display();
|
|
873 return stopEvent(evt);
|
|
874 }
|
|
875 }
|
|
876
|
|
877 Digilib.prototype.showArrow = function(name, rect, show) {
|
|
878 var arrow = getElement(name);
|
|
879 moveElement(arrow, rect);
|
|
880 showElement(arrow, show);
|
|
881 }
|
|
882
|
|
883 Digilib.prototype.showArrows = function() {
|
|
884 // show the 4 arrow bars on top of scaler img according to current dlArea
|
|
885 var r = getElementRect(this.scalerImg);
|
|
886 this.showArrow('up',
|
|
887 new Rectangle(r.x, r.y, r.width, this.ARROW_WIDTH),
|
|
888 this.canMove(0, -1)
|
|
889 );
|
|
890 this.showArrow('down',
|
|
891 new Rectangle(r.x, r.y + r.height - this.ARROW_WIDTH, r.width, this.ARROW_WIDTH),
|
|
892 this.canMove(0, 1)
|
|
893 );
|
|
894 this.showArrow('left',
|
|
895 new Rectangle(r.x, r.y, this.ARROW_WIDTH, r.height),
|
|
896 this.canMove(-1, 0)
|
|
897 );
|
|
898 this.showArrow('right',
|
|
899 new Rectangle(r.x + r.width - this.ARROW_WIDTH, r.y, this.ARROW_WIDTH, r.height),
|
|
900 this.canMove(1, 0)
|
|
901 );
|
|
902 }
|
|
903
|
|
904 Digilib.prototype.calibrate = function() {
|
|
905 // calibrate screen resolution
|
|
906 var calDiv = getElement("calibration");
|
|
907 var calRect = getElementRect(calDiv);
|
|
908 moveCenter(false);
|
|
909 var wins = getWinSize();
|
|
910 calRect.setCenter(new Position(wins.width / 2, wins.height / 2));
|
|
911 moveElement(calDiv, calRect);
|
|
912 showElement(calDiv, true);
|
|
913 var cm = window.prompt("The length of the scale on your screen in centimeter:");
|
|
914 if (cm) {
|
|
915 var dpi = calRect.width / parseFloat(cm) * 2.54;
|
|
916 this.params.set("ddpi", cropFloat(dpi));
|
|
917 }
|
|
918 showElement(calDiv, false);
|
|
919 }
|
|
920
|
|
921
|
|
922 Digilib.prototype.setScale = function(scale) {
|
|
923 // sets original-size, pixel-by-pixel or fit-to-screen scale type
|
|
924 if (scale == "pixel") {
|
|
925 // pixel by pixel
|
|
926 this.flags.set("clip");
|
|
927 this.flags.reset("osize");
|
|
928 this.flags.reset("fit");
|
|
929 } else if (scale == "original") {
|
|
930 // original size -- needs calibrated screen
|
|
931 if (!this.params.isSet("ddpi")) {
|
|
932 var dpi = cookie.get("ddpi");
|
|
933 if (dpi == null) {
|
|
934 alert("Your screen has not yet been calibrated - using default value of 72 dpi");
|
|
935 dpi = 72;
|
|
936 }
|
|
937 this.params.set("ddpi", dpi);
|
|
938 }
|
|
939 this.flags.set("osize");
|
|
940 this.flags.reset("clip");
|
|
941 this.flags.reset("fit");
|
|
942 } else {
|
|
943 // scale to screen size (default)
|
|
944 this.flags.reset("clip");
|
|
945 this.flags.reset("osize");
|
|
946 }
|
|
947 this.display();
|
|
948 }
|
|
949
|
|
950 Digilib.prototype.getScale = function() {
|
|
951 // returns scale type
|
|
952 if (this.flags.get("clip")) {
|
|
953 return "pixel";
|
|
954 } else if (this.flags.get("osize")) {
|
|
955 return "original";
|
|
956 } else {
|
|
957 return "fit";
|
|
958 }
|
|
959 }
|
|
960
|
|
961 Digilib.prototype.pageWidth = function() {
|
|
962 this.zoomFullpage('width');
|
|
963 }
|
|
964
|
|
965 Digilib.prototype.setSize = function(factor) {
|
|
966 this.params.set("ws", factor);
|
|
967 this.display();
|
|
968 }
|
|
969
|
|
970 Digilib.prototype.showMenu = function(menuId, buttonId, show) {
|
|
971 var menu = getElement(menuId);
|
|
972 if (show) {
|
|
973 // align right side of menu with button
|
|
974 var buttonPos = getElementPosition(getElement(buttonId));
|
|
975 var menusize = getElementSize(menu);
|
|
976 moveElement(menu, new Position(buttonPos.x - menusize.width - 3, buttonPos.y));
|
|
977 }
|
|
978 showElement(menu, show);
|
|
979 }
|
|
980
|
|
981
|
|
982 /********************************
|
|
983 * global variables
|
|
984 ********************************/
|
|
985
|
|
986 var dl = new Digilib();
|
|
987
|
|
988 /* old parameter function compatibility stuff */
|
|
989 function newParameter(a,b,c) {return dl.params.define(a,b,c)};
|
|
990 function resetParameter(a) {return dl.params.reset(a)};
|
|
991 function deleteParameter(a) {return dl.params.remove(a)};
|
|
992 function getParameter(a) {return dl.params.get(a)};
|
|
993 function setParameter(a,b,c) {return dl.params.set(a,b,c)};
|
|
994 function hasParameter(a) {return dl.params.isSet(a)};
|
|
995 function getAllParameters(a) {return dl.params.getAll(a)};
|
|
996 getQueryString = getAllParameters;
|
|
997 function parseParameters(a) {return dl.params.parse(a)};
|
|
998 function getAllMarks() {return dl.marks.getAll()};
|
|
999 getMarksQueryString = getAllMarks;
|
|
1000 function addMark(evt) {return dl.marks.addEvent(evt)};
|
|
1001 function deleteMark() {return dl.marks.pop()};
|
|
1002 function deleteAllMarks() {return dl.marks = new Marks()};
|
|
1003 function hasFlag(mode) {return dl.flags.get(mode)};
|
|
1004 function addFlag(mode) {return dl.flags.set(mode)};
|
|
1005 function removeFlag(mode) {return dl.flags.reset(mode)};
|
|
1006 function toggleFlag(mode) {return dl.flags.toggle(mode)};
|
|
1007 function getAllFlags() {return dl.flags.getAll()};
|
|
1008 /* old digilib function compatibility */
|
|
1009 function setDLParam(e, s, relative) {dl.setDLParam(e, s, relative)};
|
|
1010 function display(detail, moDetail) {dl.display(detail, moDetail)};
|
|
1011 function setMark(reload) {dl.setMark(reload)};
|
|
1012 function removeMark(reload) {dl.removeMark(reload)};
|
|
1013 function resetImage() {dl.resetImage()};
|
|
1014 function dragImage(evt) {dl.dragImage(evt)};
|
|
1015 function zoomArea() {dl.zoomArea()};
|
|
1016 function zoomBy(factor) {dl.zoomBy(factor)};
|
|
1017 function zoomFullpage(a) {dl.zoomFullpage(a)};
|
|
1018 function moveCenter(on) {dl.moveCenter(on)};
|
|
1019 function isFullArea(area) {dl.isFullArea(area)};
|
|
1020 function canMove(movx, movy) {dl.canMove(movx, movy)};
|
|
1021 function moveBy(movx, movy) {dl.moveBy(movx, movy)};
|
|
1022 function getRef(baseURL) {dl.getRef(baseURL)};
|
|
1023 function getRefWin(type, msg) {dl.getRefWin(type, msg)};
|
|
1024 function getQuality() {dl.getQuality()};
|
|
1025 function setQuality(qual) {dl.setQuality(qual)};
|
|
1026 function setQualityWin(msg) {dl.setQualityWin(msg)};
|
|
1027 function mirror(dir) {dl.mirror(dir)};
|
|
1028 function gotoPage(gopage, keep) {dl.gotoPage(gopage, keep)};
|
|
1029 function gotoPageWin() {dl.gotoPageWin()};
|
|
1030 function setParamWin(param, text, relative) {dl.setParamWin(param, text, relative)};
|
|
1031 function showOptions(show) {dl.showOptions(show)};
|
|
1032 function showBirdDiv(show) {dl.showBirdDiv(show)};
|
|
1033 function showAboutDiv(show) {dl.showAboutDiv(show)};
|
|
1034 function calibrate(direction) {dl.calibrate(direction)};
|
|
1035 function setScale(a) {dl.setScale(a)};
|
|
1036 function getScale(a) {dl.getScale(a)};
|
|
1037 function originalSize(on) {dl.originalSize(on)};
|
|
1038 function pixelByPixel(on) {dl.pixelByPixel(on)};
|
|
1039 function pageWidth() {dl.pageWidth()};
|
|
1040 function setSize(factor) {dl.setSize(factor)};
|
|
1041 function showMenu(a,b,c) {dl.showMenu(a,b,c)};
|
|
1042
|
|
1043
|
|
1044 // :tabSize=4:indentSize=4:noTabs=true:
|
|
1045
|