PageSourceSearch

https://iconzafrica.org/js-global/FancyZoom.js

js iconzafrica.org collected 2026-10-02 06:04:29 UTC 23,035 bytes, 761 lines download raw bytes

1// FancyZoom.js - v1.1 - http://www.fancyzoom.com
2//
3// Copyright (c) 2008 Cabel Sasser / Panic Inc
4// All rights reserved.
5// 
6//     Requires: FancyZoomHTML.js
7// Instructions: Include JS files in page, call setupZoom() in onLoad. That's it!
8//               Any <a href> links to images will be updated to zoom inline.
9//               Add rel="nozoom" to your <a href> to disable zooming for an image.
10// 
11// Redistribution and use of this effect in source form, with or without modification,
12// are permitted provided that the following conditions are met:
13// 
14// * USE OF SOURCE ON COMMERCIAL (FOR-PROFIT) WEBSITE REQUIRES ONE-TIME LICENSE FEE PER DOMAIN.
15//   Reasonably priced! Visit www.fancyzoom.com for licensing instructions. Thanks!
16//
17// * Non-commercial (personal) website use is permitted without license/payment!
18//
19// * Redistribution of source code must retain the above copyright notice,
20//   this list of conditions and the following disclaimer.
21//
22// * Redistribution of source code and derived works cannot be sold without specific
23//   written prior permission.
24//
25// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
37var includeCaption = true; // Turn on the "caption" feature, and write out the caption HTML
38var zoomTime       = 5;    // Milliseconds between frames of zoom animation
39var zoomSteps      = 15;   // Number of zoom animation frames
40var includeFade    = 1;    // Set to 1 to fade the image in / out as it zooms
41var minBorder      = 90;   // Amount of padding between large, scaled down images, and the window edges
42var shadowSettings = '0px 5px 25px rgba(0, 0, 0, '; // Blur, radius, color of shadow for compatible browsers
43
44var zoomImagesURI   = '/images-global/zoom/'; // Location of the zoom and shadow images
45
46// Init. Do not add anything below this line, unless it's something awesome.
47
48var myWidth = 0, myHeight = 0, myScroll = 0; myScrollWidth = 0; myScrollHeight = 0;
49var zoomOpen = false, preloadFrame = 1, preloadActive = false, preloadTime = 0, imgPreload = new Image();
50var preloadAnimTimer = 0;
51
52var zoomActive = new Array(); var zoomTimer  = new Array(); 
53var zoomOrigW  = new Array(); var zoomOrigH  = new Array();
54var zoomOrigX  = new Array(); var zoomOrigY  = new Array();
55
56var zoomID         = "ZoomBox";
57var theID          = "ZoomImage";
58var zoomCaption    = "ZoomCaption";
59var zoomCaptionDiv = "ZoomCapDiv";
60
61if (navigator.userAgent.indexOf("MSIE") != -1) {
62	var browserIsIE = true;
63}
64
65// Zoom: Setup The Page! Called in your <body>'s onLoad handler.
66
67function setupZoom() {
68	prepZooms();
69	insertZoomHTML();
70	zoomdiv = document.getElementById(zoomID);  
71	zoomimg = document.getElementById(theID);
72}
73
74// Zoom: Inject Javascript functions into hrefs pointing to images, one by one!
75// Skip any href that contains a rel="nozoom" tag.
76// This is done at page load time via an onLoad() handler.
77
78function prepZooms() {
79	if (! document.getElementsByTagName) {
80		return;
81	}
82	var links = document.getElementsByTagName("a");
83	for (i = 0; i < links.length; i++) {
84		if (links[i].getAttribute("href")) {
85			if (links[i].getAttribute("href").search(/(.*)\.(jpg|jpeg|gif|png|bmp|tif|tiff)/gi) != -1) {
86				if (links[i].getAttribute("rel") != "nozoom") {
87					links[i].onclick = function (event) { return zoomClick(this, event); };
88					links[i].onmouseover = function () { zoomPreload(this); };
89				}
90			}
91		}
92	}
93}
94
95// Zoom: Load an image into an image object. When done loading, function sets preloadActive to false,
96// so other bits know that they can proceed with the zoom.
97// Preloaded image is stored in imgPreload and swapped out in the zoom function.
98
99function zoomPreload(from) {
100
101	var theimage = from.getAttribute("href");
102
103	// Only preload if we have to, i.e. the image isn't this image already
104
105	if (imgPreload.src.indexOf(from.getAttribute("href").substr(from.getAttribute("href").lastIndexOf("/"))) == -1) {
106		preloadActive = true;
107		imgPreload = new Image();
108
109		// Set a function to fire when the preload is complete, setting flags along the way.
110
111		imgPreload.onload = function() {
112			preloadActive = false;
113		}
114
115		// Load it!
116		imgPreload.src = theimage;
117	}
118}
119
120// Zoom: Start the preloading animation cycle.
121
122function preloadAnimStart() {
123	preloadTime = new Date();
124	document.getElementById("ZoomSpin").style.left = (myWidth / 2) + 'px';
125	document.getElementById("ZoomSpin").style.top = ((myHeight / 2) + myScroll) + 'px';
126	document.getElementById("ZoomSpin").style.visibility = "visible";	
127	preloadFrame = 1;
128	document.getElementById("SpinImage").src = zoomImagesURI+'zoom-spin-'+preloadFrame+'.png';  
129	preloadAnimTimer = setInterval("preloadAnim()", 100);
130}
131
132// Zoom: Display and ANIMATE the jibber-jabber widget. Once preloadActive is false, bail and zoom it up!
133
134function preloadAnim(from) {
135	if (preloadActive != false) {
136		document.getElementById("SpinImage").src = zoomImagesURI+'zoom-spin-'+preloadFrame+'.png';
137		preloadFrame++;
138		if (preloadFrame > 12) preloadFrame = 1;
139	} else {
140		document.getElementById("ZoomSpin").style.visibility = "hidden";    
141		clearInterval(preloadAnimTimer);
142		preloadAnimTimer = 0;
143		zoomIn(preloadFrom);
144	}
145}
146
147// ZOOM CLICK: We got a click! Should we do the zoom? Or wait for the preload to complete?
148// todo?: Double check that imgPreload src = clicked src
149
150function zoomClick(from, evt) {
151
152	var shift = getShift(evt);
153
154	// Check for Command / Alt key. If pressed, pass them through -- don't zoom!
155	if (! evt && window.event && (window.event.metaKey || window.event.altKey)) {
156		return true;
157	} else if (evt && (evt.metaKey|| evt.altKey)) {
158		return true;
159	}
160
161	// Get browser dimensions
162	getSize();
163
164	// If preloading still, wait, and display the spinner.
165	if (preloadActive == true) {
166		// But only display the spinner if it's not already being displayed!
167		if (preloadAnimTimer == 0) {
168			preloadFrom = from;
169			preloadAnimStart();	
170		}
171	} else {
172		// Otherwise, we're loaded: do the zoom!
173		zoomIn(from, shift);
174	}
175	
176	return false;
177	
178}
179
180// Zoom: Move an element in to endH endW, using zoomHost as a starting point.
181// "from" is an object reference to the href that spawned the zoom.
182
183function zoomIn(from, shift) {
184
185	zoomimg.src = from.getAttribute("href");
186
187	// Determine the zoom settings from where we came from, the element in the <a>.
188	// If there's no element in the <a>, or we can't get the width, make stuff up
189
190	if (from.childNodes[0].width) {
191		startW = from.childNodes[0].width;
192		startH = from.childNodes[0].height;
193		startPos = findElementPos(from.childNodes[0]);
194	} else {
195		startW = 50;
196		startH = 12;
197		startPos = findElementPos(from);
198	}
199
200	hostX = startPos[0];
201	hostY = startPos[1];
202
203	// Make up for a scrolled containing div.
204	// TODO: This HAS to move into findElementPos.
205	
206	if (document.getElementById('scroller')) {
207		hostX = hostX - document.getElementById('scroller').scrollLeft;
208	}
209
210	// Determine the target zoom settings from the preloaded image object
211
212	endW = imgPreload.width;
213	endH = imgPreload.height;
214
215	// Start! But only if we're not zooming already!
216
217	if (zoomActive[theID] != true) {
218
219		// Clear everything out just in case something is already open
220
221		if (document.getElementById("ShadowBox")) {
222			document.getElementById("ShadowBox").style.visibility = "hidden";
223		} else if (! browserIsIE) {
224		
225			// Wipe timer if shadow is fading in still
226			if (fadeActive["ZoomImage"]) {
227				clearInterval(fadeTimer["ZoomImage"]);
228				fadeActive["ZoomImage"] = false;
229				fadeTimer["ZoomImage"] = false;			
230			}
231			
232			document.getElementById("ZoomImage").style.webkitBoxShadow = shadowSettings + '0.0)';			
233		}
234		
235		document.getElementById("ZoomClose").style.visibility = "hidden";     
236
237		// Setup the CAPTION, if existing. Hide it first, set the text.
238
239		if (includeCaption) {
240			document.getElementById(zoomCaptionDiv).style.visibility = "hidden";
241			if (from.getAttribute('title') && includeCaption) {
242				// Yes, there's a caption, set it up
243				document.getElementById(zoomCaption).innerHTML = from.getAttribute('title');
244			} else {
245				document.getElementById(zoomCaption).innerHTML = "";
246			}
247		}
248
249		// Store original position in an array for future zoomOut.
250
251		zoomOrigW[theID] = startW;
252		zoomOrigH[theID] = startH;
253		zoomOrigX[theID] = hostX;
254		zoomOrigY[theID] = hostY;
255
256		// Now set the starting dimensions
257
258		zoomimg.style.width = startW + 'px';
259		zoomimg.style.height = startH + 'px';
260		zoomdiv.style.left = hostX + 'px';
261		zoomdiv.style.top = hostY + 'px';
262
263		// Show the zooming image container, make it invisible
264
265		if (includeFade == 1) {
266			setOpacity(0, zoomID);
267		}
268		zoomdiv.style.visibility = "visible";
269
270		// If it's too big to fit in the window, shrink the width and height to fit (with ratio).
271
272		sizeRatio = endW / endH;
273		if (endW > myWidth - minBorder) {
274			endW = myWidth - minBorder;
275			endH = endW / sizeRatio;
276		}
277		if (endH > myHeight - minBorder) {
278			endH = myHeight - minBorder;
279			endW = endH * sizeRatio;
280		}
281
282		zoomChangeX = ((myWidth / 2) - (endW / 2) - hostX);
283		zoomChangeY = (((myHeight / 2) - (endH / 2) - hostY) + myScroll);
284		zoomChangeW = (endW - startW);
285		zoomChangeH = (endH - startH);
286		
287		// Shift key?
288	
289		if (shift) {
290			tempSteps = zoomSteps * 7;
291		} else {
292			tempSteps = zoomSteps;
293		}
294
295		// Setup Zoom
296
297		zoomCurrent = 0;
298
299		// Setup Fade with Zoom, If Requested
300
301		if (includeFade == 1) {
302			fadeCurrent = 0;
303			fadeAmount = (0 - 100) / tempSteps;
304		} else {
305			fadeAmount = 0;
306		}
307
308		// Do It!
309		
310		zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+startW+", "+zoomChangeW+", "+startH+", "+zoomChangeH+", "+hostX+", "+zoomChangeX+", "+hostY+", "+zoomChangeY+", "+tempSteps+", "+includeFade+", "+fadeAmount+", 'zoomDoneIn(zoomID)')", zoomTime);		
311		zoomActive[theID] = true; 
312	}
313}
314
315// Zoom it back out.
316
317function zoomOut(from, evt) {
318
319	// Get shift key status.
320	// IE events don't seem to get passed through the function, so grab it from the window.
321
322	if (getShift(evt)) {
323		tempSteps = zoomSteps * 7;
324	} else {
325		tempSteps = zoomSteps;
326	}	
327
328	// Check to see if something is happening/open
329  
330	if (zoomActive[theID] != true) {
331
332		// First, get rid of the shadow if necessary.
333
334		if (document.getElementById("ShadowBox")) {
335			document.getElementById("ShadowBox").style.visibility = "hidden";
336		} else if (! browserIsIE) {
337		
338			// Wipe timer if shadow is fading in still
339			if (fadeActive["ZoomImage"]) {
340				clearInterval(fadeTimer["ZoomImage"]);
341				fadeActive["ZoomImage"] = false;
342				fadeTimer["ZoomImage"] = false;			
343			}
344			
345			document.getElementById("ZoomImage").style.webkitBoxShadow = shadowSettings + '0.0)';			
346		}
347
348		// ..and the close box...
349
350		document.getElementById("ZoomClose").style.visibility = "hidden";
351
352		// ...and the caption if necessary!
353
354		if (includeCaption && document.getElementById(zoomCaption).innerHTML != "") {
355			// fadeElementSetup(zoomCaptionDiv, 100, 0, 5, 1);
356			document.getElementById(zoomCaptionDiv).style.visibility = "hidden";
357		}
358
359		// Now, figure out where we came from, to get back there
360
361		startX = parseInt(zoomdiv.style.left);
362		startY = parseInt(zoomdiv.style.top);
363		startW = zoomimg.width;
364		startH = zoomimg.height;
365		zoomChangeX = zoomOrigX[theID] - startX;
366		zoomChangeY = zoomOrigY[theID] - startY;
367		zoomChangeW = zoomOrigW[theID] - startW;
368		zoomChangeH = zoomOrigH[theID] - startH;
369
370		// Setup Zoom
371
372		zoomCurrent = 0;
373
374		// Setup Fade with Zoom, If Requested
375
376		if (includeFade == 1) {
377			fadeCurrent = 0;
378			fadeAmount = (100 - 0) / tempSteps;
379		} else {
380			fadeAmount = 0;
381		}
382
383		// Do It!
384
385		zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+startW+", "+zoomChangeW+", "+startH+", "+zoomChangeH+", "+startX+", "+zoomChangeX+", "+startY+", "+zoomChangeY+", "+tempSteps+", "+includeFade+", "+fadeAmount+", 'zoomDone(zoomID, theID)')", zoomTime);	
386		zoomActive[theID] = true;
387	}
388}
389
390// Finished Zooming In
391
392function zoomDoneIn(zoomdiv, theID) {
393
394	// Note that it's open
395  
396	zoomOpen = true;
397	zoomdiv = document.getElementById(zoomdiv);
398
399	// Position the table shadow behind the zoomed in image, and display it
400
401	if (document.getElementById("ShadowBox")) {
402
403		setOpacity(0, "ShadowBox");
404		shadowdiv = document.getElementById("ShadowBox");
405
406		shadowLeft = parseInt(zoomdiv.style.left) - 13;
407		shadowTop = parseInt(zoomdiv.style.top) - 8;
408		shadowWidth = zoomdiv.offsetWidth + 26;
409		shadowHeight = zoomdiv.offsetHeight + 26; 
410	
411		shadowdiv.style.width = shadowWidth + 'px';
412		shadowdiv.style.height = shadowHeight + 'px';
413		shadowdiv.style.left = shadowLeft + 'px';
414		shadowdiv.style.top = shadowTop + 'px';
415
416		document.getElementById("ShadowBox").style.visibility = "visible";
417		fadeElementSetup("ShadowBox", 0, 100, 5);
418		
419	} else if (! browserIsIE) {
420		// Or, do a fade of the modern shadow
421		fadeElementSetup("ZoomImage", 0, .8, 5, 0, "shadow");
422	}
423	
424	// Position and display the CAPTION, if existing
425  
426	if (includeCaption && document.getElementById(zoomCaption).innerHTML != "") {
427		// setOpacity(0, zoomCaptionDiv);
428		zoomcapd = document.getElementById(zoomCaptionDiv);
429		zoomcapd.style.top = parseInt(zoomdiv.style.top) + (zoomdiv.offsetHeight + 15) + 'px';
430		zoomcapd.style.left = (myWidth / 2) - (zoomcapd.offsetWidth / 2) + 'px';
431		zoomcapd.style.visibility = "visible";
432		// fadeElementSetup(zoomCaptionDiv, 0, 100, 5);
433	}   
434	
435	// Display Close Box (fade it if it's not IE)
436
437	if (!browserIsIE) setOpacity(0, "ZoomClose");
438	document.getElementById("ZoomClose").style.visibility = "visible";
439	if (!browserIsIE) fadeElementSetup("ZoomClose", 0, 100, 5);
440
441	// Get keypresses
442	document.onkeypress = getKey;
443	
444}
445
446// Finished Zooming Out
447
448function zoomDone(zoomdiv, theID) {
449
450	// No longer open
451  
452	zoomOpen = false;
453
454	// Clear stuff out, clean up
455
456	zoomOrigH[theID] = "";
457	zoomOrigW[theID] = "";
458	document.getElementById(zoomdiv).style.visibility = "hidden";
459	zoomActive[theID] == false;
460
461	// Stop getting keypresses
462
463	document.onkeypress = null;
464
465}
466
467// Actually zoom the element
468
469function zoomElement(zoomdiv, theID, zoomCurrent, zoomStartW, zoomChangeW, zoomStartH, zoomChangeH, zoomStartX, zoomChangeX, zoomStartY, zoomChangeY, zoomSteps, includeFade, fadeAmount, execWhenDone) {
470
471	// console.log("Zooming Step #"+zoomCurrent+ " of "+zoomSteps+" (zoom " + zoomStartW + "/" + zoomChangeW + ") (zoom " + zoomStartH + "/" + zoomChangeH + ")  (zoom " + zoomStartX + "/" + zoomChangeX + ")  (zoom " + zoomStartY + "/" + zoomChangeY + ") Fade: "+fadeAmount);
472    
473	// Test if we're done, or if we continue
474
475	if (zoomCurrent == (zoomSteps + 1)) {
476		zoomActive[theID] = false;
477		clearInterval(zoomTimer[theID]);
478
479		if (execWhenDone != "") {
480			eval(execWhenDone);
481		}
482	} else {
483	
484		// Do the Fade!
485	  
486		if (includeFade == 1) {
487			if (fadeAmount < 0) {
488				setOpacity(Math.abs(zoomCurrent * fadeAmount), zoomdiv);
489			} else {
490				setOpacity(100 - (zoomCurrent * fadeAmount), zoomdiv);
491			}
492		}
493	  
494		// Calculate this step's difference, and move it!
495		
496		moveW = cubicInOut(zoomCurrent, zoomStartW, zoomChangeW, zoomSteps);
497		moveH = cubicInOut(zoomCurrent, zoomStartH, zoomChangeH, zoomSteps);
498		moveX = cubicInOut(zoomCurrent, zoomStartX, zoomChangeX, zoomSteps);
499		moveY = cubicInOut(zoomCurrent, zoomStartY, zoomChangeY, zoomSteps);
500	
501		document.getElementById(zoomdiv).style.left = moveX + 'px';
502		document.getElementById(zoomdiv).style.top = moveY + 'px';
503		zoomimg.style.width = moveW + 'px';
504		zoomimg.style.height = moveH + 'px';
505	
506		zoomCurrent++;
507		
508		clearInterval(zoomTimer[theID]);
509		zoomTimer[theID] = setInterval("zoomElement('"+zoomdiv+"', '"+theID+"', "+zoomCurrent+", "+zoomStartW+", "+zoomChangeW+", "+zoomStartH+", "+zoomChangeH+", "+zoomStartX+", "+zoomChangeX+", "+zoomStartY+", "+zoomChangeY+", "+zoomSteps+", "+includeFade+", "+fadeAmount+", '"+execWhenDone+"')", zoomTime);
510	}
511}
512
513// Zoom Utility: Get Key Press when image is open, and act accordingly
514
515function getKey(evt) {
516	if (! evt) {
517		theKey = event.keyCode;
518	} else {
519		theKey = evt.keyCode;
520	}
521
522	if (theKey == 27) { // ESC
523		zoomOut(this, evt);
524	}
525}
526
527////////////////////////////
528//
529// FADE Functions
530//
531
532function fadeOut(elem) {
533	if (elem.id) {
534		fadeElementSetup(elem.id, 100, 0, 10);
535	}
536}
537
538function fadeIn(elem) {
539	if (elem.id) {
540		fadeElementSetup(elem.id, 0, 100, 10);	
541	}
542}
543
544// Fade: Initialize the fade function
545
546var fadeActive = new Array();
547var fadeQueue  = new Array();
548var fadeTimer  = new Array();
549var fadeClose  = new Array();
550var fadeMode   = new Array();
551
552function fadeElementSetup(theID, fdStart, fdEnd, fdSteps, fdClose, fdMode) {
553
554	// alert("Fading: "+theID+" Steps: "+fdSteps+" Mode: "+fdMode);
555
556	if (fadeActive[theID] == true) {
557		// Already animating, queue up this command
558		fadeQueue[theID] = new Array(theID, fdStart, fdEnd, fdSteps);
559	} else {
560		fadeSteps = fdSteps;
561		fadeCurrent = 0;
562		fadeAmount = (fdStart - fdEnd) / fadeSteps;
563		fadeTimer[theID] = setInterval("fadeElement('"+theID+"', '"+fadeCurrent+"', '"+fadeAmount+"', '"+fadeSteps+"')", 15);
564		fadeActive[theID] = true;
565		fadeMode[theID] = fdMode;
566		
567		if (fdClose == 1) {
568			fadeClose[theID] = true;
569		} else {
570			fadeClose[theID] = false;
571		}
572	}
573}
574
575// Fade: Do the fade. This function will call itself, modifying the parameters, so
576// many instances can run concurrently. Can fade using opacity, or fade using a box-shadow.
577
578function fadeElement(theID, fadeCurrent, fadeAmount, fadeSteps) {
579
580	if (fadeCurrent == fadeSteps) {
581
582		// We're done, so clear.
583
584		clearInterval(fadeTimer[theID]);
585		fadeActive[theID] = false;
586		fadeTimer[theID] = false;
587
588		// Should we close it once the fade is complete?
589
590		if (fadeClose[theID] == true) {
591			document.getElementById(theID).style.visibility = "hidden";
592		}
593
594		// Hang on.. did a command queue while we were working? If so, make it happen now
595
596		if (fadeQueue[theID] && fadeQueue[theID] != false) {
597			fadeElementSetup(fadeQueue[theID][0], fadeQueue[theID][1], fadeQueue[theID][2], fadeQueue[theID][3]);
598			fadeQueue[theID] = false;
599		}
600	} else {
601
602		fadeCurrent++;
603		
604		// Now actually do the fade adjustment.
605		
606		if (fadeMode[theID] == "shadow") {
607
608			// Do a special fade on the webkit-box-shadow of the object
609		
610			if (fadeAmount < 0) {
611				document.getElementById(theID).style.webkitBoxShadow = shadowSettings + (Math.abs(fadeCurrent * fadeAmount)) + ')';
612			} else {
613				document.getElementById(theID).style.webkitBoxShadow = shadowSettings + (100 - (fadeCurrent * fadeAmount)) + ')';
614			}
615			
616		} else {
617		
618			// Set the opacity depending on if we're adding or subtracting (pos or neg)
619			
620			if (fadeAmount < 0) {
621				setOpacity(Math.abs(fadeCurrent * fadeAmount), theID);
622			} else {
623				setOpacity(100 - (fadeCurrent * fadeAmount), theID);
624			}
625		}
626
627		// Keep going, and send myself the updated variables
628		clearInterval(fadeTimer[theID]);
629		fadeTimer[theID] = setInterval("fadeElement('"+theID+"', '"+fadeCurrent+"', '"+fadeAmount+"', '"+fadeSteps+"')", 15);
630	}
631}
632
633////////////////////////////
634//
635// UTILITY functions
636//
637
638// Utility: Set the opacity, compatible with a number of browsers. Value from 0 to 100.
639
640function setOpacity(opacity, theID) {
641
642	var object = document.getElementById(theID).style;
643
644	// If it's 100, set it to 99 for Firefox.
645
646	if (navigator.userAgent.indexOf("Firefox") != -1) {
647		if (opacity == 100) { opacity = 99.9999; } // This is majorly awkward
648	}
649
650	// Multi-browser opacity setting
651
652	object.filter = "alpha(opacity=" + opacity + ")"; // IE/Win
653	object.opacity = (opacity / 100);                 // Safari 1.2, Firefox+Mozilla
654
655}
656
657// Utility: Math functions for animation calucations - From http://www.robertpenner.com/easing/
658//
659// t = time, b = begin, c = change, d = duration
660// time = current frame, begin is fixed, change is basically finish - begin, duration is fixed (frames),
661
662function linear(t, b, c, d)
663{
664	return c*t/d + b;
665}
666
667function sineInOut(t, b, c, d)
668{
669	return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
670}
671
672function cubicIn(t, b, c, d) {
673	return c*(t/=d)*t*t + b;
674}
675
676function cubicOut(t, b, c, d) {
677	return c*((t=t/d-1)*t*t + 1) + b;
678}
679
680function cubicInOut(t, b, c, d)
681{
682	if ((t/=d/2) < 1) return c/2*t*t*t + b;
683	return c/2*((t-=2)*t*t + 2) + b;
684}
685
686function bounceOut(t, b, c, d)
687{
688	if ((t/=d) < (1/2.75)){
689		return c*(7.5625*t*t) + b;
690	} else if (t < (2/2.75)){
691		return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
692	} else if (t < (2.5/2.75)){
693		return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
694	} else {
695		return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
696	}
697}
698
699
700// Utility: Get the size of the window, and set myWidth and myHeight
701// Credit to quirksmode.org
702
703function getSize() {
704
705	// Window Size
706
707	if (self.innerHeight) { // Everyone but IE
708		myWidth = window.innerWidth;
709		myHeight = window.innerHeight;
710		myScroll = window.pageYOffset;
711	} else if (document.documentElement && document.documentElement.clientHeight) { // IE6 Strict
712		myWidth = document.documentElement.clientWidth;
713		myHeight = document.documentElement.clientHeight;
714		myScroll = document.documentElement.scrollTop;
715	} else if (document.body) { // Other IE, such as IE7
716		myWidth = document.body.clientWidth;
717		myHeight = document.body.clientHeight;
718		myScroll = document.body.scrollTop;
719	}
720
721	// Page size w/offscreen areas
722
723	if (window.innerHeight && window.scrollMaxY) {	
724		myScrollWidth = document.body.scrollWidth;
725		myScrollHeight = window.innerHeight + window.scrollMaxY;
726	} else if (document.body.scrollHeight > document.body.offsetHeight) { // All but Explorer Mac
727		myScrollWidth = document.body.scrollWidth;
728		myScrollHeight = document.body.scrollHeight;
729	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
730		myScrollWidth = document.body.offsetWidth;
731		myScrollHeight = document.body.offsetHeight;
732	}
733}
734
735// Utility: Get Shift Key Status
736// IE events don't seem to get passed through the function, so grab it from the window.
737
738function getShift(evt) {
739	var shift = false;
740	if (! evt && window.event) {
741		shift = window.event.shiftKey;
742	} else if (evt) {
743		shift = evt.shiftKey;
744		if (shift) evt.stopPropagation(); // Prevents Firefox from doing shifty things
745	}
746	return shift;
747}
748
749// Utility: Find the Y position of an element on a page. Return Y and X as an array
750
751function findElementPos(elemFind)
752{
753	var elemX = 0;
754	var elemY = 0;
755	do {
756		elemX += elemFind.offsetLeft;
757		elemY += elemFind.offsetTop;
758	} while ( elemFind = elemFind.offsetParent )
759
760	return Array(elemX, elemY);
761}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.