Annotation of zogiLib/js/navigation.js, revision 1.5
1.1 dwinter 1: /*
2: Copyright (C) 2003 WTWG, Uni Bern
3:
4: This program is free software; you can redistribute it and/or
5: modify it under the terms of the GNU General Public License
6: as published by the Free Software Foundation; either version 2
7: of the License, or (at your option) any later version.
8:
9: This program is distributed in the hope that it will be useful,
10: but WITHOUT ANY WARRANTY; without even the implied warranty of
11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12: GNU General Public License for more details.
13:
14: You should have received a copy of the GNU General Public License
15: along with this program; if not, write to the Free Software
16: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
17:
18: Author: Christian Luginbuehl, 01.05.2003 , Version Alcatraz 0.4
1.3 casties 19: Changed for digiLib in Zope by DW 24.03.2004, ROC 09.04.2004
1.1 dwinter 20: */
21:
22: var ZOOMFACTOR = Math.sqrt(2);
23:
1.3 casties 24: var dlParams = new Object();
25: var dlMarks = new Array();
26: var dlArea = new Rectangle(0.0, 0.0, 1.0, 1.0);
27: var dlMaxArea = new Rectangle(0.0, 0.0, 1.0, 1.0);
28: var dlFlags = new Object();
29: var dlTrafo = new Transform();
30:
31: // fixes for silly browsers
32: if (! Array.prototype.push) {
33: Array.prototype.push = function(val) {
34: this[this.length] = val;
1.4 casties 35: return this.length;
36: }
37: Array.prototype.pop = function() {
38: var val = this[this.length-1];
39: this.length -= 1;
40: return val;
1.3 casties 41: }
42: }
1.1 dwinter 43:
1.3 casties 44: // auxiliary function to crop senseless precision
45: function cropFloat(x) {
46: return parseInt(10000*x)/10000;
47: }
1.1 dwinter 48:
1.3 casties 49: function newParameter(name, defaultValue, detail) {
50: // create a new parameter with a name and a default value
1.4 casties 51: if (dlParams[name]) {
52: alert("Fatal: An object with name '" + name + "' already exists - cannot recreate!");
53: return false;
54: } else {
1.3 casties 55: dlParams[name] = new Object();
56: dlParams[name].defaultValue = defaultValue;
57: dlParams[name].hasValue = false;
58: dlParams[name].value = defaultValue;
59: dlParams[name].detail = detail;
60: return dlParams[name];
61: }
62: }
1.1 dwinter 63:
1.3 casties 64: function getParameter(name) {
65: // returns the named parameter value or its default value
66: if (dlParams[name]) {
67: if (dlParams[name].hasValue) {
68: return dlParams[name].value;
69: } else {
70: return dlParams[name].defaultValue;
71: }
72: } else {
1.4 casties 73: return undefined;
1.3 casties 74: }
75: }
1.1 dwinter 76:
1.3 casties 77: function setParameter(name, value) {
78: // sets parameter value
79: if (dlParams[name]) {
80: dlParams[name].value = value;
81: dlParams[name].hasValue = true;
1.4 casties 82: return true;
1.3 casties 83: }
1.4 casties 84: return false;
1.3 casties 85: }
1.1 dwinter 86:
1.3 casties 87: function getAllParameters(detail) {
88: // returns a string of all parameters in query format
89: var params = new Array();
90: for ( param in dlParams ) {
91: if ((dlParams[param].detail <= detail)&&(dlParams[param].hasValue)) {
92: var val = getParameter(param);
93: if (val != "") {
94: params.push(param + "=" + val);
95: }
96: }
97: }
98: return params.join("&");
99: }
1.1 dwinter 100:
1.3 casties 101: function parseParameters(query) {
102: // gets parameter values from query format string
103: var params = query.split("&");
104: for (var i = 0; i < params.length; i++) {
105: var keyval = params[i].split("=");
106: if (keyval.length == 2) {
107: setParameter(keyval[0], keyval[1]);
108: }
109: }
110: }
1.1 dwinter 111:
1.3 casties 112: function parseArea() {
113: // returns area Rectangle from current parameters
114: return new Rectangle(getParameter("wx"), getParameter("wy"), getParameter("ww"), getParameter("wh"));
115: }
116:
117: function setParamFromRect(rect) {
118: // sets digilib wx etc. from rect
119: setParameter("wx", cropFloat(rect.x));
120: setParameter("wy", cropFloat(rect.y));
121: setParameter("ww", cropFloat(rect.width));
122: setParameter("wh", cropFloat(rect.height));
1.4 casties 123: return true;
1.3 casties 124: }
125:
126: function parseTrafo() {
127: // returns Transform from current dlArea and picsize
1.4 casties 128: var picsize = getElementSize("pic");
1.3 casties 129: var trafo = new Transform();
130: // subtract area offset and size
131: trafo.concat(getTranslation(new Position(-dlArea.x, -dlArea.y)));
132: trafo.concat(getScale(new Size(1/dlArea.width, 1/dlArea.height)));
133: // scale to screen size
134: trafo.concat(getScale(picsize));
1.4 casties 135: trafo.concat(getTranslation(picsize));
1.3 casties 136: // rotate
137: //trafo.concat(getRotation(- getParameter("rot"), new Position(0.5*picsize.width, 0.5*picsize.height)));
138: // mirror
139: //if (hasFlag("hmir")) {
140: //trafo.m00 = - trafo.m00;
141: //}
142: //if (hasFlag("vmir")) {
143: //trafo.m11 = - trafo.m11;
144: //}
145: return trafo;
146: }
147:
148: function parseMarks() {
149: // returns marks array from current parameters
150: var marks = new Array();
151: var ma = getParameter("mk").split(";");
152: for (var i = 0; i < ma.length ; i++) {
153: var pos = ma[i].split("/");
154: if (pos.length > 1) {
155: marks.push(new Position(pos[0], pos[1]));
156: }
157: }
158: return marks;
159: }
1.1 dwinter 160:
1.3 casties 161: function getAllMarks() {
162: // returns a string with all marks in query format
163: var marks = new Array();
164: for (var i = 0; i < dlMarks.length; i++) {
165: marks.push(cropFloat(dlMarks[i].x) + "/" + cropFloat(dlMarks[i].y));
166: }
167: return marks.join(";");
1.1 dwinter 168: }
169:
1.4 casties 170: function addMark(pos) {
1.3 casties 171: // add a mark
1.4 casties 172: dlMarks.push(pos);
1.3 casties 173: setParameter("mk", getAllMarks());
1.4 casties 174: return true;
1.3 casties 175: }
1.1 dwinter 176:
1.3 casties 177: function deleteMark() {
178: // delete the last mark
179: dlMarks.pop();
180: setParameter("mk", getAllMarks());
1.4 casties 181: return true;
1.1 dwinter 182: }
183:
1.3 casties 184: function hasFlag(mode) {
185: // returns if mode flag is set
1.4 casties 186: return (dlFlags[mode]);
1.3 casties 187: }
1.1 dwinter 188:
1.3 casties 189: function addFlag(mode) {
190: // add a mode flag
191: dlFlags[mode] = mode;
1.4 casties 192: return true;
1.3 casties 193: }
1.1 dwinter 194:
1.3 casties 195: function removeFlag(mode) {
196: // remove a mode flag
197: if (dlFlags[mode]) {
1.4 casties 198: delete dlFlags[mode];
1.3 casties 199: }
1.4 casties 200: return true;
1.3 casties 201: }
1.1 dwinter 202:
1.3 casties 203: function toggleFlag(mode) {
204: // change a mode flag
205: if (dlFlags[mode]) {
1.4 casties 206: delete dlFlags[mode];
1.3 casties 207: } else {
208: dlFlags[mode] = mode;
209: }
1.4 casties 210: return true;
1.3 casties 211: }
1.1 dwinter 212:
1.3 casties 213: function getAllFlags() {
214: // returns a string with all flags in query format
215: var fa = new Array();
216: for (var f in dlFlags) {
217: if ((f != "")&&(dlFlags[f] != null)) {
218: fa.push(f);
219: }
220: }
221: return fa.join(",");
222: }
1.1 dwinter 223:
1.3 casties 224: function parseFlags() {
225: // sets dlFlags from the current parameters
226: var flags = new Object();
227: var fa = getParameter("mo").split(",");
228: for (var i = 0; i < fa.length ; i++) {
229: var f = fa[i];
230: if (f != "") {
231: flags[f] = f;
232: }
233: }
234: return flags;
235: }
1.1 dwinter 236:
1.3 casties 237: /*
238: * Size class
239: */
240: function Size(w, h) {
241: this.width = parseFloat(w);
242: this.height = parseFloat(h);
1.4 casties 243: return this;
1.3 casties 244: }
245:
246: /*
247: * Position class
248: */
249: function Position(x, y) {
250: this.x = parseFloat(x);
251: this.y = parseFloat(y);
1.4 casties 252: return this;
253: }
254: function evtPosition(evt) {
255: // returns the on-screen Position of the Event
256: var x;
257: var y;
258: if (document.all) {
259: x = parseInt(document.body.scrollLeft+event.clientX);
260: y = parseInt(document.body.scrollLeft+event.clientY);
261: } else {
262: x = parseInt(evt.pageX);
263: y = parseInt(evt.pageY);
264: }
265: return new Position(x, y);
1.3 casties 266: }
267:
268: /*
269: * Rectangle class
270: */
271: function Rectangle(x, y, w, h) {
272: this.x = parseFloat(x);
273: this.y = parseFloat(y);
274: this.width = parseFloat(w);
275: this.height = parseFloat(h);
1.4 casties 276: return this;
1.3 casties 277: }
278: Rectangle.prototype.copy = function() {
279: // returns a copy of this Rectangle
280: return new Rectangle(this.x, this.y, this.width, this.height);
281: }
282: Rectangle.prototype.containsPosition = function(pos) {
283: // returns if the given Position lies in this Rectangle
284: return ((pos.x >= this.x)&&(pos.y >= this.y)&&(pos.x <= this.x+this.width)&&(pos.y <= this.y+this.width));
285: }
286: Rectangle.prototype.intersect = function(rect) {
287: // returns the intersection of the given Rectangle and this one
288: var sec = rect.copy();
289: if (sec.x < this.x) {
290: sec.width = sec.width - (this.x - sec.x);
291: sec.x = this.x;
292: }
293: if (sec.y < this.y) {
294: sec.height = sec.height - (this.y - sec.y);
295: sec.y = this.y;
296: }
297: if (sec.x + sec.width > this.x + this.width) {
298: sec.width = (this.x + this.width) - sec.x;
299: }
300: if (sec.y + sec.height > this.y + this.height) {
301: sec.height = (this.y + this.height) - sec.y;
302: }
303: return sec;
304: }
305: Rectangle.prototype.fit = function(rect) {
306: // returns a Rectangle that fits into this one (by moving first)
307: var sec = rect.copy();
308: sec.x = Math.max(sec.x, this.x);
309: sec.x = Math.max(sec.x, this.x);
310: if (sec.x + sec.width > this.x + this.width) {
311: sec.x = this.x + this.width - sec.width;
312: }
313: if (sec.y + sec.height > this.y + this.height) {
314: sec.y = this.y + this.height - sec.height;
315: }
316: return sec.intersect(this);
1.1 dwinter 317: }
318:
1.3 casties 319: /*
320: * Transform class
321: */
322: function Transform() {
323: this.m00 = 1.0;
324: this.m01 = 0.0;
325: this.m02 = 0.0;
326: this.m10 = 0.0;
327: this.m11 = 1.0;
328: this.m12 = 0.0;
329: this.m20 = 0.0;
330: this.m21 = 0.0;
331: this.m22 = 1.0;
1.4 casties 332: return this;
1.3 casties 333: }
334: Transform.prototype.concat = function(traf) {
335: for (var i = 0; i < 3; i++) {
336: for (var j = 0; j < 3; j++) {
337: var c = 0.0;
338: for (var k = 0; k < 3; k++) {
339: c += traf["m"+i+k] * this["m"+k+j];
340: }
341: this["m"+i+j] = c;
342: }
343: }
1.4 casties 344: return this;
1.3 casties 345: }
346: Transform.prototype.transform = function(pos) {
347: var x = this.m00 * pos.x + this.m01 * pos.y + this.m02;
348: var y = this.m10 * pos.x + this.m11 * pos.y + this.m12;
349: return new Position(x, y);
350: }
351: Transform.prototype.invtransform = function(pos) {
352: var det = this.m00 * this.m11 - this.m01 * this.m10;
353: var x = (this.m11 * pos.x - this.m01 * pos.y - this.m11 * this.m02 + this.m01 * this.m12) / det;
354: var y = (- this.m10 * pos.x + this.m00 * pos.y + this.m10 * this.m02 - this.m00 * this.m12) / det;
355: return new Position(x, y);
356: }
357: function getRotation(angle, pos) {
358: var traf = new Transform();
359: if (angle != 0) {
360: var t = 2.0 * Math.PI * parseFloat(angle) / 360.0;
361: traf.m00 = Math.cos(t);
362: traf.m01 = - Math.sin(t);
363: traf.m10 = Math.sin(t);
364: traf.m11 = Math.cos(t);
365: traf.m02 = pos.x - pos.x * Math.cos(t) + pos.y * Math.sin(t);
366: traf.m12 = pos.y - pos.x * Math.sin(t) - pos.y * Math.cos(t);
367: }
368: return traf;
369: }
370: function getTranslation(pos) {
371: var traf = new Transform();
372: traf.m02 = pos.x;
373: traf.m12 = pos.y;
374: return traf;
375: }
376: function getScale(size) {
377: var traf = new Transform();
378: traf.m00 = size.width;
379: traf.m11 = size.height;
380: return traf;
381: }
382:
383: function getElement(tagid) {
384: // returns the named element object
1.4 casties 385: if (document.getElementById) {
386: return document.getElementById(tagid);
387: } else if (document.all) {
388: alert("document.all!");
1.3 casties 389: return document.all[tagid];
390: } else {
1.5 ! casties 391: var s = "";
! 392: for (var e in document.layers) {
! 393: s += "'" + e + "', ";
! 394: }
! 395: alert("no document.all! "+tagid+" = "+s);
1.3 casties 396: return document[tagid];
397: }
398: }
1.1 dwinter 399:
1.3 casties 400: function getElementSize(tagid) {
401: // returns a Rectangle with the size and position of the named element
402: var x = 0;
403: var y = 0;
404: var width = 0;
405: var height = 0;
406: var elem = getElement(tagid);
1.4 casties 407: if (elem.left) {
408: alert("elem.left!");
409: x = elem.left;
410: y = elem.top;
411: width = elem.width;
412: height = elem.height;
413: } else {
414: if (elem.clientLeft) {
415: // spass mit IE
416: x = elem.clientLeft;
417: y = elem.clientTop;
418: } else {
419: var e = elem;
420: while (e) {
421: x += e.offsetLeft;
422: y += e.offsetTop;
423: e = e.offsetParent;
424: }
425: }
426: width = elem.offsetWidth;
427: height = elem.offsetHeight;
1.3 casties 428: }
429: return new Rectangle(x, y, width, height);
430: }
1.1 dwinter 431:
1.3 casties 432: function moveElement(tagid, pos) {
433: // moves the named element to the indicated position
434: var elem = getElement(tagid);
435: if (elem.style) {
1.4 casties 436: elem.style.left = pos.x + "px";
437: elem.style.top = pos.y + "px";
1.3 casties 438: } else {
439: alert("moveelement: no style property!");
1.4 casties 440: elem.left = pos.x;
441: elem.top = pos.y;
1.3 casties 442: }
1.4 casties 443: return true;
1.3 casties 444: }
1.1 dwinter 445:
1.3 casties 446: function showElement(tagid, show) {
447: // shows or hides the named element
448: var elem = getElement(tagid);
449: if (elem.style) {
450: if (show) {
451: elem.style.visibility = "visible";
452: } else {
453: elem.style.visibility = "hidden";
454: }
455: } else {
456: alert("showelement: no style property!");
457: }
1.4 casties 458: return true;
1.3 casties 459: }
1.1 dwinter 460:
1.3 casties 461: function registerMouseDown(tagid, handler) {
462: // register a mouse down event handler on the indicated element
463: if ( document.all ) {
464: document.all[tagid].onmousedown = handler;
465: } else if (document.getElementById) {
466: document.getElementById(tagid).addEventListener("mousedown", handler, true);
467: } else {
468: document[tagid].captureEvents(Event.MOUSEDOWN);
469: document[tagid].onmousedown = handler;
470: }
1.4 casties 471: return true;
1.3 casties 472: }
1.1 dwinter 473:
1.3 casties 474: function unregisterMouseDown(tagid, handler) {
475: // unregister the mouse down event handler
476: if ( document.all ) {
477: document.all[tagid].onmousedown = null;
478: } else if (document.getElementById) {
479: document.getElementById(tagid).removeEventListener("mousedown", handler, true);
480: } else {
481: document[tagid].releaseEvents(Event.MOUSEDOWN);
482: }
1.4 casties 483: return true;
1.1 dwinter 484: }
485:
1.3 casties 486: function registerMouseMove(tagid, handler) {
487: // register a mouse move event handler on the indicated element
488: if ( document.all ) {
489: document.all[tagid].onmousemove = handler;
490: } else if (document.getElementById) {
491: document.getElementById(tagid).addEventListener("mousemove", handler, true);
492: } else {
493: document[tagid].captureEvents(Event.MOUSEMOVE);
494: document[tagid].onmousemove = handler;
495: }
1.4 casties 496: return true;
1.3 casties 497: }
1.1 dwinter 498:
1.3 casties 499: function unregisterMouseMove(tagid, handler) {
500: // unregister the mouse move event handler
501: if ( document.all ) {
502: document.all[tagid].onmousemove = null;
503: } else if (document.getElementById) {
504: document.getElementById(tagid).removeEventListener("mousemove", handler, true);
505: } else {
506: document[tagid].releaseEvents(Event.MOUSEMOVE);
507: }
1.4 casties 508: return true;
1.3 casties 509: }
1.1 dwinter 510:
1.3 casties 511: function registerKeyDown(handler) {
512: // register a key down handler
513: if ( document.all ) {
514: this.document.onkeypress = handler
515: } else if ( typeof(document.addEventListener) == "function" ) {
516: this.document.addEventListener('keypress', handler, true);
517: } else {
518: window.captureEvents(Event.KEYDOWN);
519: window.onkeydown = handler;
520: }
1.4 casties 521: return true;
1.3 casties 522: }
1.1 dwinter 523:
1.3 casties 524: function getWinSize() {
525: // returns a Size with the current window size (from www.quirksmode.org)
526: var wsize = new Size(100, 100);
527: if (self.innerHeight) {
528: // all except Explorer
529: wsize.width = self.innerWidth;
530: wsize.height = self.innerHeight;
531: } else if (document.documentElement && document.documentElement.clientHeight) {
532: // Explorer 6 Strict Mode
533: wsize.width = document.documentElement.clientWidth;
534: wsize.height = document.documentElement.clientHeight;
535: } else if (document.body) {
536: // other Explorers
537: wsize.width = document.body.clientWidth;
538: wsize.height = document.body.clientHeight;
539: }
540: return wsize;
541: }
1.1 dwinter 542:
1.3 casties 543: function bestPicSize(tagid) {
544: // returns a Size with the best image size for the given tagid
1.4 casties 545: var inset = 0;
546: var ws = getWinSize();
547: var es = getElementSize(tagid);
1.5 ! casties 548: if (es) {
! 549: ws.width = ws.width - es.x - inset;
! 550: ws.height = ws.height - es.y - inset;
! 551: }
1.4 casties 552: return ws;
1.1 dwinter 553: }
554:
555:
556:
1.3 casties 557: function init() {
1.5 ! casties 558: if (document.layers) {
! 559: alert("Sorry Netscape4 is not supported!");
! 560: return false;
! 561: }
1.3 casties 562: // give a name to the window containing digilib - this way one can test if there is already a
563: // digilib-window open and replace the contents of it (ex. digicat)
564: top.window.name = "digilib";
565: // put the query parameters (sans "&") in the parameters array
566: parseParameters(location.search.slice(1));
567: // treat special parameters
568: dlMarks = parseMarks();
569: dlArea = parseArea();
570: dlFlags = parseFlags();
1.1 dwinter 571:
1.3 casties 572: //registerKeyDown(parseKeypress);
573:
574: placeMarks();
1.1 dwinter 575:
1.3 casties 576: focus();
577: return true;
578: }
1.1 dwinter 579:
580:
1.3 casties 581: function display(detail) {
582: // redisplay the page
583: var queryString = getAllParameters(detail);
584: location.href = location.protocol + "//" + location.host + location.pathname + "?" + queryString;
585: }
1.1 dwinter 586:
587:
588:
589: function page(page, details) {
590:
591: if ( details == null ) {
592: details = 1;
593: }
594:
595: if ( page.indexOf('-') == 0 ) {
596: if ( dlParams.pn.value > 1 ) {
597: page = Math.max(parseInt(dlParams.pn.value) - parseInt(page.slice(1)), 1);
598: dlParams.pn.value = page;
599: display(details);
600: } else {
601: alert("You are already on the first page!");
602: }
603:
604: } else if ( page.indexOf('+') == 0 ) {
605: page = parseInt(dlParams.pn.value) + parseInt(page.slice(1));
606: dlParams.pn.value = page;
607: display(details);
608: } else if ( page == parseInt(page) ) {
609: dlParams.pn.value = parseInt(page);
610: display(details);
611: }
612:
613: }
614:
615:
616:
617: function ref(select) {
1.3 casties 618: // open a dialog with a reference to the current digilib set
619: var hyperlinkRef = baseUrl + "?" + getAllParameters(9);
620: if ( select == 0 ) {
621: prompt("Link for LaTeX-documents", "\\href{" + hyperlinkRef + "}{TEXT}");
622: } else if ( select == 1 ) {
623: prompt("Link for HTML-documents", hyperlinkRef);
624: }
1.1 dwinter 625: }
626:
627:
628: function mark() {
1.3 casties 629: // add a mark where clicked
630: if ( dlMarks.length > 7 ) {
631: alert("Only 8 marks are possible at the moment!");
632: return;
633: }
1.1 dwinter 634:
1.3 casties 635: function markEvent(evt) {
636: // event handler adding a new mark
637: unregisterMouseDown("scaler", markEvent);
1.4 casties 638: var p = dlTrafo.invtransform(evtPosition(evt));
639: addMark(p);
1.3 casties 640: placeMarks();
641: }
1.1 dwinter 642:
1.3 casties 643: // starting event capture
644: registerMouseDown("scaler", markEvent);
645: }
1.1 dwinter 646:
1.3 casties 647: function unmark() {
648: // remove the last mark
649: deleteMark();
1.1 dwinter 650: placeMarks();
651: }
652:
653: function placeMarks() {
1.3 casties 654: // put the visible marks on the image
655: var mark_count = dlMarks.length;
656: var picelem = getElement("pic");
657: // make shure the image is loaded so we know its size
658: if (picelem && picelem.complete == false) {
659: setTimeout("placeMarks()", 100);
660: } else {
1.4 casties 661: var picsize = getElementSize("pic");
1.3 casties 662: dlTrafo = parseTrafo();
663: for (var i = 0; i < 8; i++) {
664: if (i < mark_count) {
665: if (dlArea.containsPosition(dlMarks[i])) {
666: var mpos = dlTrafo.transform(dlMarks[i]);
667: // suboptimal to place -5 pixels and not half size of mark-image
1.4 casties 668: mpos.x = mpos.x -5;
669: mpos.y = mpos.y -5;
1.3 casties 670: moveElement("dot"+i, mpos);
671: showElement("dot"+i, true);
1.1 dwinter 672: }
1.3 casties 673: } else {
674: // hide the other marks
675: showElement("dot"+i, false);
676: }
1.1 dwinter 677: }
1.3 casties 678: }
1.1 dwinter 679: }
680:
681:
1.3 casties 682: function zoomPoint(inout) {
683: // zoom image in or out around the clicked point
684: var zoom = ZOOMFACTOR;
685: if (inout < 0) {
686: zoom = 1/ZOOMFACTOR;
687: }
1.4 casties 688: window.focus();
1.1 dwinter 689:
1.3 casties 690: function zoomPointEvent(evt) {
691: // take new center and set zoom parameters
1.4 casties 692: var p = dlTrafo.invtransform(evtPosition(evt));
1.3 casties 693: var neww = Math.min(dlArea.width * (1/zoom), 1.0);
694: var newh = Math.min(dlArea.height * (1/zoom), 1.0);
1.4 casties 695: var newx = p.x - 0.5 * neww;
696: var newy = p.y - 0.5 * newh;
1.3 casties 697: var zoomarea = new Rectangle(newx, newy, neww, newh);
698: // check bounds
699: zoomarea = dlMaxArea.fit(zoomarea);
700: // set parameters
701: setParameter("wx", cropFloat(zoomarea.x));
702: setParameter("wy", cropFloat(zoomarea.y));
703: setParameter("ww", cropFloat(zoomarea.width));
704: setParameter("wh", cropFloat(zoomarea.height));
705: parseArea();
706: display(3);
1.1 dwinter 707: }
1.4 casties 708:
1.3 casties 709: // starting event capture
710: registerMouseDown("scaler", zoomPointEvent);
1.1 dwinter 711: }
712:
713:
714: function zoomArea() {
1.3 casties 715: var click = 1;
716: var pt1, pt2;
717: var eck1pos, eck2pos, eck3pos, eck4pos;
718: window.focus();
719:
720: function zoomClick(evt) {
721: // mouse click handler
722: if (click == 1) {
723: // first click -- start moving
724: click = 2;
1.4 casties 725: pt1 = evtPosition(evt);
1.3 casties 726: pt2 = pt1;
1.4 casties 727: eck1pos = pt1;
728: eck2pos = new Position(pt1.x - 12, pt1.y);
729: eck3pos = new Position(pt1.x, pt1.y - 12);
730: eck4pos = new Position(pt1.y - 12, pt1.y - 12);
1.3 casties 731: moveElement("eck1", eck1pos);
732: moveElement("eck2", eck2pos);
733: moveElement("eck3", eck3pos);
734: moveElement("eck4", eck4pos);
735: showElement("eck1", true);
736: showElement("eck2", true);
737: showElement("eck3", true);
738: showElement("eck4", true);
739: registerMouseMove("scaler", zoomMove);
740: registerMouseMove("eck4", zoomMove);
741: } else {
742: // second click -- end moving
1.4 casties 743: pt2 = evtPosition(evt);
1.3 casties 744: showElement("eck1", false);
745: showElement("eck2", false);
746: showElement("eck3", false);
747: showElement("eck4", false);
748: unregisterMouseMove("scaler", zoomMove);
749: unregisterMouseMove("eck4", zoomMove);
750: unregisterMouseDown("scaler", zoomClick);
751: unregisterMouseDown("eck4", zoomClick);
1.4 casties 752: var p1 = dlTrafo.invtransform(pt1);
753: var p2 = dlTrafo.invtransform(pt2);
754: var ww = p2.x-p1.x;
755: var wh = p2.y-p1.y;
1.3 casties 756: if ((ww > 0)&&(wh > 0)) {
1.4 casties 757: setParameter("wx", cropFloat(p1.x));
758: setParameter("wy", cropFloat(p1.y));
1.3 casties 759: setParameter("ww", cropFloat(ww));
760: setParameter("wh", cropFloat(wh));
761: parseArea();
762: display(3);
763: }
764: }
1.1 dwinter 765: }
766:
1.3 casties 767: function zoomMove(evt) {
768: // mouse move handler
1.4 casties 769: pt2 = evtPosition(evt);
1.3 casties 770: // restrict marks to move right and down
1.4 casties 771: eck1pos = pt1;
772: eck2pos = new Position(Math.max(pt1.x, pt2.x)-12, pt1.y);
773: eck3pos = new Position(pt1.x, Math.max(pt1.y, pt2.y)-12);
774: eck4pos = new Position(Math.max(pt1.x, pt2.x)-12, Math.max(pt1.y, pt2.y)-12);
1.3 casties 775: moveElement("eck1", eck1pos);
776: moveElement("eck2", eck2pos);
777: moveElement("eck3", eck3pos);
778: moveElement("eck4", eck4pos);
1.1 dwinter 779: }
1.4 casties 780:
1.3 casties 781: // starting event capture
782: registerMouseDown("scaler", zoomClick);
783: registerMouseDown("eck4", zoomClick);
1.1 dwinter 784: }
785:
1.3 casties 786: function zoomFullpage() {
787: // zooms out to show the whole image
788: setParameter("wx", 0.0);
789: setParameter("wy", 0.0);
790: setParameter("ww", 1.0);
791: setParameter("wh", 1.0);
792: parseArea();
793: display(3);
1.1 dwinter 794: }
795:
796:
1.3 casties 797: function moveTo() {
1.1 dwinter 798:
1.4 casties 799: if ( (dlArea.width == 1.0) && (dlArea.height == 1.0) ) {
1.3 casties 800: alert("This function is only available when zoomed in!");
801: return;
802: }
1.1 dwinter 803:
1.3 casties 804: function moveToEvent(event) {
805: // move to handler
1.4 casties 806: var pt = evtPosition(evt);
807: var newarea = new Rectangle(pt.x-0.5*dlArea.width, pt.y-0.5*dlArea.height, dlArea.width, dlArea.height);
808: newarea = dlMaxArea.fit(newarea);
1.3 casties 809: // stopping event capture
810: unregisterMouseDown("scaler", moveToEvent);
811: // set parameters
812: setParameter("wx", cropFloat(newarea.x));
813: setParameter("wy", cropFloat(newarea.y));
814: setParameter("ww", cropFloat(newarea.width));
815: setParameter("wh", cropFloat(newarea.height));
1.1 dwinter 816: display(3);
1.3 casties 817: }
1.4 casties 818:
1.3 casties 819: // starting event capture
820: registerMouseDown("scaler", moveToEvent);
1.1 dwinter 821: }
822:
1.3 casties 823: function setSize(factor) {
824: // change the size of the image
825: setParameter("ws", cropFloat(factor));
826: display(3);
827: }
828:
829: function setQuality(qual) {
830: // set the image quality
831: for (var i = 0; i < 3; i++) {
832: removeFlag("q"+i);
833: if (i == qual) {
834: addFlag("q"+i);
1.1 dwinter 835: }
1.3 casties 836: }
837: setParameter("mo", getAllFlags());
838: display(3);
839: }
840:
841: function mirror(dir) {
842: // mirror the image horizontally or vertically
843: if (dir == "h") {
844: toggleFlag("hmir");
1.1 dwinter 845: } else {
1.3 casties 846: toggleFlag("vmir");
1.1 dwinter 847: }
1.3 casties 848: setParameter("mo", getAllFlags());
849: display(3);
1.1 dwinter 850: }
851:
852: function parseKeypress(evt) {
1.3 casties 853: // capturing keypresses for next and previous page
854: if ( document.all ) {
1.1 dwinter 855: if ( event.keyCode == 110 ) {
1.3 casties 856: page('+1');
1.1 dwinter 857: }
858: if ( event.keyCode == 98 ) {
1.3 casties 859: page('-1');
1.1 dwinter 860: }
1.3 casties 861: document.cancelBubble = true;
862: } else {
1.1 dwinter 863: if ( evt.charCode == 110 ) {
1.3 casties 864: page('+1');
865: } else if ( evt.charCode == 98 ) {
866: page('-1');
867: } else if ( evt.which == 110 ) {
868: page('+1');
1.1 dwinter 869: } else if ( evt.which == 98 ) {
1.3 casties 870: // does not work currentlyfor Opera, because it catches the 'b'-key on it's own
871: // have to change the key or find another way - luginbuehl
872: page('-1');
1.1 dwinter 873: }
1.3 casties 874: }
1.1 dwinter 875: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>