Project

General

Profile

1
/*
2
 * FancyBox - simple jQuery plugin for fancy image zooming
3
 * Examples and documentation at: http://fancy.klade.lv/
4
 * Version: 1.0.0 (29/04/2008)
5
 * Copyright (c) 2008 Janis Skarnelis
6
 * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
7
 * Requires: jQuery v1.2.1 or later
8
*/
9
(function($) {
10
	var opts = {}, 
11
		imgPreloader = new Image, imgTypes = ['png', 'jpg', 'jpeg', 'gif'], 
12
		loadingTimer, loadingFrame = 1;
13

    
14
   $.fn.fancybox = function(settings) {
15
		opts.settings = $.extend({}, $.fn.fancybox.defaults, settings);
16

    
17
		$.fn.fancybox.init();
18

    
19
		return this.each(function() {
20
			var $this = $(this);
21
			var o = $.metadata ? $.extend({}, opts.settings, $this.metadata()) : opts.settings;
22

    
23
			$this.unbind('click').click(function() {
24
				$.fn.fancybox.start(this, o); return false;
25
			});
26
		});
27
	};
28

    
29
	$.fn.fancybox.start = function(el, o) {
30
		if (opts.animating) return false;
31

    
32
		if (o.overlayShow) {
33
			$("#fancy_wrap").prepend('<div id="fancy_overlay"></div>');
34
			$("#fancy_overlay").css({'width': $(window).width(), 'height': $(document).height(), 'opacity': o.overlayOpacity});
35

    
36
			if ($.browser.msie) {
37
				$("#fancy_wrap").prepend('<iframe id="fancy_bigIframe" scrolling="no" frameborder="0"></iframe>');
38
				$("#fancy_bigIframe").css({'width': $(window).width(), 'height': $(document).height(), 'opacity': 0});
39
			}
40

    
41
			$("#fancy_overlay").click($.fn.fancybox.close);
42
		}
43

    
44
		opts.itemArray	= [];
45
		opts.itemNum	= 0;
46

    
47
		if (jQuery.isFunction(o.itemLoadCallback)) {
48
		   o.itemLoadCallback.apply(this, [opts]);
49

    
50
			var c	= $(el).children("img:first").length ? $(el).children("img:first") : $(el);
51
			var tmp	= {'width': c.width(), 'height': c.height(), 'pos': $.fn.fancybox.getPosition(c)}
52

    
53
		   for (var i = 0; i < opts.itemArray.length; i++) {
54
				opts.itemArray[i].o = $.extend({}, o, opts.itemArray[i].o);
55
				
56
				if (o.zoomSpeedIn > 0 || o.zoomSpeedOut > 0) {
57
					opts.itemArray[i].orig = tmp;
58
				}
59
		   }
60

    
61
		} else {
62
			if (!el.rel || el.rel == '') {
63
				var item = {url: el.href, title: el.title, o: o};
64

    
65
				if (o.zoomSpeedIn > 0 || o.zoomSpeedOut > 0) {
66
					var c = $(el).children("img:first").length ? $(el).children("img:first") : $(el);
67
					item.orig = {'width': c.width(), 'height': c.height(), 'pos': $.fn.fancybox.getPosition(c)}
68
				}
69

    
70
				opts.itemArray.push(item);
71

    
72
			} else {
73
				var arr	= $("a[@rel=" + el.rel + "]").get();
74

    
75
				for (var i = 0; i < arr.length; i++) {
76
					var tmp		= $.metadata ? $.extend({}, o, $(arr[i]).metadata()) : o;
77
   					var item	= {url: arr[i].href, title: arr[i].title, o: tmp};
78

    
79
   					if (o.zoomSpeedIn > 0 || o.zoomSpeedOut > 0) {
80
						var c = $(arr[i]).children("img:first").length ? $(arr[i]).children("img:first") : $(el);
81

    
82
						item.orig = {'width': c.width(), 'height': c.height(), 'pos': $.fn.fancybox.getPosition(c)}
83
					}
84

    
85
					if (arr[i].href == el.href) opts.itemNum = i;
86

    
87
					opts.itemArray.push(item);
88
				}
89
			}
90
		}
91

    
92
		$.fn.fancybox.changeItem(opts.itemNum);
93
	};
94

    
95
	$.fn.fancybox.changeItem = function(n) {
96
		$.fn.fancybox.showLoading();
97

    
98
		opts.itemNum = n;
99

    
100
		$("#fancy_nav").empty();
101
		$("#fancy_outer").stop();
102
		$("#fancy_title").hide();
103
		$(document).unbind("keydown");
104

    
105
		imgRegExp = imgTypes.join('|');
106
    	imgRegExp = new RegExp('\.' + imgRegExp + '$', 'i');
107

    
108
		var url = opts.itemArray[n].url;
109

    
110
		if (url.match(/#/)) {
111
			var target = window.location.href.split('#')[0]; target = url.replace(target,'');
112

    
113
	        $.fn.fancybox.showItem('<div id="fancy_div">' + $(target).html() + '</div>');
114

    
115
	        $("#fancy_loading").hide();
116

    
117
		} else if (url.match(imgRegExp)) {
118
			$(imgPreloader).unbind('load').bind('load', function() {
119
				$("#fancy_loading").hide();
120

    
121
				opts.itemArray[n].o.frameWidth	= imgPreloader.width;
122
				opts.itemArray[n].o.frameHeight	= imgPreloader.height;
123

    
124
				$.fn.fancybox.showItem('<img id="fancy_img" src="' + imgPreloader.src + '" />');
125

    
126
			}).attr('src', url + '?rand=' + Math.floor(Math.random() * 999999999) );
127

    
128
		} else {
129
			$.fn.fancybox.showItem('<iframe id="fancy_frame" onload="$.fn.fancybox.showIframe()" name="fancy_iframe' + Math.round(Math.random()*1000) + '" frameborder="0" hspace="0" src="' + url + '"></iframe>');
130
		}
131
	};
132

    
133
	$.fn.fancybox.showIframe = function() {
134
		$("#fancy_loading").hide();
135
		$("#fancy_frame").show();
136
	};
137

    
138
	$.fn.fancybox.showItem = function(val) {
139
		$.fn.fancybox.preloadNeighborImages();
140

    
141
		var viewportPos	= $.fn.fancybox.getViewport();
142
		var itemSize	= $.fn.fancybox.getMaxSize(viewportPos[0] - 50, viewportPos[1] - 100, opts.itemArray[opts.itemNum].o.frameWidth, opts.itemArray[opts.itemNum].o.frameHeight);
143

    
144
		var itemLeft	= viewportPos[2] + Math.round((viewportPos[0] - itemSize[0]) / 2) - 20;
145
		var itemTop		= viewportPos[3] + Math.round((viewportPos[1] - itemSize[1]) / 2) - 40;
146

    
147
		var itemOpts = {
148
			'left':		itemLeft, 
149
			'top':		itemTop, 
150
			'width':	itemSize[0] + 'px', 
151
			'height':	itemSize[1] + 'px'	
152
		}
153

    
154
		if (opts.active) {
155
			$('#fancy_content').fadeOut("normal", function() {
156
				$("#fancy_content").empty();
157
				
158
				$("#fancy_outer").animate(itemOpts, "normal", function() {
159
					$("#fancy_content").append($(val)).fadeIn("normal");
160
					$.fn.fancybox.updateDetails();
161
				});
162
			});
163

    
164
		} else {
165
			opts.active = true;
166

    
167
			$("#fancy_content").empty();
168

    
169
			if ($("#fancy_content").is(":animated")) {
170
				console.info('animated!');
171
			}
172

    
173
			if (opts.itemArray[opts.itemNum].o.zoomSpeedIn > 0) {
174
				opts.animating		= true;
175
				itemOpts.opacity	= "show";
176

    
177
				$("#fancy_outer").css({
178
					'top':		opts.itemArray[opts.itemNum].orig.pos.top - 18,
179
					'left':		opts.itemArray[opts.itemNum].orig.pos.left - 18,
180
					'height':	opts.itemArray[opts.itemNum].orig.height,
181
					'width':	opts.itemArray[opts.itemNum].orig.width
182
				});
183

    
184
				$("#fancy_content").append($(val)).show();
185

    
186
				$("#fancy_outer").animate(itemOpts, opts.itemArray[opts.itemNum].o.zoomSpeedIn, function() {
187
					opts.animating = false;
188
					$.fn.fancybox.updateDetails();
189
				});
190

    
191
			} else {
192
				$("#fancy_content").append($(val)).show();
193
				$("#fancy_outer").css(itemOpts).show();
194
				$.fn.fancybox.updateDetails();
195
			}
196
		 }
197
	};
198

    
199
	$.fn.fancybox.updateDetails = function() {
200
		$("#fancy_bg,#fancy_close").show();
201

    
202
		if (opts.itemArray[opts.itemNum].title !== undefined && opts.itemArray[opts.itemNum].title !== '') {
203
			$('#fancy_title div').html(opts.itemArray[opts.itemNum].title);
204
			$('#fancy_title').show();
205
		}
206

    
207
		if (opts.itemArray[opts.itemNum].o.hideOnContentClick) {
208
			$("#fancy_content").click($.fn.fancybox.close);
209
		} else {
210
			$("#fancy_content").unbind('click');
211
		}
212

    
213
		if (opts.itemNum != 0) {
214
			$("#fancy_nav").append('<a id="fancy_left" href="javascript:;"></a>');
215

    
216
			$('#fancy_left').click(function() {
217
				$.fn.fancybox.changeItem(opts.itemNum - 1); return false;
218
			});
219
		}
220

    
221
		if (opts.itemNum != (opts.itemArray.length - 1)) {
222
			$("#fancy_nav").append('<a id="fancy_right" href="javascript:;"></a>');
223
			
224
			$('#fancy_right').click(function(){
225
				$.fn.fancybox.changeItem(opts.itemNum + 1); return false;
226
			});
227
		}
228

    
229
		$(document).keydown(function(event) {
230
			if (event.keyCode == 27) {
231
            	$.fn.fancybox.close();
232

    
233
			} else if(event.keyCode == 37 && opts.itemNum != 0) {
234
            	$.fn.fancybox.changeItem(opts.itemNum - 1);
235

    
236
			} else if(event.keyCode == 39 && opts.itemNum != (opts.itemArray.length - 1)) {
237
            	$.fn.fancybox.changeItem(opts.itemNum + 1);
238
			}
239
		});
240
	};
241

    
242
	$.fn.fancybox.preloadNeighborImages = function() {
243
		if ((opts.itemArray.length - 1) > opts.itemNum) {
244
			preloadNextImage = new Image();
245
			preloadNextImage.src = opts.itemArray[opts.itemNum + 1].url;
246
		}
247

    
248
		if (opts.itemNum > 0) {
249
			preloadPrevImage = new Image();
250
			preloadPrevImage.src = opts.itemArray[opts.itemNum - 1].url;
251
		}
252
	};
253

    
254
	$.fn.fancybox.close = function() {
255
		if (opts.animating) return false;
256

    
257
		$(imgPreloader).unbind('load');
258
		$(document).unbind("keydown");
259

    
260
		$("#fancy_loading,#fancy_title,#fancy_close,#fancy_bg").hide();
261

    
262
		$("#fancy_nav").empty();
263

    
264
		opts.active	= false;
265

    
266
		if (opts.itemArray[opts.itemNum].o.zoomSpeedOut > 0) {
267
			var itemOpts = {
268
				'top':		opts.itemArray[opts.itemNum].orig.pos.top - 18,
269
				'left':		opts.itemArray[opts.itemNum].orig.pos.left - 18,
270
				'height':	opts.itemArray[opts.itemNum].orig.height,
271
				'width':	opts.itemArray[opts.itemNum].orig.width,
272
				'opacity':	'hide'
273
			};
274

    
275
			opts.animating = true;
276

    
277
			$("#fancy_outer").animate(itemOpts, opts.itemArray[opts.itemNum].o.zoomSpeedOut, function() {
278
				$("#fancy_content").hide().empty();
279
				$("#fancy_overlay,#fancy_bigIframe").remove();
280
				opts.animating = false;
281
			});
282

    
283
		} else {
284
			$("#fancy_outer").hide();
285
			$("#fancy_content").hide().empty();
286
			$("#fancy_overlay,#fancy_bigIframe").fadeOut("fast").remove();
287
		}
288
	};
289

    
290
	$.fn.fancybox.showLoading = function() {
291
		clearInterval(loadingTimer);
292

    
293
		var pos = $.fn.fancybox.getViewport();
294

    
295
		$("#fancy_loading").css({'left': ((pos[0] - 40) / 2 + pos[2]), 'top': ((pos[1] - 40) / 2 + pos[3])}).show();
296
		$("#fancy_loading").bind('click', $.fn.fancybox.close);
297
		
298
		loadingTimer = setInterval($.fn.fancybox.animateLoading, 66);
299
	};
300

    
301
	$.fn.fancybox.animateLoading = function(el, o) {
302
		if (!$("#fancy_loading").is(':visible')){
303
			clearInterval(loadingTimer);
304
			return;
305
		}
306

    
307
		$("#fancy_loading > div").css('top', (loadingFrame * -40) + 'px');
308

    
309
		loadingFrame = (loadingFrame + 1) % 12;
310
	};
311

    
312
	$.fn.fancybox.init = function() {
313
		if (!$('#fancy_wrap').length) {
314
			$('<div id="fancy_wrap"><div id="fancy_loading"><div></div></div><div id="fancy_outer"><div id="fancy_inner"><div id="fancy_nav"></div><div id="fancy_close"></div><div id="fancy_content"></div><div id="fancy_title"></div></div></div></div>').appendTo("body");
315
			$('<div id="fancy_bg"><div class="fancy_bg fancy_bg_n"></div><div class="fancy_bg fancy_bg_ne"></div><div class="fancy_bg fancy_bg_e"></div><div class="fancy_bg fancy_bg_se"></div><div class="fancy_bg fancy_bg_s"></div><div class="fancy_bg fancy_bg_sw"></div><div class="fancy_bg fancy_bg_w"></div><div class="fancy_bg fancy_bg_nw"></div></div>').prependTo("#fancy_inner");
316
			
317
			$('<table cellspacing="0" cellpadding="0" border="0"><tr><td id="fancy_title_left"></td><td id="fancy_title_main"><div></div></td><td id="fancy_title_right"></td></tr></table>').appendTo('#fancy_title');
318
		}
319

    
320
		if ($.browser.msie) {
321
			$("#fancy_inner").prepend('<iframe id="fancy_freeIframe" scrolling="no" frameborder="0"></iframe>');
322
		}
323

    
324
		if (jQuery.fn.pngFix) $(document).pngFix();
325

    
326
    	$("#fancy_close").click($.fn.fancybox.close);
327
	};
328

    
329
	$.fn.fancybox.getPosition = function(el) {
330
		var pos = el.offset();
331

    
332
		pos.top	+= $.fn.fancybox.num(el, 'paddingTop');
333
		pos.top	+= $.fn.fancybox.num(el, 'borderTopWidth');
334

    
335
 		pos.left += $.fn.fancybox.num(el, 'paddingLeft');
336
		pos.left += $.fn.fancybox.num(el, 'borderLeftWidth');
337

    
338
		return pos;
339
	};
340

    
341
	$.fn.fancybox.num = function (el, prop) {
342
		return parseInt($.curCSS(el.jquery?el[0]:el,prop,true))||0;
343
	};
344

    
345
	$.fn.fancybox.getPageScroll = function() {
346
		var xScroll, yScroll;
347

    
348
		if (self.pageYOffset) {
349
			yScroll = self.pageYOffset;
350
			xScroll = self.pageXOffset;
351
		} else if (document.documentElement && document.documentElement.scrollTop) {
352
			yScroll = document.documentElement.scrollTop;
353
			xScroll = document.documentElement.scrollLeft;
354
		} else if (document.body) {
355
			yScroll = document.body.scrollTop;
356
			xScroll = document.body.scrollLeft;	
357
		}
358

    
359
		return [xScroll, yScroll]; 
360
	};
361

    
362
	$.fn.fancybox.getViewport = function() {
363
		var scroll = $.fn.fancybox.getPageScroll();
364

    
365
		return [$(window).width(), $(window).height(), scroll[0], scroll[1]];
366
	};
367

    
368
	$.fn.fancybox.getMaxSize = function(maxWidth, maxHeight, imageWidth, imageHeight) {
369
		var r = Math.min(Math.min(maxWidth, imageWidth) / imageWidth, Math.min(maxHeight, imageHeight) / imageHeight);
370

    
371
		return [Math.round(r * imageWidth), Math.round(r * imageHeight)];
372
	};
373

    
374
	$.fn.fancybox.defaults = {
375
		hideOnContentClick:	false,
376
		zoomSpeedIn:		500,
377
		zoomSpeedOut:		500,
378
		frameWidth:			600,
379
		frameHeight:		400,
380
		overlayShow:		false,
381
		overlayOpacity:		0.4,
382
		itemLoadCallback:	null
383
	};
384
})(jQuery);
(23-23/26)