/* ------------------------------------------------------------------------
class: prettyphoto
use: lightbox clone for jquery
author: stephane caron (http://www.no-margin-for-errors.com)
version: 2.5.5
------------------------------------------------------------------------- */
(function($) {
$.prettyphoto = {version: '2.5.5'};
$.fn.prettyphoto = function(settings) {
settings = jquery.extend({
animationspeed: 'normal', /* fast/slow/normal */
opacity: 0.80, /* value between 0 and 1 */
showtitle: true, /* true/false */
allowresize: true, /* true/false */
default_width: 500,
default_height: 344,
counter_separator_label: '/', /* the separator for the gallery counter 1 "of" 2 */
theme: 'light_rounded', /* light_rounded / dark_rounded / light_square / dark_square / facebook */
hideflash: false, /* hides all the flash object on a page, set to true if flash appears over prettyphoto */
wmode: 'opaque', /* set the flash wmode attribute */
autoplay: true, /* automatically start videos: true/false */
modal: false, /* if set to true, only the close button will close the window */
changepicturecallback: function(){}, /* called everytime an item is shown/changed */
callback: function(){}, /* called when prettyphoto is closed */
markup: '
'
}, settings);
// fallback to a supported theme for ie6
if($.browser.msie && $.browser.version == 6){
settings.theme = "light_square";
}
if(!$pp_overlay) _buildoverlay(); // if the overlay is not there, inject it!
// global variables accessible only by prettyphoto
var doresize = true, percentbased = false, correctsizes,
// cached selectors
$pp_pic_holder, $ppt, $pp_overlay,
// prettyphoto container specific
pp_contentheight, pp_contentwidth, pp_containerheight, pp_containerwidth,
// window size
windowheight = $(window).height(), windowwidth = $(window).width(),
//gallery specific
setposition = 0,
// global elements
scrollpos = _getscroll();
// window/keyboard events
$(window).scroll(function(){ scrollpos = _getscroll(); _centeroverlay(); _resizeoverlay(); });
$(window).resize(function(){ _centeroverlay(); _resizeoverlay(); });
$(document).keydown(function(e){
if($pp_pic_holder.is(':visible'))
switch(e.keycode){
case 37:
$.prettyphoto.changepage('previous');
break;
case 39:
$.prettyphoto.changepage('next');
break;
case 27:
if(!settings.modal)
$.prettyphoto.close();
break;
};
});
// bind the code to each links
$(this).each(function(){
$(this).bind('click',function(){
_self = this; // fix scoping
// find out if the picture is part of a set
therel = $(this).attr('rel');
galleryregexp = /\[(?:.*)\]/;
thegallery = galleryregexp.exec(therel);
// build the gallery array
var images = new array(), titles = new array(), descriptions = new array();
if(thegallery){
$('a[rel*='+thegallery+']').each(function(i){
if($(this)[0] === $(_self)[0]) setposition = i; // get the position in the set
images.push($(this).attr('href'));
titles.push($(this).find('img').attr('alt'));
descriptions.push($(this).attr('title'));
});
}else{
images = $(this).attr('href');
titles = ($(this).find('img').attr('alt')) ? $(this).find('img').attr('alt') : '';
descriptions = ($(this).attr('title')) ? $(this).attr('title') : '';
}
$.prettyphoto.open(images,titles,descriptions);
return false;
});
});
/**
* opens the prettyphoto modal box.
* @param image {string,array} full path to the image to be open, can also be an array containing full images paths.
* @param title {string,array} the title to be displayed with the picture, can also be an array containing all the titles.
* @param description {string,array} the description to be displayed with the picture, can also be an array containing all the descriptions.
*/
$.prettyphoto.open = function(gallery_images,gallery_titles,gallery_descriptions) {
// to fix the bug with ie select boxes
if($.browser.msie && $.browser.version == 6){
$('select').css('visibility','hidden');
};
if(settings.hideflash) $('object,embed').css('visibility','hidden'); // hide the flash
// convert everything to an array in the case it's a single item
images = $.makearray(gallery_images);
titles = $.makearray(gallery_titles);
descriptions = $.makearray(gallery_descriptions);
image_set = ($(images).size() > 0) ? true : false; // find out if it's a set
// hide the next/previous links if on first or last images.
_checkposition($(images).size());
$('.pp_loadericon').show(); // do i need to explain?
// fade the content in
$pp_overlay.show().fadeto(settings.animationspeed,settings.opacity);
// display the current position
$pp_pic_holder.find('.currenttextholder').text((setposition+1) + settings.counter_separator_label + $(images).size());
// set the description
if(descriptions[setposition]){
$pp_pic_holder.find('.pp_description').show().html(unescape(descriptions[setposition]));
}else{
$pp_pic_holder.find('.pp_description').hide().text('');
};
// set the title
if(titles[setposition] && settings.showtitle){
hastitle = true;
$ppt.html(unescape(titles[setposition]));
}else{
hastitle = false;
};
// get the dimensions
movie_width = ( parsefloat(grab_param('width',images[setposition])) ) ? grab_param('width',images[setposition]) : settings.default_width.tostring();
movie_height = ( parsefloat(grab_param('height',images[setposition])) ) ? grab_param('height',images[setposition]) : settings.default_height.tostring();
// if the size is % based, calculate according to window dimensions
if(movie_width.indexof('%') != -1 || movie_height.indexof('%') != -1){
movie_height = parsefloat(($(window).height() * parsefloat(movie_height) / 100) - 100);
movie_width = parsefloat(($(window).width() * parsefloat(movie_width) / 100) - 100);
percentbased = true;
}
imgpreloader = "";
// inject the proper content
switch(_getfiletype(images[setposition])){
case 'image':
// set the new image
imgpreloader = new image();
// preload the neighbour images
nextimage = new image();
if(image_set && setposition > $(images).size()) nextimage.src = images[setposition + 1];
previmage = new image();
if(image_set && images[setposition - 1]) previmage.src = images[setposition - 1];
$pp_pic_holder.find('#pp_full_res')[0].innerhtml = settings.image_markup;
$pp_pic_holder.find('#fullresimage').attr('src',images[setposition]);
imgpreloader.onload = function(){
// fit item to viewport
correctsizes = _fittoviewport(imgpreloader.width,imgpreloader.height);
_showcontent();
};
imgpreloader.onerror = function(){
alert('image cannot be loaded. make sure the path is correct and image exist.');
$.prettyphoto.close();
};
imgpreloader.src = images[setposition];
break;
case 'youtube':
correctsizes = _fittoviewport(movie_width,movie_height); // fit item to viewport
movie = 'http://www.youtube.com/v/'+grab_param('v',images[setposition]);
if(settings.autoplay) movie += "&autoplay=1";
toinject = settings.flash_markup.replace(/{width}/g,correctsizes['width']).replace(/{height}/g,correctsizes['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);
break;
case 'vimeo':
correctsizes = _fittoviewport(movie_width,movie_height); // fit item to viewport
movie_id = images[setposition];
movie = 'http://vimeo.com/moogaloop.swf?clip_id='+ movie_id.replace('http://vimeo.com/','');
if(settings.autoplay) movie += "&autoplay=1";
toinject = settings.flash_markup.replace(/{width}/g,correctsizes['width']).replace(/{height}/g,correctsizes['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);
break;
case 'quicktime':
correctsizes = _fittoviewport(movie_width,movie_height); // fit item to viewport
correctsizes['height']+=15; correctsizes['contentheight']+=15; correctsizes['containerheight']+=15; // add space for the control bar
toinject = settings.quicktime_markup.replace(/{width}/g,correctsizes['width']).replace(/{height}/g,correctsizes['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,images[setposition]).replace(/{autoplay}/g,settings.autoplay);
break;
case 'flash':
correctsizes = _fittoviewport(movie_width,movie_height); // fit item to viewport
flash_vars = images[setposition];
flash_vars = flash_vars.substring(images[setposition].indexof('flashvars') + 10,images[setposition].length);
filename = images[setposition];
filename = filename.substring(0,filename.indexof('?'));
toinject = settings.flash_markup.replace(/{width}/g,correctsizes['width']).replace(/{height}/g,correctsizes['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+'?'+flash_vars);
break;
case 'iframe':
correctsizes = _fittoviewport(movie_width,movie_height); // fit item to viewport
frame_url = images[setposition];
frame_url = frame_url.substr(0,frame_url.indexof('iframe')-1);
toinject = settings.iframe_markup.replace(/{width}/g,correctsizes['width']).replace(/{height}/g,correctsizes['height']).replace(/{path}/g,frame_url);
break;
case 'inline':
// to get the item height clone it, apply default width, wrap it in the prettyphoto containers , then delete
myclone = $(images[setposition]).clone().css({'width':settings.default_width}).wrapinner('
').appendto($('body'));
correctsizes = _fittoviewport($(myclone).width(),$(myclone).height());
$(myclone).remove();
toinject = settings.inline_markup.replace(/{content}/g,$(images[setposition]).html());
break;
};
if(!imgpreloader){
$pp_pic_holder.find('#pp_full_res')[0].innerhtml = toinject;
// show content
_showcontent();
};
};
/**
* change page in the prettyphoto modal box
* @param direction {string} direction of the paging, previous or next.
*/
$.prettyphoto.changepage = function(direction){
if(direction == 'previous') {
setposition--;
if (setposition < 0){
setposition = 0;
return;
};
}else{
if($('.pp_arrow_next').is('.disabled')) return;
setposition++;
};
// allow the resizing of the images
if(!doresize) doresize = true;
_hidecontent(function(){$.prettyphoto.open(images,titles,descriptions)});
$('a.pp_expand,a.pp_contract').fadeout(settings.animationspeed);
};
/**
* closes the prettyphoto modal box.
*/
$.prettyphoto.close = function(){
$pp_pic_holder.find('object,embed').css('visibility','hidden');
$('div.pp_pic_holder,div.ppt,.pp_fade').fadeout(settings.animationspeed);
$pp_overlay.fadeout(settings.animationspeed, function(){
$pp_pic_holder.attr('style','').find('div:not(.pp_hovercontainer)').attr('style',''); // reset the width and everything that has been set.
_centeroverlay(); // center it
// to fix the bug with ie select boxes
if($.browser.msie && $.browser.version == 6){
$('select').css('visibility','visible');
};
// show the flash
if(settings.hideflash) $('object,embed').css('visibility','visible');
setposition = 0;
settings.callback();
});
doresize = true;
};
/**
* set the proper sizes on the containers and animate the content in.
*/
_showcontent = function(){
$('.pp_loadericon').hide();
// calculate the opened top position of the pic holder
projectedtop = scrollpos['scrolltop'] + ((windowheight/2) - (correctsizes['containerheight']/2));
if(projectedtop < 0) projectedtop = 0 + $ppt.height();
// resize the content holder
$pp_pic_holder.find('.pp_content').animate({'height':correctsizes['contentheight']},settings.animationspeed);
// resize picture the holder
$pp_pic_holder.animate({
'top': projectedtop,
'left': (windowwidth/2) - (correctsizes['containerwidth']/2),
'width': correctsizes['containerwidth']
},settings.animationspeed,function(){
$pp_pic_holder.find('.pp_hovercontainer,#fullresimage').height(correctsizes['height']).width(correctsizes['width']);
// fade the new image
$pp_pic_holder.find('.pp_fade').fadein(settings.animationspeed);
// show the nav
if(image_set && _getfiletype(images[setposition])=="image") { $pp_pic_holder.find('.pp_hovercontainer').show(); }else{ $pp_pic_holder.find('.pp_hovercontainer').hide(); }
// show the title
if(settings.showtitle && hastitle){
$ppt.css({
'top' : $pp_pic_holder.offset().top - 25,
'left' : $pp_pic_holder.offset().left + 20,
'display' : 'none'
});
$ppt.fadein(settings.animationspeed);
};
// fade the resizing link if the image is resized
if(correctsizes['resized']) $('a.pp_expand,a.pp_contract').fadein(settings.animationspeed);
// callback!
settings.changepicturecallback();
});
};
/**
* hide the content...duh!
*/
function _hidecontent(callback){
// fade out the current picture
$pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');
$pp_pic_holder.find('.pp_fade').fadeout(settings.animationspeed,function(){
$('.pp_loadericon').show();
if(callback) callback();
});
// hide the title
$ppt.fadeout(settings.animationspeed);
}
/**
* check the item position in the gallery array, hide or show the navigation links
* @param setcount {integer} the total number of items in the set
*/
function _checkposition(setcount){
// if at the end, hide the next link
if(setposition == setcount-1) {
$pp_pic_holder.find('a.pp_next').css('visibility','hidden');
$pp_pic_holder.find('a.pp_arrow_next').addclass('disabled').unbind('click');
}else{
$pp_pic_holder.find('a.pp_next').css('visibility','visible');
$pp_pic_holder.find('a.pp_arrow_next.disabled').removeclass('disabled').bind('click',function(){
$.prettyphoto.changepage('next');
return false;
});
};
// if at the beginning, hide the previous link
if(setposition == 0) {
$pp_pic_holder.find('a.pp_previous').css('visibility','hidden');
$pp_pic_holder.find('a.pp_arrow_previous').addclass('disabled').unbind('click');
}else{
$pp_pic_holder.find('a.pp_previous').css('visibility','visible');
$pp_pic_holder.find('a.pp_arrow_previous.disabled').removeclass('disabled').bind('click',function(){
$.prettyphoto.changepage('previous');
return false;
});
};
// hide the bottom nav if it's not a set.
if(setcount > 1) {
$('.pp_nav').show();
}else{
$('.pp_nav').hide();
}
};
/**
* resize the item dimensions if it's bigger than the viewport
* @param width {integer} width of the item to be opened
* @param height {integer} height of the item to be opened
* @return an array containin the "fitted" dimensions
*/
function _fittoviewport(width,height){
hasbeenresized = false;
_getdimensions(width,height);
// define them in case there's no resize needed
imagewidth = width;
imageheight = height;
if( ((pp_containerwidth > windowwidth) || (pp_containerheight > windowheight)) && doresize && settings.allowresize && !percentbased) {
hasbeenresized = true;
notfitting = true;
while (notfitting){
if((pp_containerwidth > windowwidth)){
imagewidth = (windowwidth - 200);
imageheight = (height/width) * imagewidth;
}else if((pp_containerheight > windowheight)){
imageheight = (windowheight - 200);
imagewidth = (width/height) * imageheight;
}else{
notfitting = false;
};
pp_containerheight = imageheight;
pp_containerwidth = imagewidth;
};
_getdimensions(imagewidth,imageheight);
};
return {
width:math.floor(imagewidth),
height:math.floor(imageheight),
containerheight:math.floor(pp_containerheight),
containerwidth:math.floor(pp_containerwidth) + 40,
contentheight:math.floor(pp_contentheight),
contentwidth:math.floor(pp_contentwidth),
resized:hasbeenresized
};
};
/**
* get the containers dimensions according to the item size
* @param width {integer} width of the item to be opened
* @param height {integer} height of the item to be opened
*/
function _getdimensions(width,height){
width = parsefloat(width);
height = parsefloat(height);
// get the details height, to do so, i need to clone it since it's invisible
$pp_details = $pp_pic_holder.find('.pp_details');
$pp_details.width(width);
detailsheight = parsefloat($pp_details.css('margintop')) + parsefloat($pp_details.css('marginbottom'));
$pp_details = $pp_details.clone().appendto($('body')).css({
'position':'absolute',
'top':-10000
});
detailsheight += $pp_details.height();
detailsheight = (detailsheight <= 34) ? 36 : detailsheight; // min-height for the details
if($.browser.msie && $.browser.version==7) detailsheight+=8;
$pp_details.remove();
// get the container size, to resize the holder to the right dimensions
pp_contentheight = height + detailsheight;
pp_contentwidth = width;
pp_containerheight = pp_contentheight + $ppt.height() + $pp_pic_holder.find('.pp_top').height() + $pp_pic_holder.find('.pp_bottom').height();
pp_containerwidth = width;
}
function _getfiletype(itemsrc){
if (itemsrc.match(/youtube\.com\/watch/i)) {
return 'youtube';
}else if (itemsrc.match(/vimeo\.com/i)) {
return 'vimeo';
}else if(itemsrc.indexof('.mov') != -1){
return 'quicktime';
}else if(itemsrc.indexof('.swf') != -1){
return 'flash';
}else if(itemsrc.indexof('iframe') != -1){
return 'iframe'
}else if(itemsrc.substr(0,1) == '#'){
return 'inline';
}else{
return 'image';
};
};
function _centeroverlay(){
if(doresize) {
titleheight = $ppt.height();
contentheight = $pp_pic_holder.height();
contentwidth = $pp_pic_holder.width();
projectedtop = (windowheight/2) + scrollpos['scrolltop'] - ((contentheight+titleheight)/2);
$pp_pic_holder.css({
'top': projectedtop,
'left': (windowwidth/2) + scrollpos['scrollleft'] - (contentwidth/2)
});
$ppt.css({
'top' : projectedtop - titleheight,
'left': (windowwidth/2) + scrollpos['scrollleft'] - (contentwidth/2) + 20
});
};
};
function _getscroll(){
if (self.pageyoffset) {
return {scrolltop:self.pageyoffset,scrollleft:self.pagexoffset};
} else if (document.documentelement && document.documentelement.scrolltop) { // explorer 6 strict
return {scrolltop:document.documentelement.scrolltop,scrollleft:document.documentelement.scrollleft};
} else if (document.body) {// all other explorers
return {scrolltop:document.body.scrolltop,scrollleft:document.body.scrollleft};
};
};
function _resizeoverlay() {
windowheight = $(window).height();
windowwidth = $(window).width();
$pp_overlay.css({
'height':$(document).height()
});
};
function _buildoverlay(){
// inject the markup
$('body').append(settings.markup);
// set my global selectors
$pp_pic_holder = $('.pp_pic_holder');
$ppt = $('.ppt');
$pp_overlay = $('div.pp_overlay');
$pp_pic_holder.attr('class','pp_pic_holder ' + settings.theme); // set the proper theme
$pp_overlay
.css({
'opacity':0,
'height':$(document).height()
})
.bind('click',function(){
if(!settings.modal)
$.prettyphoto.close();
});
$('a.pp_close').bind('click',function(){ $.prettyphoto.close(); return false; });
$('a.pp_expand').bind('click',function(){
$this = $(this); // fix scoping
// expand the image
if($this.hasclass('pp_expand')){
$this.removeclass('pp_expand').addclass('pp_contract');
doresize = false;
}else{
$this.removeclass('pp_contract').addclass('pp_expand');
doresize = true;
};
_hidecontent(function(){ $.prettyphoto.open(images,titles,descriptions) });
$pp_pic_holder.find('.pp_fade').fadeout(settings.animationspeed);
return false;
});
$pp_pic_holder.find('.pp_previous, .pp_arrow_previous').bind('click',function(){
$.prettyphoto.changepage('previous');
return false;
});
$pp_pic_holder.find('.pp_next, .pp_arrow_next').bind('click',function(){
$.prettyphoto.changepage('next');
return false;
});
};
_centeroverlay(); // center it
};
function grab_param(name,url){
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexs = "[\\?&]"+name+"=([^]*)";
var regex = new regexp( regexs );
var results = regex.exec( url );
if( results == null )
return "";
else
return results[1];
}
})(jquery);