source: main/trunk/greenstone3/web/interfaces/default_old/js/documentbasket/mojomagnify.js@ 29861

Last change on this file since 29861 was 29861, checked in by Georgiy Litvinov, 9 years ago

renamed interfaces

  • Property svn:executable set to *
File size: 10.5 KB
Line 
1/*
2 * MojoMagnify 0.1.10 - JavaScript Image Magnifier
3 * Copyright (c) 2008-2010 Jacob Seidelin, [email protected], http://blog.nihilogic.dk/
4 * Licensed under the MPL License [http://www.nihilogic.dk/licenses/mpl-license.txt]
5 */
6
7
8var MojoMagnify = (function() {
9
10 var $ = function(id) {return document.getElementById(id);};
11 var dc = function(tag) {return document.createElement(tag);};
12
13 var isIE = !!document.all && !!window.attachEvent && !window.opera;
14
15 function addEvent(element, ev, handler)
16 {
17 if (element.addEventListener) {
18 element.addEventListener(ev, handler, false);
19 } else if (element.attachEvent) {
20 element.attachEvent("on" + ev, handler);
21 }
22 }
23
24 function removeEvent(element, ev, handler) {
25 if (element.removeEventListener) {
26 element.removeEventListener(ev, handler, false);
27 } else if (element.detachEvent) {
28 element.detachEvent("on" + ev, handler);
29 }
30 }
31
32
33 function getElementPos(element)
34 {
35 var x = element.offsetLeft;
36 var y = element.offsetTop;
37 var parent = element.offsetParent;
38 while (parent) {
39 x += parent.offsetLeft - parent.scrollLeft;
40 y += parent.offsetTop - parent.scrollTop;
41 parent = parent.offsetParent;
42 }
43 return {
44 x : x,
45 y : y
46 }
47 }
48
49 function getEventMousePos(element, e) {
50 var scrollX = document.body.scrollLeft || document.documentElement.scrollLeft;
51 var scrollY = document.body.scrollTop || document.documentElement.scrollTop;
52
53 if (e.currentTarget) {
54 var pos = getElementPos(element);
55 return {
56 x : e.clientX - pos.x + scrollX,
57 y : e.clientY - pos.y + scrollY
58 }
59 }
60 return {
61 x : e.offsetX,
62 y : e.offsetY
63 }
64 }
65
66 function setZoomPos(img, x, y, pos) {
67 var zoomImg = img.__mojoMagnifyImage;
68 if (!zoomImg) return;
69
70 var full = img.__mojoMagnifyOptions.full;
71
72 img.__mojoMagnifyX = x;
73 img.__mojoMagnifyY = y;
74 img.__mojoMagnifyPos = pos;
75
76 var zoom = img.__mojoMagnifyZoomer;
77
78 var maskWidth = zoom.offsetWidth;
79 var maskHeight = zoom.offsetHeight;
80
81 var imgLeft = img.offsetLeft;
82 var imgTop = img.offsetTop;
83
84 var w = img.offsetWidth ? img.offsetWidth : img.naturalWidth;
85 var h = img.offsetHeight ? img.offsetHeight : img.naturalHeight;
86
87 if (full) {
88 var fx = x / w;
89 var fy = y / h;
90
91 var dw = maskWidth - w;
92 var dh = maskHeight - h;
93
94 var left = -dw * fx;
95 var top = -dh * fy;
96 } else {
97 var left = pos.x - maskWidth/2;
98 var top = pos.y - maskHeight/2;
99
100 if (!isIE) {
101 left -= imgLeft;
102 top -= imgTop;
103 }
104 }
105
106 zoom.style.left = left + "px";
107 zoom.style.top = top + "px";
108
109 var zoomWidth = zoomImg.offsetWidth ? zoomImg.offsetWidth : zoomImg.naturalWidth;
110 var zoomHeight = zoomImg.offsetHeight ? zoomImg.offsetHeight : zoomImg.naturalHeight;
111
112 if (full) {
113 var zx = 0;
114 var zy = 0;
115 } else {
116 var zoomXRatio = zoomWidth / w;
117 var zoomYRatio = zoomHeight / h;
118
119 var zoomX = Math.round(x * zoomXRatio);
120 var zoomY = Math.round(y * zoomYRatio);
121
122 var zx = -zoomX + maskWidth/2;
123 var zy = -zoomY + maskHeight/2;
124 }
125
126 zoomImg.style.left = zx + "px";
127 zoomImg.style.top = zy + "px";
128 }
129
130 function startAnimation(img) {
131 var options = img.__mojoMagnifyOptions;
132
133 if (img.__mojoMagnifyAnimTimer)
134 clearTimeout(img.__mojoMagnifyAnimTimer);
135 var step = 1;
136
137 var zoom = img.__mojoMagnifyZoomer;
138 var zoomImg = img.__mojoMagnifyImage;
139 var zoomBorder = img.__mojoMagnifyBorder;
140
141 var imgWidth = img.offsetWidth ? img.offsetWidth : img.naturalWidth;
142 var imgHeight = img.offsetHeight ? img.offsetHeight : img.naturalHeight;
143
144 var dw = img.__mojoMagnifyWidth - imgWidth;
145 var dh = img.__mojoMagnifyHeight - imgHeight;
146
147 var next = function() {
148 var w = imgWidth + dw * (step/10);
149 var h = imgHeight + dh * (step/10);
150
151 zoomBorder.style.width = w + "px";
152 zoomBorder.style.height = h + "px";
153 zoom.style.width = w + "px";
154 zoom.style.height = h + "px";
155 zoomImg.style.width = w + "px";
156 zoomImg.style.height = h + "px";
157
158 if (img.__mojoMagnifyPos) {
159 setZoomPos(img, img.__mojoMagnifyX, img.__mojoMagnifyY, img.__mojoMagnifyPos);
160 }
161
162 if (step < 10) {
163
164 step += 1;
165 img.__mojoMagnifyAnimTimer = setTimeout(next, 60);
166 } else {
167 img.__mojoMagnifyAnimTimer = 0;
168 }
169 }
170 next();
171 }
172
173
174 function makeMagnifiable(img, zoomSrc, opt) {
175 // just set the new zoom src if this img already has the Mojo structure setup
176 if (img.__mojoMagnifyImage) {
177 img.__mojoMagnifyImage.src = zoomSrc;
178 return;
179 }
180
181 var options = opt || {};
182
183 img.__mojoMagnifyOptions = options;
184
185 // make sure the image is loaded, if not then add an onload event and return
186 if (!img.complete && !img.__mojoMagnifyQueued) {
187 addEvent(img, "load", function() {
188 img.__mojoMagnifyQueued = true;
189 setTimeout(function() {
190 makeMagnifiable(img, zoomSrc);
191 }, 1);
192 });
193 return;
194 }
195
196 var w = img.offsetWidth ? img.offsetWidth : img.naturalWidth;
197 var h = img.offsetHeight ? img.offsetHeight : img.naturalHeight;
198
199 var oldParent = img.parentNode;
200 if (oldParent.nodeName.toLowerCase() != "a") {
201 var linkParent = dc("a");
202 linkParent.setAttribute("href", zoomSrc);
203 oldParent.replaceChild(linkParent, img);
204 linkParent.appendChild(img);
205 } else {
206 var linkParent = oldParent;
207 }
208
209 linkParent.style.position = "relative";
210 linkParent.style.display = "block";
211 linkParent.style.width = w+"px";
212 linkParent.style.height = h+"px";
213
214 var imgLeft = img.offsetLeft;
215 var imgTop = img.offsetTop;
216
217 var zoom = dc("div");
218 zoom.className = "mojomagnify_zoom";
219 zoom.style.left = "-9999px";
220
221 var parent = img.parentNode;
222 var zoomImg = dc("img");
223 zoomImg.className = "mojomagnify_img";
224 zoomImg.style.position = "absolute";
225 zoomImg.style.maxWidth = "none";
226 zoomImg.style.maxHeight = "none";
227
228 if (isIE) {
229 // IE won't let the mouse click pass through properly to the link,
230 // so we clone the link and use it for the zoom image as well. Do for all browsers, perhaps?
231 var zoomLink = dc("a");
232 zoomLink.setAttribute("href", linkParent.getAttribute("href"));
233 zoomLink.setAttribute("onclick", linkParent.getAttribute("onclick"));
234 zoomLink.style.position = "absolute";
235 zoomLink.style.left = "0px";
236 zoomLink.style.top = "0px";
237 zoomLink.appendChild(zoomImg);
238 zoom.appendChild(zoomLink);
239 } else {
240 zoom.appendChild(zoomImg);
241 }
242
243 var ctr = dc("div");
244 with (ctr.style) {
245 position = "absolute";
246 left = imgLeft+"px";
247 top = imgTop+"px";
248 width = w+"px";
249 height = h+"px";
250 overflow = "hidden";
251 display = "block";
252 }
253
254
255 ctr.appendChild(zoom);
256 parent.appendChild(ctr);
257
258 var zoomBorder = dc("div");
259 zoomBorder.className = "mojomagnify_border";
260 zoom.appendChild(zoomBorder);
261
262 var zoomInput = parent;
263
264 // clear old overlay
265 if (img.__mojoMagnifyOverlay)
266 parent.removeChild(img.__mojoMagnifyOverlay);
267 img.__mojoMagnifyOverlay = ctr;
268
269 // clear old high-res image
270 if (img.__mojoMagnifyImage && img.__mojoMagnifyImage.parentNode)
271 img.__mojoMagnifyImage.parentNode.removeChild(img.__mojoMagnifyImage);
272
273 img.__mojoMagnifyImage = zoomImg;
274 img.__mojoMagnifyZoomer = zoom;
275 img.__mojoMagnifyBorder = zoomBorder;
276
277 var isInImage = false;
278
279 function onMouseOut(e) {
280 e = e || window.event;
281
282 var target = e.target || e.srcElement;
283 if (!target) return;
284 if (target.nodeName != "DIV") return;
285 var relTarget = e.relatedTarget || e.toElement;
286 if (!relTarget) return;
287 while (relTarget != target && relTarget.nodeName != "BODY" && relTarget.parentNode) {
288 relTarget = relTarget.parentNode;
289 }
290 if (relTarget != target) {
291 isInImage = false;
292 ctr.style.display = "none";
293 }
294 };
295
296 function onMouseMove(e) {
297 e = e || window.event;
298 if (!isInImage) {
299 if (options.animate) {
300 startAnimation(img);
301 }
302 }
303 isInImage = true;
304
305 ctr.style.display = "block";
306
307 var pos = getEventMousePos(zoomInput, e);
308
309 if (e.srcElement && isIE) {
310 if (e.srcElement == zoom) return;
311 if (e.srcElement != zoomInput) {
312 var zoomImgPos = getElementPos(e.srcElement);
313 var imgPos = getElementPos(img);
314 pos.x -= (imgPos.x - zoomImgPos.x);
315 pos.y -= (imgPos.y - zoomImgPos.y);
316 }
317 }
318
319 var x = e.clientX - (getElementPos(img).x - (document.body.scrollLeft||document.documentElement.scrollLeft));
320 var y = e.clientY - (getElementPos(img).y - (document.body.scrollTop||document.documentElement.scrollTop));
321
322 setZoomPos(img, x, y, pos);
323 }
324
325 addEvent(zoomImg, "load", function() {
326
327 addEvent(ctr, "mouseout", onMouseOut);
328 addEvent(ctr, "mouseleave", onMouseOut);
329 if (isIE) {
330 addEvent(document.body, "mouseover",
331 function(e) {
332 e = e || window.event;
333
334 if (isInImage && e.toElement != zoomImg) {
335 ctr.style.display = "none";
336 }
337 }
338 );
339 }
340
341 // try removing the event first so we don't get multiple handlers firing
342 removeEvent(zoomInput, "mousemove", onMouseMove);
343 addEvent(zoomInput, "mousemove", onMouseMove);
344
345 if (options.full) {
346 var maskWidth = zoomImg.offsetWidth;
347 var maskHeight = zoomImg.offsetHeight;
348 img.__mojoMagnifyWidth = maskWidth;
349 img.__mojoMagnifyHeight = maskHeight;
350 zoomBorder.style.width = maskWidth + "px";
351 zoomBorder.style.height = maskHeight + "px";
352 zoom.style.width = maskWidth + "px";
353 zoom.style.height = maskHeight + "px";
354 }
355
356 ctr.style.display = "none";
357 });
358
359 // I've no idea. Simply setting the src will make IE screw it self into a 100% CPU fest. In a timeout, it's ok.
360 setTimeout(function() {
361 zoomImg.src = zoomSrc;
362 }, 1);
363 }
364
365 function setCoords(img, x, y) {
366 if (!img.__mojoMagnifyOverlay) return;
367 isInImage = true;
368 img.__mojoMagnifyOverlay.style.display = "block";
369 setZoomPos(img, x, y, { x : x, y : y });
370 }
371
372 function init() {
373 var images = document.getElementsByTagName("img");
374 var imgList = [];
375 for (var i=0;i<images.length;i++) {
376 imgList.push(images[i]);
377 }
378 for (var i=0;i<imgList.length;i++) {
379 var img = imgList[i];
380 var zoomSrc = img.getAttribute("data-magnifysrc");
381 if (zoomSrc) {
382 var opt = {
383 full : img.getAttribute("data-magnifyfull") === "true",
384 animate : img.getAttribute("data-magnifyanimate") === "true"
385 };
386 makeMagnifiable(img, zoomSrc, opt);
387 }
388 }
389 }
390
391 return {
392 addEvent : addEvent,
393 init : init,
394 makeMagnifiable : makeMagnifiable,
395 setCoords : setCoords
396 };
397
398})();
399
400MojoMagnify.addEvent(window, "load", MojoMagnify.init);
Note: See TracBrowser for help on using the repository browser.