Annotation of zogiLib/js/navigation.js, revision 1.4
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.4 ! casties 391: alert("no document.all!");
1.3 casties 392: return document[tagid];
393: }
394: }
1.1 dwinter 395:
1.3 casties 396: function getElementSize(tagid) {
397: // returns a Rectangle with the size and position of the named element
398: var x = 0;
399: var y = 0;
400: var width = 0;
401: var height = 0;
402: var elem = getElement(tagid);
1.4 ! casties 403: if (elem.left) {
! 404: alert("elem.left!");
! 405: x = elem.left;
! 406: y = elem.top;
! 407: width = elem.width;
! 408: height = elem.height;
! 409: } else {
! 410: if (elem.clientLeft) {
! 411: // spass mit IE
! 412: x = elem.clientLeft;
! 413: y = elem.clientTop;
! 414: } else {
! 415: var e = elem;
! 416: while (e) {
! 417: x += e.offsetLeft;
! 418: y += e.offsetTop;
! 419: e = e.offsetParent;
! 420: }
! 421: }
! 422: width = elem.offsetWidth;
! 423: height = elem.offsetHeight;
1.3 casties 424: }
425: return new Rectangle(x, y, width, height);
426: }
1.1 dwinter 427:
1.3 casties 428: function moveElement(tagid, pos) {
429: // moves the named element to the indicated position
430: var elem = getElement(tagid);
431: if (elem.style) {
1.4 ! casties 432: elem.style.left = pos.x + "px";
! 433: elem.style.top = pos.y + "px";
1.3 casties 434: } else {
435: alert("moveelement: no style property!");
1.4 ! casties 436: elem.left = pos.x;
! 437: elem.top = pos.y;
1.3 casties 438: }
1.4 ! casties 439: return true;
1.3 casties 440: }
1.1 dwinter 441:
1.3 casties 442: function showElement(tagid, show) {
443: // shows or hides the named element
444: var elem = getElement(tagid);
445: if (elem.style) {
446: if (show) {
447: elem.style.visibility = "visible";
448: } else {
449: elem.style.visibility = "hidden";
450: }
451: } else {
452: alert("showelement: no style property!");
453: }
1.4 ! casties 454: return true;
1.3 casties 455: }
1.1 dwinter 456:
1.3 casties 457: function registerMouseDown(tagid, handler) {
458: // register a mouse down event handler on the indicated element
459: if ( document.all ) {
460: document.all[tagid].onmousedown = handler;
461: } else if (document.getElementById) {
462: document.getElementById(tagid).addEventListener("mousedown", handler, true);
463: } else {
464: document[tagid].captureEvents(Event.MOUSEDOWN);
465: document[tagid].onmousedown = handler;
466: }
1.4 ! casties 467: return true;
1.3 casties 468: }
1.1 dwinter 469:
1.3 casties 470: function unregisterMouseDown(tagid, handler) {
471: // unregister the mouse down event handler
472: if ( document.all ) {
473: document.all[tagid].onmousedown = null;
474: } else if (document.getElementById) {
475: document.getElementById(tagid).removeEventListener("mousedown", handler, true);
476: } else {
477: document[tagid].releaseEvents(Event.MOUSEDOWN);
478: }
1.4 ! casties 479: return true;
1.1 dwinter 480: }
481:
1.3 casties 482: function registerMouseMove(tagid, handler) {
483: // register a mouse move event handler on the indicated element
484: if ( document.all ) {
485: document.all[tagid].onmousemove = handler;
486: } else if (document.getElementById) {
487: document.getElementById(tagid).addEventListener("mousemove", handler, true);
488: } else {
489: document[tagid].captureEvents(Event.MOUSEMOVE);
490: document[tagid].onmousemove = handler;
491: }
1.4 ! casties 492: return true;
1.3 casties 493: }
1.1 dwinter 494:
1.3 casties 495: function unregisterMouseMove(tagid, handler) {
496: // unregister the mouse move event handler
497: if ( document.all ) {
498: document.all[tagid].onmousemove = null;
499: } else if (document.getElementById) {
500: document.getElementById(tagid).removeEventListener("mousemove", handler, true);
501: } else {
502: document[tagid].releaseEvents(Event.MOUSEMOVE);
503: }
1.4 ! casties 504: return true;
1.3 casties 505: }
1.1 dwinter 506:
1.3 casties 507: function registerKeyDown(handler) {
508: // register a key down handler
509: if ( document.all ) {
510: this.document.onkeypress = handler
511: } else if ( typeof(document.addEventListener) == "function" ) {
512: this.document.addEventListener('keypress', handler, true);
513: } else {
514: window.captureEvents(Event.KEYDOWN);
515: window.onkeydown = handler;
516: }
1.4 ! casties 517: return true;
1.3 casties 518: }
1.1 dwinter 519:
1.3 casties 520: function getWinSize() {
521: // returns a Size with the current window size (from www.quirksmode.org)
522: var wsize = new Size(100, 100);
523: if (self.innerHeight) {
524: // all except Explorer
525: wsize.width = self.innerWidth;
526: wsize.height = self.innerHeight;
527: } else if (document.documentElement && document.documentElement.clientHeight) {
528: // Explorer 6 Strict Mode
529: wsize.width = document.documentElement.clientWidth;
530: wsize.height = document.documentElement.clientHeight;
531: } else if (document.body) {
532: // other Explorers
533: wsize.width = document.body.clientWidth;
534: wsize.height = document.body.clientHeight;
535: }
536: return wsize;
537: }
1.1 dwinter 538:
1.3 casties 539: function bestPicSize(tagid) {
540: // returns a Size with the best image size for the given tagid
1.4 ! casties 541: var inset = 0;
! 542: var ws = getWinSize();
! 543: var es = getElementSize(tagid);
! 544: ws.width = ws.width - es.x - inset;
! 545: ws.height = ws.height - es.y - inset;
! 546: return ws;
1.1 dwinter 547: }
548:
549:
550:
1.3 casties 551: function init() {
552: // give a name to the window containing digilib - this way one can test if there is already a
553: // digilib-window open and replace the contents of it (ex. digicat)
554: top.window.name = "digilib";
555: // put the query parameters (sans "&") in the parameters array
556: parseParameters(location.search.slice(1));
557: // treat special parameters
558: dlMarks = parseMarks();
559: dlArea = parseArea();
560: dlFlags = parseFlags();
1.1 dwinter 561:
1.3 casties 562: //registerKeyDown(parseKeypress);
563:
564: placeMarks();
1.1 dwinter 565:
1.3 casties 566: focus();
567: return true;
568: }
1.1 dwinter 569:
570:
1.3 casties 571: function display(detail) {
572: // redisplay the page
573: var queryString = getAllParameters(detail);
574: location.href = location.protocol + "//" + location.host + location.pathname + "?" + queryString;
575: }
1.1 dwinter 576:
577:
578:
579: function page(page, details) {
580:
581: if ( details == null ) {
582: details = 1;
583: }
584:
585: if ( page.indexOf('-') == 0 ) {
586: if ( dlParams.pn.value > 1 ) {
587: page = Math.max(parseInt(dlParams.pn.value) - parseInt(page.slice(1)), 1);
588: dlParams.pn.value = page;
589: display(details);
590: } else {
591: alert("You are already on the first page!");
592: }
593:
594: } else if ( page.indexOf('+') == 0 ) {
595: page = parseInt(dlParams.pn.value) + parseInt(page.slice(1));
596: dlParams.pn.value = page;
597: display(details);
598: } else if ( page == parseInt(page) ) {
599: dlParams.pn.value = parseInt(page);
600: display(details);
601: }
602:
603: }
604:
605:
606:
607: function ref(select) {
1.3 casties 608: // open a dialog with a reference to the current digilib set
609: var hyperlinkRef = baseUrl + "?" + getAllParameters(9);
610: if ( select == 0 ) {
611: prompt("Link for LaTeX-documents", "\\href{" + hyperlinkRef + "}{TEXT}");
612: } else if ( select == 1 ) {
613: prompt("Link for HTML-documents", hyperlinkRef);
614: }
1.1 dwinter 615: }
616:
617:
618: function mark() {
1.3 casties 619: // add a mark where clicked
620: if ( dlMarks.length > 7 ) {
621: alert("Only 8 marks are possible at the moment!");
622: return;
623: }
1.1 dwinter 624:
1.3 casties 625: function markEvent(evt) {
626: // event handler adding a new mark
627: unregisterMouseDown("scaler", markEvent);
1.4 ! casties 628: var p = dlTrafo.invtransform(evtPosition(evt));
! 629: addMark(p);
1.3 casties 630: placeMarks();
631: }
1.1 dwinter 632:
1.3 casties 633: // starting event capture
634: registerMouseDown("scaler", markEvent);
635: }
1.1 dwinter 636:
1.3 casties 637: function unmark() {
638: // remove the last mark
639: deleteMark();
1.1 dwinter 640: placeMarks();
641: }
642:
643: function placeMarks() {
1.3 casties 644: // put the visible marks on the image
645: var mark_count = dlMarks.length;
646: var picelem = getElement("pic");
647: // make shure the image is loaded so we know its size
648: if (picelem && picelem.complete == false) {
649: setTimeout("placeMarks()", 100);
650: } else {
1.4 ! casties 651: var picsize = getElementSize("pic");
1.3 casties 652: dlTrafo = parseTrafo();
653: for (var i = 0; i < 8; i++) {
654: if (i < mark_count) {
655: if (dlArea.containsPosition(dlMarks[i])) {
656: var mpos = dlTrafo.transform(dlMarks[i]);
657: // suboptimal to place -5 pixels and not half size of mark-image
1.4 ! casties 658: mpos.x = mpos.x -5;
! 659: mpos.y = mpos.y -5;
1.3 casties 660: moveElement("dot"+i, mpos);
661: showElement("dot"+i, true);
1.1 dwinter 662: }
1.3 casties 663: } else {
664: // hide the other marks
665: showElement("dot"+i, false);
666: }
1.1 dwinter 667: }
1.3 casties 668: }
1.1 dwinter 669: }
670:
671:
1.3 casties 672: function zoomPoint(inout) {
673: // zoom image in or out around the clicked point
674: var zoom = ZOOMFACTOR;
675: if (inout < 0) {
676: zoom = 1/ZOOMFACTOR;
677: }
1.4 ! casties 678: window.focus();
1.1 dwinter 679:
1.3 casties 680: function zoomPointEvent(evt) {
681: // take new center and set zoom parameters
1.4 ! casties 682: var p = dlTrafo.invtransform(evtPosition(evt));
1.3 casties 683: var neww = Math.min(dlArea.width * (1/zoom), 1.0);
684: var newh = Math.min(dlArea.height * (1/zoom), 1.0);
1.4 ! casties 685: var newx = p.x - 0.5 * neww;
! 686: var newy = p.y - 0.5 * newh;
1.3 casties 687: var zoomarea = new Rectangle(newx, newy, neww, newh);
688: // check bounds
689: zoomarea = dlMaxArea.fit(zoomarea);
690: // set parameters
691: setParameter("wx", cropFloat(zoomarea.x));
692: setParameter("wy", cropFloat(zoomarea.y));
693: setParameter("ww", cropFloat(zoomarea.width));
694: setParameter("wh", cropFloat(zoomarea.height));
695: parseArea();
696: display(3);
1.1 dwinter 697: }
1.4 ! casties 698:
1.3 casties 699: // starting event capture
700: registerMouseDown("scaler", zoomPointEvent);
1.1 dwinter 701: }
702:
703:
704: function zoomArea() {
1.3 casties 705: var click = 1;
706: var pt1, pt2;
707: var eck1pos, eck2pos, eck3pos, eck4pos;
708: window.focus();
709:
710: function zoomClick(evt) {
711: // mouse click handler
712: if (click == 1) {
713: // first click -- start moving
714: click = 2;
1.4 ! casties 715: pt1 = evtPosition(evt);
1.3 casties 716: pt2 = pt1;
1.4 ! casties 717: eck1pos = pt1;
! 718: eck2pos = new Position(pt1.x - 12, pt1.y);
! 719: eck3pos = new Position(pt1.x, pt1.y - 12);
! 720: eck4pos = new Position(pt1.y - 12, pt1.y - 12);
1.3 casties 721: moveElement("eck1", eck1pos);
722: moveElement("eck2", eck2pos);
723: moveElement("eck3", eck3pos);
724: moveElement("eck4", eck4pos);
725: showElement("eck1", true);
726: showElement("eck2", true);
727: showElement("eck3", true);
728: showElement("eck4", true);
729: registerMouseMove("scaler", zoomMove);
730: registerMouseMove("eck4", zoomMove);
731: } else {
732: // second click -- end moving
1.4 ! casties 733: pt2 = evtPosition(evt);
1.3 casties 734: showElement("eck1", false);
735: showElement("eck2", false);
736: showElement("eck3", false);
737: showElement("eck4", false);
738: unregisterMouseMove("scaler", zoomMove);
739: unregisterMouseMove("eck4", zoomMove);
740: unregisterMouseDown("scaler", zoomClick);
741: unregisterMouseDown("eck4", zoomClick);
1.4 ! casties 742: var p1 = dlTrafo.invtransform(pt1);
! 743: var p2 = dlTrafo.invtransform(pt2);
! 744: var ww = p2.x-p1.x;
! 745: var wh = p2.y-p1.y;
1.3 casties 746: if ((ww > 0)&&(wh > 0)) {
1.4 ! casties 747: setParameter("wx", cropFloat(p1.x));
! 748: setParameter("wy", cropFloat(p1.y));
1.3 casties 749: setParameter("ww", cropFloat(ww));
750: setParameter("wh", cropFloat(wh));
751: parseArea();
752: display(3);
753: }
754: }
1.1 dwinter 755: }
756:
1.3 casties 757: function zoomMove(evt) {
758: // mouse move handler
1.4 ! casties 759: pt2 = evtPosition(evt);
1.3 casties 760: // restrict marks to move right and down
1.4 ! casties 761: eck1pos = pt1;
! 762: eck2pos = new Position(Math.max(pt1.x, pt2.x)-12, pt1.y);
! 763: eck3pos = new Position(pt1.x, Math.max(pt1.y, pt2.y)-12);
! 764: eck4pos = new Position(Math.max(pt1.x, pt2.x)-12, Math.max(pt1.y, pt2.y)-12);
1.3 casties 765: moveElement("eck1", eck1pos);
766: moveElement("eck2", eck2pos);
767: moveElement("eck3", eck3pos);
768: moveElement("eck4", eck4pos);
1.1 dwinter 769: }
1.4 ! casties 770:
1.3 casties 771: // starting event capture
772: registerMouseDown("scaler", zoomClick);
773: registerMouseDown("eck4", zoomClick);
1.1 dwinter 774: }
775:
1.3 casties 776: function zoomFullpage() {
777: // zooms out to show the whole image
778: setParameter("wx", 0.0);
779: setParameter("wy", 0.0);
780: setParameter("ww", 1.0);
781: setParameter("wh", 1.0);
782: parseArea();
783: display(3);
1.1 dwinter 784: }
785:
786:
1.3 casties 787: function moveTo() {
1.1 dwinter 788:
1.4 ! casties 789: if ( (dlArea.width == 1.0) && (dlArea.height == 1.0) ) {
1.3 casties 790: alert("This function is only available when zoomed in!");
791: return;
792: }
1.1 dwinter 793:
1.3 casties 794: function moveToEvent(event) {
795: // move to handler
1.4 ! casties 796: var pt = evtPosition(evt);
! 797: var newarea = new Rectangle(pt.x-0.5*dlArea.width, pt.y-0.5*dlArea.height, dlArea.width, dlArea.height);
! 798: newarea = dlMaxArea.fit(newarea);
1.3 casties 799: // stopping event capture
800: unregisterMouseDown("scaler", moveToEvent);
801: // set parameters
802: setParameter("wx", cropFloat(newarea.x));
803: setParameter("wy", cropFloat(newarea.y));
804: setParameter("ww", cropFloat(newarea.width));
805: setParameter("wh", cropFloat(newarea.height));
1.1 dwinter 806: display(3);
1.3 casties 807: }
1.4 ! casties 808:
1.3 casties 809: // starting event capture
810: registerMouseDown("scaler", moveToEvent);
1.1 dwinter 811: }
812:
1.3 casties 813: function setSize(factor) {
814: // change the size of the image
815: setParameter("ws", cropFloat(factor));
816: display(3);
817: }
818:
819: function setQuality(qual) {
820: // set the image quality
821: for (var i = 0; i < 3; i++) {
822: removeFlag("q"+i);
823: if (i == qual) {
824: addFlag("q"+i);
1.1 dwinter 825: }
1.3 casties 826: }
827: setParameter("mo", getAllFlags());
828: display(3);
829: }
830:
831: function mirror(dir) {
832: // mirror the image horizontally or vertically
833: if (dir == "h") {
834: toggleFlag("hmir");
1.1 dwinter 835: } else {
1.3 casties 836: toggleFlag("vmir");
1.1 dwinter 837: }
1.3 casties 838: setParameter("mo", getAllFlags());
839: display(3);
1.1 dwinter 840: }
841:
842: function parseKeypress(evt) {
1.3 casties 843: // capturing keypresses for next and previous page
844: if ( document.all ) {
1.1 dwinter 845: if ( event.keyCode == 110 ) {
1.3 casties 846: page('+1');
1.1 dwinter 847: }
848: if ( event.keyCode == 98 ) {
1.3 casties 849: page('-1');
1.1 dwinter 850: }
1.3 casties 851: document.cancelBubble = true;
852: } else {
1.1 dwinter 853: if ( evt.charCode == 110 ) {
1.3 casties 854: page('+1');
855: } else if ( evt.charCode == 98 ) {
856: page('-1');
857: } else if ( evt.which == 110 ) {
858: page('+1');
1.1 dwinter 859: } else if ( evt.which == 98 ) {
1.3 casties 860: // does not work currentlyfor Opera, because it catches the 'b'-key on it's own
861: // have to change the key or find another way - luginbuehl
862: page('-1');
1.1 dwinter 863: }
1.3 casties 864: }
1.1 dwinter 865: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>