Annotation of zogiLib/js/dl_lib.js, revision 1.8
1.1 casties 1: /* Copyright (C) 2003,2004 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: ROC 3.5.2004
18: first version by Christian Luginbuehl, 01.05.2003
19: Changed for digiLib in Zope by DW 24.03.2004
20: */
21:
22:
23: /*
24: * parameter handling
25: */
26:
27: var dlArea = new Rectangle(0.0, 0.0, 1.0, 1.0);
28: var dlMaxArea = new Rectangle(0.0, 0.0, 1.0, 1.0);
29:
30: function parseArea() {
31: // returns area Rectangle from current parameters
32: return new Rectangle(getParameter("wx"), getParameter("wy"), getParameter("ww"), getParameter("wh"));
33: }
34:
35: function setParamFromArea(rect) {
36: // sets digilib wx etc. from rect
37: setParameter("wx", cropFloat(rect.x));
38: setParameter("wy", cropFloat(rect.y));
39: setParameter("ww", cropFloat(rect.width));
40: setParameter("wh", cropFloat(rect.height));
41: return true;
42: }
43:
44: var dlTrafo = new Transform();
45:
1.2 casties 46: function parseTrafo(elem) {
1.1 casties 47: // returns Transform from current dlArea and picsize
1.2 casties 48: var picsize = getElementRect(elem);
1.1 casties 49: var trafo = new Transform();
50: // subtract area offset and size
51: trafo.concat(getTranslation(new Position(-dlArea.x, -dlArea.y)));
52: trafo.concat(getScale(new Size(1/dlArea.width, 1/dlArea.height)));
53: // scale to screen size
54: trafo.concat(getScale(picsize));
55: trafo.concat(getTranslation(picsize));
56: // rotate
57: //trafo.concat(getRotation(- getParameter("rot"), new Position(0.5*picsize.width, 0.5*picsize.height)));
58: // mirror
59: //if (hasFlag("hmir")) {
60: //trafo.m00 = - trafo.m00;
61: //}
62: //if (hasFlag("vmir")) {
63: //trafo.m11 = - trafo.m11;
64: //}
65: return trafo;
66: }
67:
68:
69: var dlMarks = new Array();
70:
71: function parseMarks() {
72: // returns marks array from current parameters
73: var marks = new Array();
1.2 casties 74: var ma;
75: var mk = getParameter("mk");
76: if (mk.indexOf(";") >= 0) {
77: // old format with ";"
78: ma = mk.split(";");
79: } else {
80: ma = mk.split(",");
81: }
1.1 casties 82: for (var i = 0; i < ma.length ; i++) {
83: var pos = ma[i].split("/");
84: if (pos.length > 1) {
85: marks.push(new Position(pos[0], pos[1]));
86: }
87: }
88: return marks;
89: }
90:
91: function getAllMarks() {
92: // returns a string with all marks in query format
93: var marks = new Array();
94: for (var i = 0; i < dlMarks.length; i++) {
95: marks.push(cropFloat(dlMarks[i].x) + "/" + cropFloat(dlMarks[i].y));
96: }
1.2 casties 97: return marks.join(",");
1.1 casties 98: }
99:
100: function addMark(pos) {
101: // add a mark
102: dlMarks.push(pos);
103: setParameter("mk", getAllMarks());
104: return true;
105: }
106:
107: function deleteMark() {
108: // delete the last mark
109: dlMarks.pop();
110: setParameter("mk", getAllMarks());
111: return true;
112: }
113:
114: var dlFlags = new Object();
115:
116: function hasFlag(mode) {
117: // returns if mode flag is set
118: return (dlFlags[mode]);
119: }
120:
121: function addFlag(mode) {
122: // add a mode flag
123: dlFlags[mode] = mode;
124: return true;
125: }
126:
127: function removeFlag(mode) {
128: // remove a mode flag
129: if (dlFlags[mode]) {
130: delete dlFlags[mode];
131: }
132: return true;
133: }
134:
135: function toggleFlag(mode) {
136: // change a mode flag
137: if (dlFlags[mode]) {
138: delete dlFlags[mode];
139: } else {
140: dlFlags[mode] = mode;
141: }
142: return true;
143: }
144:
145: function getAllFlags() {
146: // returns a string with all flags in query format
147: var fa = new Array();
148: for (var f in dlFlags) {
149: if ((f != "")&&(dlFlags[f] != null)) {
150: fa.push(f);
151: }
152: }
153: return fa.join(",");
154: }
155:
156: function parseFlags() {
157: // sets dlFlags from the current parameters
158: var flags = new Object();
159: var fa = getParameter("mo").split(",");
160: for (var i = 0; i < fa.length ; i++) {
161: var f = fa[i];
162: if (f != "") {
163: flags[f] = f;
164: }
165: }
166: return flags;
167: }
168:
169:
1.2 casties 170: function bestPicSize(elem, inset) {
171: // returns a Size with the best image size for the given element
172: if (! defined(inset)) {
173: inset = 25;
174: }
1.1 casties 175: var ws = getWinSize();
1.2 casties 176: var es = getElementPosition(elem);
1.1 casties 177: if (es) {
178: ws.width = ws.width - es.x - inset;
179: ws.height = ws.height - es.y - inset;
180: }
181: return ws;
182: }
183:
184:
185: /* **********************************************
186: * digilib specific routines
187: * ******************************************** */
188:
1.2 casties 189: var elemScaler = null;
190: var picElem = null;
191:
192: function dl_init() {
1.7 casties 193: elemScaler = getElement("scaler", true);
1.2 casties 194: picElem = getElement("pic", true);
1.7 casties 195: if (picElem == null && elemScaler) {
1.4 casties 196: // in N4 pic is in the scaler layer
1.2 casties 197: picElem = elemScaler.document.images[0];
1.6 casties 198: }
199: if ((!elemScaler)||(!picElem)) {
200: alert("Sorry, zogilib doesn't work here!");
201: return false;
1.2 casties 202: }
203: // give a name to the window containing digilib
1.8 ! casties 204: if (dlTarget) {
! 205: window.name = dlTarget;
! 206: } else {
! 207: window.name = "digilib";
! 208: }
1.2 casties 209: // put the query parameters (sans "?") in the parameters array
1.1 casties 210: parseParameters(location.search.slice(1));
211: // treat special parameters
212: dlMarks = parseMarks();
213: dlArea = parseArea();
214: dlFlags = parseFlags();
1.2 casties 215: // wait for image to load and display marks
1.1 casties 216: renderMarks();
1.2 casties 217: // done
1.1 casties 218: focus();
1.4 casties 219: return;
1.1 casties 220: }
221:
222: function display(detail) {
223: // redisplay the page
1.2 casties 224: if (! detail) {
225: detail = 9;
226: }
1.1 casties 227: var queryString = getAllParameters(detail);
228: location.href = location.protocol + "//" + location.host + location.pathname + "?" + queryString;
229: }
230:
1.2 casties 231: function openWin(url, title, params) {
232: // open browser window
233: var ow = window.open(url, title, params);
234: ow.focus();
235: }
1.1 casties 236:
237: /* **********************************************
238: * interactive digilib functions
239: * ******************************************** */
240:
1.2 casties 241: function getRef(select) {
1.1 casties 242: // open a dialog with a reference to the current digilib set
1.3 casties 243: if (! baseUrl) {
244: var baseUrl = location.protocol + "//" + location.host + location.pathname;
245: }
246: var hyperlinkRef = baseUrl;
247: var par = getAllParameters(9);
248: if (par.length > 0) {
249: hyperlinkRef += "?" + par;
250: }
1.1 casties 251: if ( select == 0 ) {
252: prompt("Link for LaTeX-documents", "\\href{" + hyperlinkRef + "}{TEXT}");
253: } else if ( select == 1 ) {
254: prompt("Link for HTML-documents", hyperlinkRef);
255: }
256: }
257:
258: function renderMarks() {
259: // put the visible marks on the image
260: var mark_count = dlMarks.length;
261: // make shure the image is loaded so we know its size
1.2 casties 262: if (defined(picElem.complete) && picElem.complete == false && ! browserType.isN4 ) {
263: setTimeout("renderMarks()", 100);
1.1 casties 264: } else {
1.2 casties 265: dlTrafo = parseTrafo(picElem);
1.1 casties 266: for (var i = 0; i < 8; i++) {
1.2 casties 267: var me = getElement("dot"+i);
1.1 casties 268: if (i < mark_count) {
269: if (dlArea.containsPosition(dlMarks[i])) {
270: var mpos = dlTrafo.transform(dlMarks[i]);
271: // suboptimal to place -5 pixels and not half size of mark-image
272: mpos.x = mpos.x -5;
273: mpos.y = mpos.y -5;
1.2 casties 274: moveElement(me, mpos);
275: showElement(me, true);
1.1 casties 276: }
277: } else {
278: // hide the other marks
1.2 casties 279: showElement(me, false);
1.1 casties 280: }
281: }
282: }
283: }
284:
1.2 casties 285: function setMark() {
1.1 casties 286: // add a mark where clicked
287: if ( dlMarks.length > 7 ) {
288: alert("Only 8 marks are possible at the moment!");
289: return;
290: }
291:
292: function markEvent(evt) {
1.4 casties 293: // event handler adding a new mark
294: unregisterMouseDown(elemScaler, markEvent);
1.1 casties 295: var p = dlTrafo.invtransform(evtPosition(evt));
296: addMark(p);
1.2 casties 297: display();
1.1 casties 298: }
299:
300: // starting event capture
1.2 casties 301: registerMouseDown(elemScaler, markEvent);
1.1 casties 302: }
303:
304: var ZOOMFACTOR = Math.sqrt(2);
305:
306: function zoomPoint(inout) {
307: // zoom image in or out around the clicked point
308: var zoom = ZOOMFACTOR;
309: if (inout < 0) {
310: zoom = 1/ZOOMFACTOR;
311: }
312: window.focus();
313:
314: function zoomPointEvent(evt) {
315: // take new center and set zoom parameters
1.4 casties 316: unregisterMouseDown(elemScaler, zoomPointEvent);
1.1 casties 317: var p = dlTrafo.invtransform(evtPosition(evt));
318: var neww = Math.min(dlArea.width * (1/zoom), 1.0);
319: var newh = Math.min(dlArea.height * (1/zoom), 1.0);
320: var newx = p.x - 0.5 * neww;
321: var newy = p.y - 0.5 * newh;
322: var zoomarea = new Rectangle(newx, newy, neww, newh);
323: // check bounds
324: zoomarea = dlMaxArea.fit(zoomarea);
325: // set parameters
326: setParamFromArea(zoomarea);
327: parseArea();
1.2 casties 328: // zoomed is always fit
329: setParameter("ws", 1);
330: display();
1.1 casties 331: }
332:
333: // starting event capture
1.2 casties 334: registerMouseDown(elemScaler, zoomPointEvent);
1.1 casties 335: }
336:
337:
338: function zoomArea() {
339: var click = 1;
340: var pt1, pt2;
341: var eck1pos, eck2pos, eck3pos, eck4pos;
342: window.focus();
1.2 casties 343: var eck1 = getElement("eck1");
344: var eck2 = getElement("eck2");
345: var eck3 = getElement("eck3");
346: var eck4 = getElement("eck4");
1.1 casties 347:
348: function zoomClick(evt) {
349: // mouse click handler
350: if (click == 1) {
351: // first click -- start moving
352: click = 2;
353: pt1 = evtPosition(evt);
354: pt2 = pt1;
355: eck1pos = pt1;
356: eck2pos = new Position(pt1.x - 12, pt1.y);
357: eck3pos = new Position(pt1.x, pt1.y - 12);
358: eck4pos = new Position(pt1.y - 12, pt1.y - 12);
1.2 casties 359: moveElement(eck1, eck1pos);
360: moveElement(eck2, eck2pos);
361: moveElement(eck3, eck3pos);
362: moveElement(eck4, eck4pos);
363: showElement(eck1, true);
364: showElement(eck2, true);
365: showElement(eck3, true);
366: showElement(eck4, true);
367: registerMouseMove(elemScaler, zoomMove);
368: registerMouseMove(eck4, zoomMove);
1.1 casties 369: } else {
370: // second click -- end moving
371: pt2 = evtPosition(evt);
1.2 casties 372: showElement(eck1, false);
373: showElement(eck2, false);
374: showElement(eck3, false);
375: showElement(eck4, false);
376: unregisterMouseMove(elemScaler, zoomMove);
377: unregisterMouseMove(eck4, zoomMove);
378: unregisterMouseDown(elemScaler, zoomClick);
379: unregisterMouseDown(eck4, zoomClick);
1.1 casties 380: var p1 = dlTrafo.invtransform(pt1);
381: var p2 = dlTrafo.invtransform(pt2);
382: var ww = p2.x-p1.x;
383: var wh = p2.y-p1.y;
384: if ((ww > 0)&&(wh > 0)) {
385: setParameter("wx", cropFloat(p1.x));
386: setParameter("wy", cropFloat(p1.y));
387: setParameter("ww", cropFloat(ww));
388: setParameter("wh", cropFloat(wh));
389: parseArea();
1.2 casties 390: // zoomed is always fit
391: setParameter("ws", 1);
392: display();
1.1 casties 393: }
394: }
395: }
396:
397: function zoomMove(evt) {
398: // mouse move handler
399: pt2 = evtPosition(evt);
400: // restrict marks to move right and down
401: eck1pos = pt1;
402: eck2pos = new Position(Math.max(pt1.x, pt2.x)-12, pt1.y);
403: eck3pos = new Position(pt1.x, Math.max(pt1.y, pt2.y)-12);
404: eck4pos = new Position(Math.max(pt1.x, pt2.x)-12, Math.max(pt1.y, pt2.y)-12);
1.2 casties 405: moveElement(eck1, eck1pos);
406: moveElement(eck2, eck2pos);
407: moveElement(eck3, eck3pos);
408: moveElement(eck4, eck4pos);
1.1 casties 409: }
410:
411: // starting event capture
1.2 casties 412: registerMouseDown(elemScaler, zoomClick);
413: registerMouseDown(eck4, zoomClick);
1.1 casties 414: }
415:
416:
1.4 casties 417: function moveCenter() {
418: // move visible area so that it's centered around the clicked point
1.1 casties 419: if ( (dlArea.width == 1.0) && (dlArea.height == 1.0) ) {
1.4 casties 420: // noting to do
1.1 casties 421: return;
422: }
1.4 casties 423: window.focus();
1.1 casties 424:
1.4 casties 425: function moveCenterEvent(evt) {
1.1 casties 426: // move to handler
1.4 casties 427: unregisterMouseDown(elemScaler, moveCenterEvent);
428: var pt = dlTrafo.invtransform(evtPosition(evt));
1.1 casties 429: var newarea = new Rectangle(pt.x-0.5*dlArea.width, pt.y-0.5*dlArea.height, dlArea.width, dlArea.height);
430: newarea = dlMaxArea.fit(newarea);
431: // set parameters
1.4 casties 432: setParamFromArea(newarea);
433: parseArea();
1.2 casties 434: display();
1.1 casties 435: }
436:
437: // starting event capture
1.4 casties 438: registerMouseDown(elemScaler, moveCenterEvent);
1.1 casties 439: }
440:
441:
1.2 casties 442: // debuggin'
443: function showcoordsN4() {
444: var s = "";
445: for (var l in document.layers) {
446: if (l == "length") continue;
447: e = document.layers[l];
448: if (e) {
449: s += " [" + e.name + "]: pageX:" + e.pageX + " pageY:" + e.pageY + " width:" + e.clip.width + " height:" + e.clip.height + " visibility:" + e.visibility + " zindex:" + e.zIndex + "<br>\n";
450: } else {
451: s += " {" + l + "}<br>\n";
1.1 casties 452: }
453: }
1.2 casties 454: return s;
455: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>