|
1 /** |
|
2 * Interface Elements for jQuery |
|
3 * ImageBox |
|
4 * |
|
5 * http://interface.eyecon.ro |
|
6 * |
|
7 * Copyright (c) 2006 Stefan Petre |
|
8 * Dual licensed under the MIT (MIT-LICENSE.txt) |
|
9 * and GPL (GPL-LICENSE.txt) licenses. |
|
10 * |
|
11 */ |
|
12 |
|
13 /** |
|
14 * This a jQuery equivalent for Lightbox2. Alternative to image popups that will display images in an overlay. All links that have attribute 'rel' starting with 'imagebox' and link to an image will display the image inside the page. Galleries can by build buy giving the value 'imagebox-galname' to attribute 'rel'. Attribute 'title' will be used as caption. |
|
15 * Keyboard navigation: |
|
16 * - next image: arrow right, page down, 'n' key, space |
|
17 * - previous image: arrow left, page up, 'p' key, backspace |
|
18 * - close: escape |
|
19 * |
|
20 * CSS |
|
21 * #ImageBoxOverlay |
|
22 * { |
|
23 * background-color: #000; |
|
24 * } |
|
25 * #ImageBoxCaption |
|
26 * { |
|
27 * background-color: #F4F4EC; |
|
28 * } |
|
29 * #ImageBoxContainer |
|
30 * { |
|
31 * width: 250px; |
|
32 * height: 250px; |
|
33 * background-color: #F4F4EC; |
|
34 * } |
|
35 * #ImageBoxCaptionText |
|
36 * { |
|
37 * font-weight: bold; |
|
38 * padding-bottom: 5px; |
|
39 * font-size: 13px; |
|
40 * color: #000; |
|
41 * } |
|
42 * #ImageBoxCaptionImages |
|
43 * { |
|
44 * margin: 0; |
|
45 * } |
|
46 * #ImageBoxNextImage |
|
47 * { |
|
48 * background-image: url(images/imagebox/spacer.gif); |
|
49 * background-color: transparent; |
|
50 * } |
|
51 * #ImageBoxPrevImage |
|
52 * { |
|
53 * background-image: url(images/imagebox/spacer.gif); |
|
54 * background-color: transparent; |
|
55 * } |
|
56 * #ImageBoxNextImage:hover |
|
57 * { |
|
58 * background-image: url(images/imagebox/next_image.jpg); |
|
59 * background-repeat: no-repeat; |
|
60 * background-position: right top; |
|
61 * } |
|
62 * #ImageBoxPrevImage:hover |
|
63 * { |
|
64 * background-image: url(images/imagebox/prev_image.jpg); |
|
65 * background-repeat: no-repeat; |
|
66 * background-position: left bottom; |
|
67 * } |
|
68 * |
|
69 * @name Imagebox |
|
70 * @description This a jQuery equivalent for Lightbox2. Alternative to image popups that will display images in an overlay. All links that have attribute 'rel' starting with 'imagebox' and link to an image will display the image inside the page. Galleries can by build buy giving the value 'imagebox-galname' to attribute 'rel'. Attribute 'title' will be used as caption. |
|
71 * @param Hash hash A hash of parameters |
|
72 * @option Integer border border width |
|
73 * @option String loaderSRC path to loading image |
|
74 * @option String closeHTML path to close overlay image |
|
75 * @option Float overlayOpacity opacity for overlay |
|
76 * @option String textImage when a galalry it is build then the iteration is displayed |
|
77 * @option String textImageFrom when a galalry it is build then the iteration is displayed |
|
78 * @option Integer fadeDuration fade duration in miliseconds |
|
79 * |
|
80 * @type jQuery |
|
81 * @cat Plugins/Interface |
|
82 * @author Stefan Petre |
|
83 */ |
|
84 jQuery.ImageBox = { |
|
85 options : { |
|
86 border : 10, |
|
87 loaderSRC : 'images/loading.gif', |
|
88 closeHTML : '<img src="images/close.jpg" />', |
|
89 overlayOpacity : 0.8, |
|
90 textImage : 'Showing image', |
|
91 textImageFrom : 'from', |
|
92 fadeDuration : 400 |
|
93 }, |
|
94 imageLoaded : false, |
|
95 firstResize : false, |
|
96 currentRel : null, |
|
97 animationInProgress : false, |
|
98 opened : false, |
|
99 |
|
100 keyPressed : function(event) |
|
101 { |
|
102 if(!jQuery.ImageBox.opened || jQuery.ImageBox.animationInProgress) |
|
103 return; |
|
104 var pressedKey = event.charCode || event.keyCode || -1; |
|
105 switch (pressedKey) |
|
106 { |
|
107 //end |
|
108 case 35: |
|
109 if (jQuery.ImageBox.currentRel) |
|
110 jQuery.ImageBox.start(null, jQuery('a[@rel=' + jQuery.ImageBox.currentRel+ ']:last').get(0)); |
|
111 break; |
|
112 //home |
|
113 case 36: |
|
114 if (jQuery.ImageBox.currentRel) |
|
115 jQuery.ImageBox.start(null, jQuery('a[@rel=' + jQuery.ImageBox.currentRel+ ']:first').get(0)); |
|
116 break; |
|
117 //left |
|
118 case 37: |
|
119 //backspace |
|
120 case 8: |
|
121 //page up |
|
122 case 33: |
|
123 //p |
|
124 case 80: |
|
125 case 112: |
|
126 var prevEl = jQuery('#ImageBoxPrevImage'); |
|
127 if(prevEl.get(0).onclick != null) { |
|
128 prevEl.get(0).onclick.apply(prevEl.get(0)); |
|
129 } |
|
130 break; |
|
131 //up |
|
132 case 38: |
|
133 break; |
|
134 //right |
|
135 case 39: |
|
136 //page down |
|
137 case 34: |
|
138 //space |
|
139 case 32: |
|
140 //n |
|
141 case 110: |
|
142 case 78: |
|
143 var nextEl = jQuery('#ImageBoxNextImage'); |
|
144 if(nextEl.get(0).onclick != null) { |
|
145 nextEl.get(0).onclick.apply(nextEl.get(0)); |
|
146 } |
|
147 break; |
|
148 //down; |
|
149 case 40: |
|
150 break; |
|
151 //escape |
|
152 case 27: |
|
153 jQuery.ImageBox.hideImage(); |
|
154 break; |
|
155 } |
|
156 }, |
|
157 |
|
158 init : function(options) |
|
159 { |
|
160 if (options) |
|
161 jQuery.extend(jQuery.ImageBox.options, options); |
|
162 if (window.event) { |
|
163 jQuery('body',document).bind('keyup', jQuery.ImageBox.keyPressed); |
|
164 } else { |
|
165 jQuery(document).bind('keyup', jQuery.ImageBox.keyPressed); |
|
166 } |
|
167 jQuery('a').each( |
|
168 function() |
|
169 { |
|
170 el = jQuery(this); |
|
171 relAttr = el.attr('rel')||''; |
|
172 hrefAttr = el.attr('href')||''; |
|
173 imageTypes = /\.jpg|\.jpeg|\.png|\.gif|\.bmp/g; |
|
174 if (hrefAttr.toLowerCase().match(imageTypes) != null && relAttr.toLowerCase().indexOf('imagebox') == 0) { |
|
175 el.bind('click', jQuery.ImageBox.start); |
|
176 } |
|
177 } |
|
178 ); |
|
179 if (jQuery.browser.msie) { |
|
180 iframe = document.createElement('iframe'); |
|
181 jQuery(iframe) |
|
182 .attr( |
|
183 { |
|
184 id : 'ImageBoxIframe', |
|
185 src : 'javascript:false;', |
|
186 frameborder : 'no', |
|
187 scrolling : 'no' |
|
188 } |
|
189 ) |
|
190 .css ( |
|
191 { |
|
192 display : 'none', |
|
193 position : 'absolute', |
|
194 top : '0', |
|
195 left : '0', |
|
196 filter : 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)' |
|
197 } |
|
198 ); |
|
199 jQuery('body').append(iframe); |
|
200 } |
|
201 |
|
202 overlay = document.createElement('div'); |
|
203 jQuery(overlay) |
|
204 .attr('id', 'ImageBoxOverlay') |
|
205 .css( |
|
206 { |
|
207 position : 'absolute', |
|
208 display : 'none', |
|
209 top : '0', |
|
210 left : '0', |
|
211 opacity : 0 |
|
212 } |
|
213 ) |
|
214 .append(document.createTextNode(' ')) |
|
215 .bind('click', jQuery.ImageBox.hideImage); |
|
216 |
|
217 captionText = document.createElement('div'); |
|
218 jQuery(captionText) |
|
219 .attr('id', 'ImageBoxCaptionText') |
|
220 .css( |
|
221 { |
|
222 paddingLeft : jQuery.ImageBox.options.border + 'px' |
|
223 } |
|
224 ) |
|
225 .append(document.createTextNode(' ')); |
|
226 |
|
227 captionImages = document.createElement('div'); |
|
228 jQuery(captionImages) |
|
229 .attr('id', 'ImageBoxCaptionImages') |
|
230 .css( |
|
231 { |
|
232 paddingLeft : jQuery.ImageBox.options.border + 'px', |
|
233 paddingBottom : jQuery.ImageBox.options.border + 'px' |
|
234 } |
|
235 ) |
|
236 .append(document.createTextNode(' ')); |
|
237 |
|
238 closeEl = document.createElement('a'); |
|
239 jQuery(closeEl) |
|
240 .attr( |
|
241 { |
|
242 id : 'ImageBoxClose', |
|
243 href : '#' |
|
244 } |
|
245 ) |
|
246 .css( |
|
247 { |
|
248 position : 'absolute', |
|
249 right : jQuery.ImageBox.options.border + 'px', |
|
250 top : '0' |
|
251 } |
|
252 ) |
|
253 .append(jQuery.ImageBox.options.closeHTML) |
|
254 .bind('click', jQuery.ImageBox.hideImage); |
|
255 |
|
256 captionEl = document.createElement('div'); |
|
257 jQuery(captionEl) |
|
258 .attr('id', 'ImageBoxCaption') |
|
259 .css( |
|
260 { |
|
261 position : 'relative', |
|
262 textAlign : 'left', |
|
263 margin : '0 auto', |
|
264 zIndex : 1 |
|
265 } |
|
266 ) |
|
267 .append(captionText) |
|
268 .append(captionImages) |
|
269 .append(closeEl); |
|
270 |
|
271 loader = document.createElement('img'); |
|
272 loader.src = jQuery.ImageBox.options.loaderSRC; |
|
273 jQuery(loader) |
|
274 .attr('id', 'ImageBoxLoader') |
|
275 .css( |
|
276 { |
|
277 position : 'absolute' |
|
278 } |
|
279 ); |
|
280 |
|
281 prevImage = document.createElement('a'); |
|
282 jQuery(prevImage) |
|
283 .attr( |
|
284 { |
|
285 id : 'ImageBoxPrevImage', |
|
286 href : '#' |
|
287 } |
|
288 ) |
|
289 .css( |
|
290 { |
|
291 position : 'absolute', |
|
292 display : 'none', |
|
293 overflow : 'hidden', |
|
294 textDecoration : 'none' |
|
295 } |
|
296 ) |
|
297 .append(document.createTextNode(' ')); |
|
298 |
|
299 nextImage = document.createElement('a'); |
|
300 jQuery(nextImage) |
|
301 .attr( |
|
302 { |
|
303 id : 'ImageBoxNextImage', |
|
304 href : '#' |
|
305 } |
|
306 ) |
|
307 .css( |
|
308 { |
|
309 position : 'absolute', |
|
310 overflow : 'hidden', |
|
311 textDecoration : 'none' |
|
312 } |
|
313 ) |
|
314 .append(document.createTextNode(' ')); |
|
315 |
|
316 container = document.createElement('div'); |
|
317 jQuery(container) |
|
318 .attr('id', 'ImageBoxContainer') |
|
319 .css( |
|
320 { |
|
321 display : 'none', |
|
322 position : 'relative', |
|
323 overflow : 'hidden', |
|
324 textAlign : 'left', |
|
325 margin : '0 auto', |
|
326 top : '0', |
|
327 left : '0', |
|
328 zIndex : 2 |
|
329 } |
|
330 ) |
|
331 .append([loader, prevImage, nextImage]); |
|
332 |
|
333 outerContainer = document.createElement('div'); |
|
334 jQuery(outerContainer) |
|
335 .attr('id', 'ImageBoxOuterContainer') |
|
336 .css( |
|
337 { |
|
338 display : 'none', |
|
339 position : 'absolute', |
|
340 overflow : 'hidden', |
|
341 top : '0', |
|
342 left : '0', |
|
343 textAlign : 'center', |
|
344 backgroundColor : 'transparent', |
|
345 lineHeigt : '0' |
|
346 } |
|
347 ) |
|
348 .append([container,captionEl]); |
|
349 |
|
350 jQuery('body') |
|
351 .append(overlay) |
|
352 .append(outerContainer); |
|
353 }, |
|
354 |
|
355 start : function(e, elm) |
|
356 { |
|
357 el = elm ? jQuery(elm) : jQuery(this); |
|
358 linkRel = el.attr('rel'); |
|
359 var totalImages, iteration, prevImage, nextImage; |
|
360 if (linkRel != 'imagebox') { |
|
361 jQuery.ImageBox.currentRel = linkRel; |
|
362 gallery = jQuery('a[@rel=' + linkRel + ']'); |
|
363 totalImages = gallery.size(); |
|
364 iteration = gallery.index(elm ? elm : this); |
|
365 prevImage = gallery.get(iteration - 1); |
|
366 nextImage = gallery.get(iteration + 1); |
|
367 } |
|
368 imageSrc = el.attr('href'); |
|
369 captionText = el.attr('title'); |
|
370 pageSize = jQuery.iUtil.getScroll(); |
|
371 overlay = jQuery('#ImageBoxOverlay'); |
|
372 if (!jQuery.ImageBox.opened) { |
|
373 jQuery.ImageBox.opened = true; |
|
374 if (jQuery.browser.msie) { |
|
375 jQuery('#ImageBoxIframe') |
|
376 .css ('height', Math.max(pageSize.ih,pageSize.h) + 'px') |
|
377 .css ('width', Math.max(pageSize.iw,pageSize.w) + 'px') |
|
378 .show(); |
|
379 } |
|
380 overlay |
|
381 .css ('height', Math.max(pageSize.ih,pageSize.h) + 'px') |
|
382 .css ('width', Math.max(pageSize.iw,pageSize.w) + 'px') |
|
383 .show() |
|
384 .fadeTo( |
|
385 300, |
|
386 jQuery.ImageBox.options.overlayOpacity, |
|
387 function() |
|
388 { |
|
389 jQuery.ImageBox.loadImage( |
|
390 imageSrc, |
|
391 captionText, |
|
392 pageSize, |
|
393 totalImages, |
|
394 iteration, |
|
395 prevImage, |
|
396 nextImage |
|
397 ); |
|
398 } |
|
399 ); |
|
400 jQuery('#ImageBoxOuterContainer').css ('width', Math.max(pageSize.iw,pageSize.w) + 'px'); |
|
401 } else { |
|
402 jQuery('#ImageBoxPrevImage').get(0).onclick = null; |
|
403 jQuery('#ImageBoxNextImage').get(0).onclick = null; |
|
404 jQuery.ImageBox.loadImage( |
|
405 imageSrc, |
|
406 captionText, |
|
407 pageSize, |
|
408 totalImages, |
|
409 iteration, |
|
410 prevImage, |
|
411 nextImage |
|
412 ); |
|
413 } |
|
414 return false; |
|
415 }, |
|
416 |
|
417 loadImage : function(imageSrc, captiontext, pageSize, totalImages, iteration, prevImage, nextImage) |
|
418 { |
|
419 jQuery('#ImageBoxCurrentImage').remove(); |
|
420 prevImageEl = jQuery('#ImageBoxPrevImage'); |
|
421 prevImageEl.hide(); |
|
422 nextImageEl = jQuery('#ImageBoxNextImage'); |
|
423 nextImageEl.hide(); |
|
424 loader = jQuery('#ImageBoxLoader'); |
|
425 container = jQuery('#ImageBoxContainer'); |
|
426 outerContainer = jQuery('#ImageBoxOuterContainer'); |
|
427 captionEl = jQuery('#ImageBoxCaption').css('visibility', 'hidden'); |
|
428 jQuery('#ImageBoxCaptionText').html(captionText); |
|
429 jQuery.ImageBox.animationInProgress = true; |
|
430 if (totalImages) |
|
431 jQuery('#ImageBoxCaptionImages').html( |
|
432 jQuery.ImageBox.options.textImage |
|
433 + ' ' + (iteration + 1) + ' ' |
|
434 + jQuery.ImageBox.options.textImageFrom |
|
435 + ' ' + totalImages |
|
436 ); |
|
437 if (prevImage) { |
|
438 prevImageEl.get(0).onclick = function() |
|
439 { |
|
440 this.blur(); |
|
441 jQuery.ImageBox.start(null, prevImage); |
|
442 return false; |
|
443 }; |
|
444 } |
|
445 if (nextImage) { |
|
446 nextImageEl.get(0).onclick =function() |
|
447 { |
|
448 this.blur(); |
|
449 jQuery.ImageBox.start(null, nextImage); |
|
450 return false; |
|
451 }; |
|
452 } |
|
453 loader.show(); |
|
454 containerSize = jQuery.iUtil.getSize(container.get(0)); |
|
455 containerW = Math.max(containerSize.wb, loader.get(0).width + jQuery.ImageBox.options.border * 2); |
|
456 containerH = Math.max(containerSize.hb, loader.get(0).height + jQuery.ImageBox.options.border * 2); |
|
457 loader |
|
458 .css( |
|
459 { |
|
460 left : (containerW - loader.get(0).width)/2 + 'px', |
|
461 top : (containerH - loader.get(0).height)/2 + 'px' |
|
462 } |
|
463 ); |
|
464 container |
|
465 .css( |
|
466 { |
|
467 width : containerW + 'px', |
|
468 height : containerH + 'px' |
|
469 } |
|
470 ) |
|
471 .show(); |
|
472 clientSize = jQuery.iUtil.getClient(); |
|
473 outerContainer |
|
474 .css('top', pageSize.t + (clientSize.h / 15) + 'px'); |
|
475 if (outerContainer.css('display') == 'none') { |
|
476 outerContainer |
|
477 .show() |
|
478 .fadeIn( |
|
479 jQuery.ImageBox.options.fadeDuration |
|
480 ); |
|
481 } |
|
482 imageEl = new Image; |
|
483 jQuery(imageEl) |
|
484 .attr('id', 'ImageBoxCurrentImage') |
|
485 .bind('load', |
|
486 function() |
|
487 { |
|
488 containerW = imageEl.width + jQuery.ImageBox.options.border * 2; |
|
489 containerH = imageEl.height + jQuery.ImageBox.options.border * 2; |
|
490 loader.hide(); |
|
491 container.animate( |
|
492 { |
|
493 height : containerH |
|
494 }, |
|
495 containerSize.hb != containerH ? jQuery.ImageBox.options.fadeDuration : 1, |
|
496 function() |
|
497 { |
|
498 container.animate( |
|
499 { |
|
500 width : containerW |
|
501 }, |
|
502 containerSize.wb != containerW ? jQuery.ImageBox.options.fadeDuration : 1, |
|
503 function() |
|
504 { |
|
505 container.prepend(imageEl); |
|
506 jQuery(imageEl) |
|
507 .css( |
|
508 { |
|
509 position : 'absolute', |
|
510 left : jQuery.ImageBox.options.border + 'px', |
|
511 top : jQuery.ImageBox.options.border + 'px' |
|
512 } |
|
513 ) |
|
514 .fadeIn( |
|
515 jQuery.ImageBox.options.fadeDuration, |
|
516 function() |
|
517 { |
|
518 captionSize = jQuery.iUtil.getSize(captionEl.get(0)); |
|
519 if (prevImage) { |
|
520 prevImageEl |
|
521 .css( |
|
522 { |
|
523 left : jQuery.ImageBox.options.border + 'px', |
|
524 top : jQuery.ImageBox.options.border + 'px', |
|
525 width : containerW/2 - jQuery.ImageBox.options.border * 3 + 'px', |
|
526 height : containerH - jQuery.ImageBox.options.border * 2 + 'px' |
|
527 } |
|
528 ) |
|
529 .show(); |
|
530 } |
|
531 if (nextImage) { |
|
532 nextImageEl |
|
533 .css( |
|
534 { |
|
535 left : containerW/2 + jQuery.ImageBox.options.border * 2 + 'px', |
|
536 top : jQuery.ImageBox.options.border + 'px', |
|
537 width : containerW/2 - jQuery.ImageBox.options.border * 3 + 'px', |
|
538 height : containerH - jQuery.ImageBox.options.border * 2 + 'px' |
|
539 } |
|
540 ) |
|
541 .show(); |
|
542 } |
|
543 captionEl |
|
544 .css( |
|
545 { |
|
546 width : containerW + 'px', |
|
547 top : - captionSize.hb + 'px', |
|
548 visibility : 'visible' |
|
549 } |
|
550 ) |
|
551 .animate( |
|
552 { |
|
553 top : -1 |
|
554 }, |
|
555 jQuery.ImageBox.options.fadeDuration, |
|
556 function() |
|
557 { |
|
558 jQuery.ImageBox.animationInProgress = false; |
|
559 } |
|
560 ); |
|
561 } |
|
562 ); |
|
563 } |
|
564 ); |
|
565 } |
|
566 ); |
|
567 } |
|
568 ); |
|
569 imageEl.src = imageSrc; |
|
570 |
|
571 }, |
|
572 |
|
573 hideImage : function() |
|
574 { |
|
575 jQuery('#ImageBoxCurrentImage').remove(); |
|
576 jQuery('#ImageBoxOuterContainer').hide(); |
|
577 jQuery('#ImageBoxCaption').css('visibility', 'hidden'); |
|
578 jQuery('#ImageBoxOverlay').fadeTo( |
|
579 300, |
|
580 0, |
|
581 function(){ |
|
582 jQuery(this).hide(); |
|
583 if (jQuery.browser.msie) { |
|
584 jQuery('#ImageBoxIframe').hide(); |
|
585 } |
|
586 } |
|
587 ); |
|
588 jQuery('#ImageBoxPrevImage').get(0).onclick = null; |
|
589 jQuery('#ImageBoxNextImage').get(0).onclick = null; |
|
590 jQuery.ImageBox.currentRel = null; |
|
591 jQuery.ImageBox.opened = false; |
|
592 jQuery.ImageBox.animationInProgress = false; |
|
593 return false; |
|
594 } |
|
595 }; |