jquery.prettyPhoto.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  1. /* ------------------------------------------------------------------------
  2. Class: prettyPhoto
  3. Use: Lightbox clone for jQuery
  4. Author: Stephane Caron (http://www.no-margin-for-errors.com)
  5. Version: 3.1.6
  6. ------------------------------------------------------------------------- */
  7. (function($) {
  8. $.prettyPhoto = {version: '3.1.6'};
  9. $.fn.prettyPhoto = function(pp_settings) {
  10. pp_settings = jQuery.extend({
  11. hook: 'rel', /* the attribute tag to use for prettyPhoto hooks. default: 'rel'. For HTML5, use "data-rel" or similar. */
  12. animation_speed: 'fast', /* fast/slow/normal */
  13. ajaxcallback: function() {},
  14. slideshow: 5000, /* false OR interval time in ms */
  15. autoplay_slideshow: false, /* true/false */
  16. opacity: 0.80, /* Value between 0 and 1 */
  17. show_title: true, /* true/false */
  18. allow_resize: true, /* Resize the photos bigger than viewport. true/false */
  19. allow_expand: true, /* Allow the user to expand a resized image. true/false */
  20. default_width: 500,
  21. default_height: 344,
  22. counter_separator_label: '/', /* The separator for the gallery counter 1 "of" 2 */
  23. theme: 'pp_default', /* light_rounded / dark_rounded / light_square / dark_square / facebook */
  24. horizontal_padding: 20, /* The padding on each side of the picture */
  25. hideflash: false, /* Hides all the flash object on a page, set to TRUE if flash appears over prettyPhoto */
  26. wmode: 'opaque', /* Set the flash wmode attribute */
  27. autoplay: true, /* Automatically start videos: True/False */
  28. modal: false, /* If set to true, only the close button will close the window */
  29. deeplinking: true, /* Allow prettyPhoto to update the url to enable deeplinking. */
  30. overlay_gallery: true, /* If set to true, a gallery will overlay the fullscreen image on mouse over */
  31. overlay_gallery_max: 30, /* Maximum number of pictures in the overlay gallery */
  32. keyboard_shortcuts: true, /* Set to false if you open forms inside prettyPhoto */
  33. changepicturecallback: function(){}, /* Called everytime an item is shown/changed */
  34. callback: function(){}, /* Called when prettyPhoto is closed */
  35. ie6_fallback: true,
  36. markup: '<div class="pp_pic_holder"> \
  37. <div class="ppt">&nbsp;</div> \
  38. <div class="pp_top"> \
  39. <div class="pp_left"></div> \
  40. <div class="pp_middle"></div> \
  41. <div class="pp_right"></div> \
  42. </div> \
  43. <div class="pp_content_container"> \
  44. <div class="pp_left"> \
  45. <div class="pp_right"> \
  46. <div class="pp_content"> \
  47. <div class="pp_loaderIcon"></div> \
  48. <div class="pp_fade"> \
  49. <a href="#" class="pp_expand" title="Expand the image">Expand</a> \
  50. <div class="pp_hoverContainer"> \
  51. <a class="pp_next" href="#">next</a> \
  52. <a class="pp_previous" href="#">previous</a> \
  53. </div> \
  54. <div id="pp_full_res"></div> \
  55. <div class="pp_details"> \
  56. <div class="pp_nav"> \
  57. <a href="#" class="pp_arrow_previous">Previous</a> \
  58. <p class="currentTextHolder">0/0</p> \
  59. <a href="#" class="pp_arrow_next">Next</a> \
  60. </div> \
  61. <p class="pp_description"></p> \
  62. <div class="pp_social">{pp_social}</div> \
  63. <a class="pp_close" href="#">Close</a> \
  64. </div> \
  65. </div> \
  66. </div> \
  67. </div> \
  68. </div> \
  69. </div> \
  70. <div class="pp_bottom"> \
  71. <div class="pp_left"></div> \
  72. <div class="pp_middle"></div> \
  73. <div class="pp_right"></div> \
  74. </div> \
  75. </div> \
  76. <div class="pp_overlay"></div>',
  77. gallery_markup: '<div class="pp_gallery"> \
  78. <a href="#" class="pp_arrow_previous">Previous</a> \
  79. <div> \
  80. <ul> \
  81. {gallery} \
  82. </ul> \
  83. </div> \
  84. <a href="#" class="pp_arrow_next">Next</a> \
  85. </div>',
  86. image_markup: '<img id="fullResImage" src="{path}" />',
  87. flash_markup: '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="{width}" height="{height}"><param name="wmode" value="{wmode}" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="{path}" /><embed src="{path}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="{width}" height="{height}" wmode="{wmode}"></embed></object>',
  88. quicktime_markup: '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="https://www.apple.com/qtactivex/qtplugin.cab" height="{height}" width="{width}"><param name="src" value="{path}"><param name="autoplay" value="{autoplay}"><param name="type" value="video/quicktime"><embed src="{path}" height="{height}" width="{width}" autoplay="{autoplay}" type="video/quicktime" pluginspage="https://www.apple.com/quicktime/download/"></embed></object>',
  89. iframe_markup: '<iframe src ="{path}" width="{width}" height="{height}" frameborder="no"></iframe>',
  90. inline_markup: '<div class="pp_inline">{content}</div>',
  91. custom_markup: '',
  92. social_tools: '<div class="twitter"><a href="//twitter.com/share" class="twitter-share-button" data-count="none">Tweet</a><script type="text/javascript" src="//platform.twitter.com/widgets.js"></script></div><div class="facebook"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href={location_href}&amp;layout=button_count&amp;show_faces=true&amp;width=500&amp;action=like&amp;font&amp;colorscheme=light&amp;height=23" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:500px; height:23px;" allowTransparency="true"></iframe></div>' /* html or false to disable */
  93. }, pp_settings);
  94. // Global variables accessible only by prettyPhoto
  95. var matchedObjects = this, percentBased = false, pp_dimensions, pp_open,
  96. // prettyPhoto container specific
  97. pp_contentHeight, pp_contentWidth, pp_containerHeight, pp_containerWidth,
  98. // Window size
  99. windowHeight = $(window).height(), windowWidth = $(window).width(),
  100. // Global elements
  101. pp_slideshow;
  102. doresize = true, scroll_pos = _get_scroll();
  103. // Window/Keyboard events
  104. $(window).unbind('resize.prettyphoto').bind('resize.prettyphoto',function(){ _center_overlay(); _resize_overlay(); });
  105. if(pp_settings.keyboard_shortcuts) {
  106. $(document).unbind('keydown.prettyphoto').bind('keydown.prettyphoto',function(e){
  107. if(typeof $pp_pic_holder != 'undefined'){
  108. if($pp_pic_holder.is(':visible')){
  109. switch(e.keyCode){
  110. case 37:
  111. $.prettyPhoto.changePage('previous');
  112. e.preventDefault();
  113. break;
  114. case 39:
  115. $.prettyPhoto.changePage('next');
  116. e.preventDefault();
  117. break;
  118. case 27:
  119. if(!settings.modal)
  120. $.prettyPhoto.close();
  121. e.preventDefault();
  122. break;
  123. };
  124. // return false;
  125. };
  126. };
  127. });
  128. };
  129. /**
  130. * Initialize prettyPhoto.
  131. */
  132. $.prettyPhoto.initialize = function() {
  133. settings = pp_settings;
  134. if(settings.theme == 'pp_default') settings.horizontal_padding = 16;
  135. // Find out if the picture is part of a set
  136. theRel = $(this).attr(settings.hook);
  137. galleryRegExp = /\[(?:.*)\]/;
  138. isSet = (galleryRegExp.exec(theRel)) ? true : false;
  139. // Put the SRCs, TITLEs, ALTs into an array.
  140. pp_images = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return $(n).attr('href'); }) : $.makeArray($(this).attr('href'));
  141. pp_titles = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return ($(n).find('img').attr('alt')) ? $(n).find('img').attr('alt') : ""; }) : $.makeArray($(this).find('img').attr('alt'));
  142. pp_descriptions = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return ($(n).attr('title')) ? $(n).attr('title') : ""; }) : $.makeArray($(this).attr('title'));
  143. if(pp_images.length > settings.overlay_gallery_max) settings.overlay_gallery = false;
  144. set_position = jQuery.inArray($(this).attr('href'), pp_images); // Define where in the array the clicked item is positionned
  145. rel_index = (isSet) ? set_position : $("a["+settings.hook+"^='"+theRel+"']").index($(this));
  146. _build_overlay(this); // Build the overlay {this} being the caller
  147. if(settings.allow_resize)
  148. $(window).bind('scroll.prettyphoto',function(){ _center_overlay(); });
  149. $.prettyPhoto.open();
  150. return false;
  151. }
  152. /**
  153. * Opens the prettyPhoto modal box.
  154. * @param image {String,Array} Full path to the image to be open, can also be an array containing full images paths.
  155. * @param title {String,Array} The title to be displayed with the picture, can also be an array containing all the titles.
  156. * @param description {String,Array} The description to be displayed with the picture, can also be an array containing all the descriptions.
  157. */
  158. $.prettyPhoto.open = function(event) {
  159. if(typeof settings == "undefined"){ // Means it's an API call, need to manually get the settings and set the variables
  160. settings = pp_settings;
  161. pp_images = $.makeArray(arguments[0]);
  162. pp_titles = (arguments[1]) ? $.makeArray(arguments[1]) : $.makeArray("");
  163. pp_descriptions = (arguments[2]) ? $.makeArray(arguments[2]) : $.makeArray("");
  164. isSet = (pp_images.length > 1) ? true : false;
  165. set_position = (arguments[3])? arguments[3]: 0;
  166. _build_overlay(event.target); // Build the overlay {this} being the caller
  167. }
  168. if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','hidden'); // Hide the flash
  169. _checkPosition($(pp_images).length); // Hide the next/previous links if on first or last images.
  170. $('.pp_loaderIcon').show();
  171. if(settings.deeplinking)
  172. setHashtag();
  173. // Rebuild Facebook Like Button with updated href
  174. if(settings.social_tools){
  175. facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
  176. $pp_pic_holder.find('.pp_social').html(facebook_like_link);
  177. }
  178. // Fade the content in
  179. if($ppt.is(':hidden')) $ppt.css('opacity',0).show();
  180. $pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity);
  181. // Display the current position
  182. $pp_pic_holder.find('.currentTextHolder').text((set_position+1) + settings.counter_separator_label + $(pp_images).length);
  183. // Set the description
  184. if(typeof pp_descriptions[set_position] != 'undefined' && pp_descriptions[set_position] != ""){
  185. $pp_pic_holder.find('.pp_description').show().html(unescape(pp_descriptions[set_position]));
  186. }else{
  187. $pp_pic_holder.find('.pp_description').hide();
  188. }
  189. // Get the dimensions
  190. movie_width = ( parseFloat(getParam('width',pp_images[set_position])) ) ? getParam('width',pp_images[set_position]) : settings.default_width.toString();
  191. movie_height = ( parseFloat(getParam('height',pp_images[set_position])) ) ? getParam('height',pp_images[set_position]) : settings.default_height.toString();
  192. // If the size is % based, calculate according to window dimensions
  193. percentBased=false;
  194. if(movie_height.indexOf('%') != -1) { movie_height = parseFloat(($(window).height() * parseFloat(movie_height) / 100) - 150); percentBased = true; }
  195. if(movie_width.indexOf('%') != -1) { movie_width = parseFloat(($(window).width() * parseFloat(movie_width) / 100) - 150); percentBased = true; }
  196. // Fade the holder
  197. $pp_pic_holder.fadeIn(function(){
  198. // Set the title
  199. (settings.show_title && pp_titles[set_position] != "" && typeof pp_titles[set_position] != "undefined") ? $ppt.html(unescape(pp_titles[set_position])) : $ppt.html('&nbsp;');
  200. imgPreloader = "";
  201. skipInjection = false;
  202. // Inject the proper content
  203. switch(_getFileType(pp_images[set_position])){
  204. case 'image':
  205. imgPreloader = new Image();
  206. // Preload the neighbour images
  207. nextImage = new Image();
  208. if(isSet && set_position < $(pp_images).length -1) nextImage.src = pp_images[set_position + 1];
  209. prevImage = new Image();
  210. if(isSet && pp_images[set_position - 1]) prevImage.src = pp_images[set_position - 1];
  211. $pp_pic_holder.find('#pp_full_res')[0].innerHTML = settings.image_markup.replace(/{path}/g,pp_images[set_position]);
  212. imgPreloader.onload = function(){
  213. // Fit item to viewport
  214. pp_dimensions = _fitToViewport(imgPreloader.width,imgPreloader.height);
  215. _showContent();
  216. };
  217. imgPreloader.onerror = function(){
  218. alert('Image cannot be loaded. Make sure the path is correct and image exist.');
  219. $.prettyPhoto.close();
  220. };
  221. imgPreloader.src = pp_images[set_position];
  222. break;
  223. case 'youtube':
  224. pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
  225. // Regular youtube link
  226. movie_id = getParam('v',pp_images[set_position]);
  227. // youtu.be link
  228. if(movie_id == ""){
  229. movie_id = pp_images[set_position].split('youtu.be/');
  230. movie_id = movie_id[1];
  231. if(movie_id.indexOf('?') > 0)
  232. movie_id = movie_id.substr(0,movie_id.indexOf('?')); // Strip anything after the ?
  233. if(movie_id.indexOf('&') > 0)
  234. movie_id = movie_id.substr(0,movie_id.indexOf('&')); // Strip anything after the &
  235. }
  236. movie = '//www.youtube.com/embed/'+movie_id;
  237. (getParam('rel',pp_images[set_position])) ? movie+="?rel="+getParam('rel',pp_images[set_position]) : movie+="?rel=1";
  238. if(settings.autoplay) movie += "&autoplay=1";
  239. toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);
  240. break;
  241. case 'vimeo':
  242. pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
  243. movie_id = pp_images[set_position];
  244. var regExp = /http(s?):\/\/(www\.)?vimeo.com\/(\d+)/;
  245. var match = movie_id.match(regExp);
  246. movie = '//player.vimeo.com/video/'+ match[3] +'?title=0&amp;byline=0&amp;portrait=0';
  247. if(settings.autoplay) movie += "&autoplay=1;";
  248. vimeo_width = pp_dimensions['width'] + '/embed/?moog_width='+ pp_dimensions['width'];
  249. toInject = settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,movie);
  250. break;
  251. case 'quicktime':
  252. pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
  253. pp_dimensions['height']+=15; pp_dimensions['contentHeight']+=15; pp_dimensions['containerHeight']+=15; // Add space for the control bar
  254. toInject = settings.quicktime_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);
  255. break;
  256. case 'flash':
  257. pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
  258. flash_vars = pp_images[set_position];
  259. flash_vars = flash_vars.substring(pp_images[set_position].indexOf('flashvars') + 10,pp_images[set_position].length);
  260. filename = pp_images[set_position];
  261. filename = filename.substring(0,filename.indexOf('?'));
  262. toInject = settings.flash_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+'?'+flash_vars);
  263. break;
  264. case 'iframe':
  265. pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
  266. frame_url = pp_images[set_position];
  267. frame_url = frame_url.substr(0,frame_url.indexOf('iframe')-1);
  268. toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,frame_url);
  269. break;
  270. case 'ajax':
  271. doresize = false; // Make sure the dimensions are not resized.
  272. pp_dimensions = _fitToViewport(movie_width,movie_height);
  273. doresize = true; // Reset the dimensions
  274. skipInjection = true;
  275. $.get(pp_images[set_position],function(responseHTML){
  276. toInject = settings.inline_markup.replace(/{content}/g,responseHTML);
  277. $pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
  278. _showContent();
  279. });
  280. break;
  281. case 'custom':
  282. pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
  283. toInject = settings.custom_markup;
  284. break;
  285. case 'inline':
  286. // to get the item height clone it, apply default width, wrap it in the prettyPhoto containers , then delete
  287. myClone = $(pp_images[set_position]).clone().append('<br clear="all" />').css({'width':settings.default_width}).wrapInner('<div id="pp_full_res"><div class="pp_inline"></div></div>').appendTo($('body')).show();
  288. doresize = false; // Make sure the dimensions are not resized.
  289. pp_dimensions = _fitToViewport($(myClone).width(),$(myClone).height());
  290. doresize = true; // Reset the dimensions
  291. $(myClone).remove();
  292. toInject = settings.inline_markup.replace(/{content}/g,$(pp_images[set_position]).html());
  293. break;
  294. };
  295. if(!imgPreloader && !skipInjection){
  296. $pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
  297. // Show content
  298. _showContent();
  299. };
  300. });
  301. return false;
  302. };
  303. /**
  304. * Change page in the prettyPhoto modal box
  305. * @param direction {String} Direction of the paging, previous or next.
  306. */
  307. $.prettyPhoto.changePage = function(direction){
  308. currentGalleryPage = 0;
  309. if(direction == 'previous') {
  310. set_position--;
  311. if (set_position < 0) set_position = $(pp_images).length-1;
  312. }else if(direction == 'next'){
  313. set_position++;
  314. if(set_position > $(pp_images).length-1) set_position = 0;
  315. }else{
  316. set_position=direction;
  317. };
  318. rel_index = set_position;
  319. if(!doresize) doresize = true; // Allow the resizing of the images
  320. if(settings.allow_expand) {
  321. $('.pp_contract').removeClass('pp_contract').addClass('pp_expand');
  322. }
  323. _hideContent(function(){ $.prettyPhoto.open(); });
  324. };
  325. /**
  326. * Change gallery page in the prettyPhoto modal box
  327. * @param direction {String} Direction of the paging, previous or next.
  328. */
  329. $.prettyPhoto.changeGalleryPage = function(direction){
  330. if(direction=='next'){
  331. currentGalleryPage ++;
  332. if(currentGalleryPage > totalPage) currentGalleryPage = 0;
  333. }else if(direction=='previous'){
  334. currentGalleryPage --;
  335. if(currentGalleryPage < 0) currentGalleryPage = totalPage;
  336. }else{
  337. currentGalleryPage = direction;
  338. };
  339. slide_speed = (direction == 'next' || direction == 'previous') ? settings.animation_speed : 0;
  340. slide_to = currentGalleryPage * (itemsPerPage * itemWidth);
  341. $pp_gallery.find('ul').animate({left:-slide_to},slide_speed);
  342. };
  343. /**
  344. * Start the slideshow...
  345. */
  346. $.prettyPhoto.startSlideshow = function(){
  347. if(typeof pp_slideshow == 'undefined'){
  348. $pp_pic_holder.find('.pp_play').unbind('click').removeClass('pp_play').addClass('pp_pause').click(function(){
  349. $.prettyPhoto.stopSlideshow();
  350. return false;
  351. });
  352. pp_slideshow = setInterval($.prettyPhoto.startSlideshow,settings.slideshow);
  353. }else{
  354. $.prettyPhoto.changePage('next');
  355. };
  356. }
  357. /**
  358. * Stop the slideshow...
  359. */
  360. $.prettyPhoto.stopSlideshow = function(){
  361. $pp_pic_holder.find('.pp_pause').unbind('click').removeClass('pp_pause').addClass('pp_play').click(function(){
  362. $.prettyPhoto.startSlideshow();
  363. return false;
  364. });
  365. clearInterval(pp_slideshow);
  366. pp_slideshow=undefined;
  367. }
  368. /**
  369. * Closes prettyPhoto.
  370. */
  371. $.prettyPhoto.close = function(){
  372. if($pp_overlay.is(":animated")) return;
  373. $.prettyPhoto.stopSlideshow();
  374. $pp_pic_holder.stop().find('object,embed').css('visibility','hidden');
  375. $('div.pp_pic_holder,div.ppt,.pp_fade').fadeOut(settings.animation_speed,function(){ $(this).remove(); });
  376. $pp_overlay.fadeOut(settings.animation_speed, function(){
  377. if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','visible'); // Show the flash
  378. $(this).remove(); // No more need for the prettyPhoto markup
  379. $(window).unbind('scroll.prettyphoto');
  380. clearHashtag();
  381. settings.callback();
  382. doresize = true;
  383. pp_open = false;
  384. delete settings;
  385. });
  386. };
  387. /**
  388. * Set the proper sizes on the containers and animate the content in.
  389. */
  390. function _showContent(){
  391. $('.pp_loaderIcon').hide();
  392. // Calculate the opened top position of the pic holder
  393. projectedTop = scroll_pos['scrollTop'] + ((windowHeight/2) - (pp_dimensions['containerHeight']/2));
  394. if(projectedTop < 0) projectedTop = 0;
  395. $ppt.fadeTo(settings.animation_speed,1);
  396. // Resize the content holder
  397. $pp_pic_holder.find('.pp_content')
  398. .animate({
  399. height:pp_dimensions['contentHeight'],
  400. width:pp_dimensions['contentWidth']
  401. },settings.animation_speed);
  402. // Resize picture the holder
  403. $pp_pic_holder.animate({
  404. 'top': projectedTop,
  405. 'left': ((windowWidth/2) - (pp_dimensions['containerWidth']/2) < 0) ? 0 : (windowWidth/2) - (pp_dimensions['containerWidth']/2),
  406. width:pp_dimensions['containerWidth']
  407. },settings.animation_speed,function(){
  408. $pp_pic_holder.find('.pp_hoverContainer,#fullResImage').height(pp_dimensions['height']).width(pp_dimensions['width']);
  409. $pp_pic_holder.find('.pp_fade').fadeIn(settings.animation_speed); // Fade the new content
  410. // Show the nav
  411. if(isSet && _getFileType(pp_images[set_position])=="image") { $pp_pic_holder.find('.pp_hoverContainer').show(); }else{ $pp_pic_holder.find('.pp_hoverContainer').hide(); }
  412. if(settings.allow_expand) {
  413. if(pp_dimensions['resized']){ // Fade the resizing link if the image is resized
  414. $('a.pp_expand,a.pp_contract').show();
  415. }else{
  416. $('a.pp_expand').hide();
  417. }
  418. }
  419. if(settings.autoplay_slideshow && !pp_slideshow && !pp_open) $.prettyPhoto.startSlideshow();
  420. settings.changepicturecallback(); // Callback!
  421. pp_open = true;
  422. });
  423. _insert_gallery();
  424. pp_settings.ajaxcallback();
  425. };
  426. /**
  427. * Hide the content...DUH!
  428. */
  429. function _hideContent(callback){
  430. // Fade out the current picture
  431. $pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');
  432. $pp_pic_holder.find('.pp_fade').fadeOut(settings.animation_speed,function(){
  433. $('.pp_loaderIcon').show();
  434. callback();
  435. });
  436. };
  437. /**
  438. * Check the item position in the gallery array, hide or show the navigation links
  439. * @param setCount {integer} The total number of items in the set
  440. */
  441. function _checkPosition(setCount){
  442. (setCount > 1) ? $('.pp_nav').show() : $('.pp_nav').hide(); // Hide the bottom nav if it's not a set.
  443. };
  444. /**
  445. * Resize the item dimensions if it's bigger than the viewport
  446. * @param width {integer} Width of the item to be opened
  447. * @param height {integer} Height of the item to be opened
  448. * @return An array containin the "fitted" dimensions
  449. */
  450. function _fitToViewport(width,height){
  451. resized = false;
  452. _getDimensions(width,height);
  453. // Define them in case there's no resize needed
  454. imageWidth = width, imageHeight = height;
  455. if( ((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)) && doresize && settings.allow_resize && !percentBased) {
  456. resized = true, fitting = false;
  457. while (!fitting){
  458. if((pp_containerWidth > windowWidth)){
  459. imageWidth = (windowWidth - 200);
  460. imageHeight = (height/width) * imageWidth;
  461. }else if((pp_containerHeight > windowHeight)){
  462. imageHeight = (windowHeight - 200);
  463. imageWidth = (width/height) * imageHeight;
  464. }else{
  465. fitting = true;
  466. };
  467. pp_containerHeight = imageHeight, pp_containerWidth = imageWidth;
  468. };
  469. if((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)){
  470. _fitToViewport(pp_containerWidth,pp_containerHeight)
  471. };
  472. _getDimensions(imageWidth,imageHeight);
  473. };
  474. return {
  475. width:Math.floor(imageWidth),
  476. height:Math.floor(imageHeight),
  477. containerHeight:Math.floor(pp_containerHeight),
  478. containerWidth:Math.floor(pp_containerWidth) + (settings.horizontal_padding * 2),
  479. contentHeight:Math.floor(pp_contentHeight),
  480. contentWidth:Math.floor(pp_contentWidth),
  481. resized:resized
  482. };
  483. };
  484. /**
  485. * Get the containers dimensions according to the item size
  486. * @param width {integer} Width of the item to be opened
  487. * @param height {integer} Height of the item to be opened
  488. */
  489. function _getDimensions(width,height){
  490. width = parseFloat(width);
  491. height = parseFloat(height);
  492. // Get the details height, to do so, I need to clone it since it's invisible
  493. $pp_details = $pp_pic_holder.find('.pp_details');
  494. $pp_details.width(width);
  495. detailsHeight = parseFloat($pp_details.css('marginTop')) + parseFloat($pp_details.css('marginBottom'));
  496. $pp_details = $pp_details.clone().addClass(settings.theme).width(width).appendTo($('body')).css({
  497. 'position':'absolute',
  498. 'top':-10000
  499. });
  500. detailsHeight += $pp_details.height();
  501. detailsHeight = (detailsHeight <= 34) ? 36 : detailsHeight; // Min-height for the details
  502. $pp_details.remove();
  503. // Get the titles height, to do so, I need to clone it since it's invisible
  504. $pp_title = $pp_pic_holder.find('.ppt');
  505. $pp_title.width(width);
  506. titleHeight = parseFloat($pp_title.css('marginTop')) + parseFloat($pp_title.css('marginBottom'));
  507. $pp_title = $pp_title.clone().appendTo($('body')).css({
  508. 'position':'absolute',
  509. 'top':-10000
  510. });
  511. titleHeight += $pp_title.height();
  512. $pp_title.remove();
  513. // Get the container size, to resize the holder to the right dimensions
  514. pp_contentHeight = height + detailsHeight;
  515. pp_contentWidth = width;
  516. pp_containerHeight = pp_contentHeight + titleHeight + $pp_pic_holder.find('.pp_top').height() + $pp_pic_holder.find('.pp_bottom').height();
  517. pp_containerWidth = width;
  518. }
  519. function _getFileType(itemSrc){
  520. if (itemSrc.match(/youtube\.com\/watch/i) || itemSrc.match(/youtu\.be/i)) {
  521. return 'youtube';
  522. }else if (itemSrc.match(/vimeo\.com/i)) {
  523. return 'vimeo';
  524. }else if(itemSrc.match(/\b.mov\b/i)){
  525. return 'quicktime';
  526. }else if(itemSrc.match(/\b.swf\b/i)){
  527. return 'flash';
  528. }else if(itemSrc.match(/\biframe=true\b/i)){
  529. return 'iframe';
  530. }else if(itemSrc.match(/\bajax=true\b/i)){
  531. return 'ajax';
  532. }else if(itemSrc.match(/\bcustom=true\b/i)){
  533. return 'custom';
  534. }else if(itemSrc.substr(0,1) == '#'){
  535. return 'inline';
  536. }else{
  537. return 'image';
  538. };
  539. };
  540. function _center_overlay(){
  541. if(doresize && typeof $pp_pic_holder != 'undefined') {
  542. scroll_pos = _get_scroll();
  543. contentHeight = $pp_pic_holder.height(), contentwidth = $pp_pic_holder.width();
  544. projectedTop = (windowHeight/2) + scroll_pos['scrollTop'] - (contentHeight/2);
  545. if(projectedTop < 0) projectedTop = 0;
  546. if(contentHeight > windowHeight)
  547. return;
  548. $pp_pic_holder.css({
  549. 'top': projectedTop,
  550. 'left': (windowWidth/2) + scroll_pos['scrollLeft'] - (contentwidth/2)
  551. });
  552. };
  553. };
  554. function _get_scroll(){
  555. if (self.pageYOffset) {
  556. return {scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};
  557. } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
  558. return {scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft};
  559. } else if (document.body) {// all other Explorers
  560. return {scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft};
  561. };
  562. };
  563. function _resize_overlay() {
  564. windowHeight = $(window).height(), windowWidth = $(window).width();
  565. if(typeof $pp_overlay != "undefined") $pp_overlay.height($(document).height()).width(windowWidth);
  566. };
  567. function _insert_gallery(){
  568. if(isSet && settings.overlay_gallery && _getFileType(pp_images[set_position])=="image") {
  569. itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
  570. navWidth = (settings.theme == "facebook" || settings.theme == "pp_default") ? 50 : 30; // Define the arrow width depending on the theme
  571. itemsPerPage = Math.floor((pp_dimensions['containerWidth'] - 100 - navWidth) / itemWidth);
  572. itemsPerPage = (itemsPerPage < pp_images.length) ? itemsPerPage : pp_images.length;
  573. totalPage = Math.ceil(pp_images.length / itemsPerPage) - 1;
  574. // Hide the nav in the case there's no need for links
  575. if(totalPage == 0){
  576. navWidth = 0; // No nav means no width!
  577. $pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').hide();
  578. }else{
  579. $pp_gallery.find('.pp_arrow_next,.pp_arrow_previous').show();
  580. };
  581. galleryWidth = itemsPerPage * itemWidth;
  582. fullGalleryWidth = pp_images.length * itemWidth;
  583. // Set the proper width to the gallery items
  584. $pp_gallery
  585. .css('margin-left',-((galleryWidth/2) + (navWidth/2)))
  586. .find('div:first').width(galleryWidth+5)
  587. .find('ul').width(fullGalleryWidth)
  588. .find('li.selected').removeClass('selected');
  589. goToPage = (Math.floor(set_position/itemsPerPage) < totalPage) ? Math.floor(set_position/itemsPerPage) : totalPage;
  590. $.prettyPhoto.changeGalleryPage(goToPage);
  591. $pp_gallery_li.filter(':eq('+set_position+')').addClass('selected');
  592. }else{
  593. $pp_pic_holder.find('.pp_content').unbind('mouseenter mouseleave');
  594. // $pp_gallery.hide();
  595. }
  596. }
  597. function _build_overlay(caller){
  598. // Inject Social Tool markup into General markup
  599. if(settings.social_tools)
  600. facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
  601. settings.markup = settings.markup.replace('{pp_social}','');
  602. $('body').append(settings.markup); // Inject the markup
  603. $pp_pic_holder = $('.pp_pic_holder') , $ppt = $('.ppt'), $pp_overlay = $('div.pp_overlay'); // Set my global selectors
  604. // Inject the inline gallery!
  605. if(isSet && settings.overlay_gallery) {
  606. currentGalleryPage = 0;
  607. toInject = "";
  608. for (var i=0; i < pp_images.length; i++) {
  609. if(!pp_images[i].match(/\b(jpg|jpeg|png|gif)\b/gi)){
  610. classname = 'default';
  611. img_src = '';
  612. }else{
  613. classname = '';
  614. img_src = pp_images[i];
  615. }
  616. toInject += "<li class='"+classname+"'><a href='#'><img src='" + img_src + "' width='50' alt='' /></a></li>";
  617. };
  618. toInject = settings.gallery_markup.replace(/{gallery}/g,toInject);
  619. $pp_pic_holder.find('#pp_full_res').after(toInject);
  620. $pp_gallery = $('.pp_pic_holder .pp_gallery'), $pp_gallery_li = $pp_gallery.find('li'); // Set the gallery selectors
  621. $pp_gallery.find('.pp_arrow_next').click(function(){
  622. $.prettyPhoto.changeGalleryPage('next');
  623. $.prettyPhoto.stopSlideshow();
  624. return false;
  625. });
  626. $pp_gallery.find('.pp_arrow_previous').click(function(){
  627. $.prettyPhoto.changeGalleryPage('previous');
  628. $.prettyPhoto.stopSlideshow();
  629. return false;
  630. });
  631. $pp_pic_holder.find('.pp_content').hover(
  632. function(){
  633. $pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeIn();
  634. },
  635. function(){
  636. $pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeOut();
  637. });
  638. itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
  639. $pp_gallery_li.each(function(i){
  640. $(this)
  641. .find('a')
  642. .click(function(){
  643. $.prettyPhoto.changePage(i);
  644. $.prettyPhoto.stopSlideshow();
  645. return false;
  646. });
  647. });
  648. };
  649. // Inject the play/pause if it's a slideshow
  650. if(settings.slideshow){
  651. $pp_pic_holder.find('.pp_nav').prepend('<a href="#" class="pp_play">Play</a>')
  652. $pp_pic_holder.find('.pp_nav .pp_play').click(function(){
  653. $.prettyPhoto.startSlideshow();
  654. return false;
  655. });
  656. }
  657. $pp_pic_holder.attr('class','pp_pic_holder ' + settings.theme); // Set the proper theme
  658. $pp_overlay
  659. .css({
  660. 'opacity':0,
  661. 'height':$(document).height(),
  662. 'width':$(window).width()
  663. })
  664. .bind('click',function(){
  665. if(!settings.modal) $.prettyPhoto.close();
  666. });
  667. $('a.pp_close').bind('click',function(){ $.prettyPhoto.close(); return false; });
  668. if(settings.allow_expand) {
  669. $('a.pp_expand').bind('click',function(e){
  670. // Expand the image
  671. if($(this).hasClass('pp_expand')){
  672. $(this).removeClass('pp_expand').addClass('pp_contract');
  673. doresize = false;
  674. }else{
  675. $(this).removeClass('pp_contract').addClass('pp_expand');
  676. doresize = true;
  677. };
  678. _hideContent(function(){ $.prettyPhoto.open(); });
  679. return false;
  680. });
  681. }
  682. $pp_pic_holder.find('.pp_previous, .pp_nav .pp_arrow_previous').bind('click',function(){
  683. $.prettyPhoto.changePage('previous');
  684. $.prettyPhoto.stopSlideshow();
  685. return false;
  686. });
  687. $pp_pic_holder.find('.pp_next, .pp_nav .pp_arrow_next').bind('click',function(){
  688. $.prettyPhoto.changePage('next');
  689. $.prettyPhoto.stopSlideshow();
  690. return false;
  691. });
  692. _center_overlay(); // Center it
  693. };
  694. if(!pp_alreadyInitialized && getHashtag()){
  695. pp_alreadyInitialized = true;
  696. // Grab the rel index to trigger the click on the correct element
  697. hashIndex = getHashtag();
  698. hashRel = hashIndex;
  699. hashIndex = hashIndex.substring(hashIndex.indexOf('/')+1,hashIndex.length-1);
  700. hashRel = hashRel.substring(0,hashRel.indexOf('/'));
  701. // Little timeout to make sure all the prettyPhoto initialize scripts has been run.
  702. // Useful in the event the page contain several init scripts.
  703. setTimeout(function(){ $("a["+pp_settings.hook+"^='"+hashRel+"']:eq("+hashIndex+")").trigger('click'); },50);
  704. }
  705. return this.unbind('click.prettyphoto').bind('click.prettyphoto',$.prettyPhoto.initialize); // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
  706. };
  707. function getHashtag(){
  708. var url = location.href;
  709. hashtag = (url.indexOf('#prettyPhoto') !== -1) ? decodeURI(url.substring(url.indexOf('#prettyPhoto')+1,url.length)) : false;
  710. if(hashtag){ hashtag = hashtag.replace(/<|>/g,''); }
  711. return hashtag;
  712. };
  713. function setHashtag(){
  714. if(typeof theRel == 'undefined') return; // theRel is set on normal calls, it's impossible to deeplink using the API
  715. location.hash = theRel + '/'+rel_index+'/';
  716. };
  717. function clearHashtag(){
  718. if ( location.href.indexOf('#prettyPhoto') !== -1 ) location.hash = "prettyPhoto";
  719. }
  720. function getParam(name,url){
  721. name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  722. var regexS = "[\\?&]"+name+"=([^&#]*)";
  723. var regex = new RegExp( regexS );
  724. var results = regex.exec( url );
  725. return ( results == null ) ? "" : results[1];
  726. }
  727. })(jQuery);
  728. var pp_alreadyInitialized = false; // Used for the deep linking to make sure not to call the same function several times.