lc_lightbox.lite.js 80 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588
  1. /**
  2. * LC Lightbox - LITE
  3. * yet.. another jQuery lightbox.. or not?
  4. *
  5. * @version : 1.1
  6. * @copyright : Luca Montanari aka LCweb
  7. * @website : https://lcweb.it
  8. * @requires : jQuery v1.7 or later
  9. * Released under the MIT license
  10. */
  11. (function ($) {
  12. lcl_objs = []; // array containing all initialized objects - useful for deeplinks
  13. lcl_shown = false; // know whether lightbox is shown
  14. lcl_is_active = false; // true when lightbox systems are acting (disable triggers)
  15. lcl_slideshow = undefined; // lightbox slideshow - setInterval object
  16. lcl_on_mobile = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent);
  17. // static vars avoiding useless parameters usage - related to currently opened lightbox - otherwise they are empty
  18. lcl_curr_obj = false; // store currently active object
  19. lcl_curr_opts = false; // currently active instance settings
  20. lcl_curr_vars = false; // currently active instance settings
  21. lcl_deeplink_tracked= false; // flag to track url changes and initial reading once
  22. lcl_hashless_url = false; // page URL without eventual hashes
  23. lcl_url_hash = ''; // URL hashtag
  24. // fixed values
  25. lcl_vid_instance_num = 0; // video.js instances number
  26. // lightbox structure
  27. var lb_code =
  28. '<div id="lcl_wrap" class="lcl_pre_show lcl_pre_first_el lcl_first_sizing lcl_is_resizing">'+
  29. '<div id="lcl_window">'+
  30. '<div id="lcl_corner_close" title="close"></div>'+
  31. '<div id="lcl_loader" class="lcl_loader_pre_first_el"><span id="lcll_1"></span><span id="lcll_2"></span></div>'+
  32. '<div id="lcl_nav_cmd">'+
  33. '<div class="lcl_icon lcl_prev" title="previous"></div>'+
  34. // '<div class="lcl_icon lcl_play"></div>'+
  35. '<div class="lcl_icon lcl_next" title="next"></div>'+
  36. // '<div class="lcl_icon lcl_counter"></div>'+
  37. '<div class="lcl_icon lcl_right_icon lcl_close" title="close"></div>'+
  38. // '<div class="lcl_icon lcl_right_icon lcl_fullscreen" title="toggle fullscreen"></div>'+
  39. // '<div class="lcl_icon lcl_right_icon lcl_txt_toggle" title="toggle text"></div>'+
  40. // '<div class="lcl_icon lcl_right_icon lcl_download" title="download"></div>'+
  41. // '<div class="lcl_icon lcl_right_icon lcl_thumbs_toggle" title="toggle thumbnails"></div>'+
  42. // '<div class="lcl_icon lcl_right_icon lcl_socials" title="toggle socials"></div>'+
  43. '</div>'+
  44. '<div id="lcl_contents_wrap">'+
  45. '<div id="lcl_subj">'+
  46. '<div id="lcl_elem_wrap"></div>'+
  47. '</div>'+
  48. '<div id="lcl_txt"></div>'+
  49. '</div>'+
  50. '</div>'+
  51. '<div id="lcl_thumbs_nav"></div>'+
  52. '<div id="lcl_overlay"></div>'+
  53. '</div>';
  54. ////////////////////////////////////////////////////////////////////
  55. // initialization
  56. // obj can be an array and overrides elements / [src: url/selector (only required data), title: (string), txt: (string), author: (string), ajax: bool, type: image/frame/text]
  57. lc_lightbox = function(obj, lcl_settings) {
  58. if(typeof(obj) != 'string' && (typeof(obj) != 'object' || !obj.length)) {return false;}
  59. // check among already initialized
  60. var already_init = false;
  61. $.each(lcl_objs, function(i, v) {
  62. if(JSON.stringify(v) == JSON.stringify(obj)) {
  63. already_init = v;
  64. return false;
  65. }
  66. });
  67. if(already_init === false) {
  68. var instance = new lcl(obj, lcl_settings);
  69. lcl_objs.push(instance);
  70. return instance;
  71. }
  72. return already_init;
  73. };
  74. // destruct method
  75. lcl_destroy = function(instance) {
  76. var index = $.inArray(instance, lcl_objs);
  77. if(index !== -1) {
  78. lcl_objs.splice(index, 1);
  79. }
  80. };
  81. ////////////////////////////////////////////////////////////////////
  82. /* initialize */
  83. var lcl = function(obj, settings) {
  84. var lcl_settings = $.extend({
  85. gallery : true, // whether to display a single element or compose a gallery
  86. gallery_hook : 'rel', // attribute grouping elements - use false to create a gallery with all fetched elements
  87. live_elements : true, // if a selector is found, set true to handle automatically DOM changes
  88. preload_all : false, // whether to preload all images on document ready
  89. global_type : 'image', // force elements type
  90. src_attr : 'href', // attribute containing element's source
  91. title_attr : 'title', // attribute containing the title - is possible to specify a selector with this syntax: "> .selector" or "> span"
  92. txt_attr : 'data-lcl-txt', // attribute containing the description - is possible to specify a selector with this syntax: "> .selector" or "> span"
  93. author_attr : 'data-lcl-author', // attribute containing the author - is possible to specify a selector with this syntax: "> .selector" or "> span"
  94. slideshow : true, // whether to enable slideshow
  95. open_close_time : 500, // animation duration for lightbox opening and closing / 1000 = 1sec
  96. ol_time_diff : 100, // overlay's animation advance (on opening) and delay (on close) to window / 1000 = sec
  97. fading_time : 150, // elements fading animation duration in millisecods / 1000 = 1sec
  98. animation_time : 300, // sizing animation duration in millisecods / 1000 = 1sec
  99. slideshow_time : 6000, // slideshow interval duration in milliseconds / 1000 = 1sec
  100. autoplay : false, // autoplay slideshow - bool
  101. counter : false, // whether to display elements counter
  102. progressbar : true, // whether to display a progressbar when slideshow runs
  103. carousel : true, // whether to create a non-stop pagination cycling elements
  104. max_width : '93%', // Lightbox maximum width. Use a responsive percent value or an integer for static pixel value
  105. max_height : '93%', // Lightbox maximum height. Use a responsive percent value or an integer for static pixel value
  106. ol_opacity : 0.7, // overlay opacity / value between 0 and 1
  107. ol_color : '#111', // background color of the overlay
  108. ol_pattern : false, // overlay patterns - insert the pattern name or false
  109. border_w : 3, // width of the lightbox border in pixels
  110. border_col : '#ddd', // color of the lightbox border
  111. padding : 10, // width of the lightbox padding in pixels
  112. radius : 4, // lightbox border radius in pixels
  113. shadow : true, // whether to apply a shadow around lightbox window
  114. remove_scrollbar: true, // whether to hide page's vertical scroller
  115. wrap_class : '', // custom classes added to wrapper - for custom styling/tracking
  116. skin : 'light', // light / dark / custom
  117. data_position : 'over', // over / under / lside / rside
  118. cmd_position : 'inner', // inner / outer
  119. ins_close_pos : 'normal', // set closing button position for inner commands - normal/corner
  120. nav_btn_pos : 'normal', // set arrows and play/pause position - normal/middle
  121. txt_hidden : 500, // whether to hide texts on lightbox opening - bool or int (related to browser's smaller side)
  122. show_title : true, // bool / whether to display titles
  123. show_descr : true, // bool / whether to display descriptions
  124. show_author : true, // bool / whether to display authors
  125. thumbs_nav : true, // enables thumbnails navigation (requires elements poster or images)
  126. tn_icons : true, // print type icons on thumbs if types are mixed
  127. tn_hidden : 500, // whether to hide thumbs nav on lightbox opening - bool or int (related to browser's smaller side)
  128. thumbs_w : 110, // width of the thumbs for the standard lightbox
  129. thumbs_h : 110, // height of the thumbs for the standard lightbox
  130. thumb_attr : false, // attribute containing thumb URL to use or false to use thumbs maker
  131. thumbs_maker_url: false, // script baseurl to create thumbnails (use src=%URL% w=%W% h=%H%)
  132. fullscreen : true, // Allow the user to expand a resized image. true/false
  133. fs_img_behavior : 'fit', // resize mode of the fullscreen image - smart/fit/fill
  134. fs_only : 500, // when directly open in fullscreen mode - bool or int (related to browser's smaller side)
  135. browser_fs_mode : true, // whether to trigger or nor browser fullscreen mode
  136. socials : true, // bool
  137. txt_toggle_cmd : true, // bool / allow text hiding
  138. download : true, // bool / whether to add download button
  139. touchswipe : true, // bool / Allow touch interactions for mobile (requires AlloyFinger)
  140. mousewheel : true, // bool / Allow elements navigation with mousewheel
  141. modal : false, // enable modal mode (no closing on overlay click)
  142. rclick_prevent : false, // whether to avoid right click on lightbox
  143. elems_parsed : function() {},
  144. html_is_ready : function() {},
  145. on_open : function() {},
  146. on_elem_switch : function() {},
  147. slideshow_start : function() {},
  148. slideshow_end : function() {},
  149. on_fs_enter : function() {},
  150. on_fs_exit : function() {},
  151. on_close : function() {},
  152. }, settings);
  153. // Variables accessible globally
  154. var lcl_vars = {
  155. elems : [], // elements object / src: url/text (only required data), title: (string), descr: (string), author: (string), type: image/iframe/text
  156. is_arr_instance : (typeof(obj) != 'string' && typeof(obj[0].childNodes) == 'undefined') ? true : false, // true if lightbox is initialized usign direct array immission
  157. elems_count : (typeof(obj) != 'string' && typeof(obj[0].childNodes) == 'undefined') ? obj.length : $(obj).length, // elements count at the moment of lb initialization
  158. elems_selector : (typeof(obj) == 'string') ? obj : false, // elements selector - used for dynamic elements fetching
  159. elem_index : false, // current element index
  160. gallery_hook_val: false, // gallery hook value - to discard other ones
  161. preload_all_used: false, // flag to know when complete preload on document's ready has been triggered
  162. img_sizes_cache : [], // store image sizes after their preload - index is images index
  163. inner_cmd_w : false, // store inner commands width for inner->outer switch
  164. txt_exists : false, // any text exists in current element?
  165. txt_und_sizes : false, // custom lb sizes after text under calculation
  166. force_fullscreen: false, // flag to know whether to simulate "always fs" for small screens
  167. html_style : '', // html tag style (for scrollbar hiding)
  168. body_style : '', // body tag style (for scrollbar hiding)
  169. };
  170. // textal element selector has been used? setup the real obj
  171. if(typeof(obj) == 'string') {
  172. obj = $(obj);
  173. }
  174. // .data() system to avoid issues on multi instances
  175. var lcl_ai_opts = $.data(obj, 'lcl_settings', lcl_settings);
  176. var lcl_ai_vars = $.data(obj, 'lcl_vars', lcl_vars);
  177. /////////////////////////////////////////////////////////////
  178. /* given a string - returns an unique numerical hash */
  179. var get_hash = function(str) {
  180. if(typeof(str) != 'string') {
  181. return str;
  182. }
  183. var hash = 0, i = 0, len = str.toString().length;
  184. while (i < len) {
  185. hash = ((hash << 5) - hash + str.charCodeAt(i++)) << 0;
  186. }
  187. return (hash < 0) ? hash * -1 : hash;
  188. };
  189. /* element already elaborated? check through hash - returns false or elem object */
  190. var obj_already_man = function(hash) {
  191. var found = false;
  192. $.each(lcl_ai_vars.elems, function(i, v) {
  193. if(v.hash == hash) {
  194. found = v;
  195. return false;
  196. }
  197. });
  198. return found;
  199. };
  200. /* revert HTML entitles that might have been used in attrs (and trim) */
  201. var revert_html_entit = function(str) {
  202. if(!str) {return str;}
  203. str = str.replace(/&lt;/g, '<')
  204. .replace(/&gt;/g, '>')
  205. .replace(/&amp;/g, '&')
  206. .replace(/&quot;/g, '"')
  207. .replace(/&#039;/g, "'");
  208. return $.trim(str);
  209. };
  210. /* returns title/text/author detecting whether to get an attribute or selector */
  211. var attr_or_selector_data = function($elem, subj_key) {
  212. var o = lcl_ai_opts;
  213. var subj = o[subj_key];
  214. if(subj.indexOf('> ') !== -1) {
  215. return ($elem.find( subj.replace('> ', '') ).length) ? $.trim( $elem.find( subj.replace('> ', '') ).html()) : '';
  216. }
  217. else {
  218. return (typeof($elem.attr( subj )) != 'undefined') ? revert_html_entit( $elem.attr( subj )) : '';
  219. }
  220. };
  221. /* elaborate binded elements */
  222. var setup_elems_obj = function($subj) {
  223. var o = lcl_ai_opts;
  224. // if single opening - load just that index
  225. if(!o.gallery) {
  226. $subj = $subj.eq( lcl_ai_vars.elem_index );
  227. }
  228. // [src: url/selector (only required data), title: (string), descr: (string), author: (string), ajax: bool, type: image/frame/text]
  229. var new_elems = [];
  230. $subj.each(function() {
  231. var $e = $(this);
  232. var src = $e.attr( o.src_attr );
  233. var hash = get_hash(src);
  234. // check against gallery hook
  235. if(lcl_ai_vars.gallery_hook_val && $e.attr(o.gallery_hook) != lcl_ai_vars.gallery_hook_val) {
  236. return true;
  237. }
  238. var already_man = obj_already_man(hash);
  239. if(already_man) {
  240. var el = already_man;
  241. }
  242. else {
  243. var type = el_type_finder(src, $e.data('lcl-type'));
  244. // compose
  245. if(type != 'unknown') {
  246. var el = {
  247. src : src,
  248. type : type,
  249. hash : (o.deeplink) ? get_hash(src) : false,
  250. title : (o.show_title) ? attr_or_selector_data($e, 'title_attr') : '',
  251. txt : (o.show_descr) ? attr_or_selector_data($e, 'txt_attr') : '',
  252. author : (o.show_author) ? attr_or_selector_data($e, 'author_attr') : '',
  253. thumb : (o.thumb_attr && typeof(o.thumb_attr) != 'undefined') ? $e.attr(o.thumb_attr) : '',
  254. download: ((type == 'image') && typeof($e.data('lcl-path')) != 'undefined') ? $e.data('lcl-path') : false,
  255. force_outer_cmd : (typeof($e.data('lcl-outer-cmd')) != 'undefined') ? $e.data('lcl-outer-cmd') : '',
  256. canonical_url : (typeof($e.data('lcl-canonical-url')) != 'undefined') ? $e.data('lcl-canonical-url') : '',
  257. };
  258. }
  259. else {
  260. var el = {
  261. src : src,
  262. type : type,
  263. hash : (o.deeplink) ? get_hash(src) : false
  264. };
  265. }
  266. }
  267. new_elems.push(el);
  268. });
  269. // if only one element - remove nav arrows and thumbs nav
  270. if(new_elems.length < 2) {
  271. $('.lcl_prev, .lcl_next, #lcl_thumb_nav').remove();
  272. }
  273. if(!new_elems.length) {
  274. return false;
  275. }
  276. // setup
  277. lcl_ai_vars.elems = new_elems;
  278. return true;
  279. };
  280. /* given element source - return its type | accepts type forcing */
  281. var el_type_finder = function(src, forced_type) {
  282. if(typeof(forced_type) == 'undefined') {
  283. forced_type = lcl_ai_opts.global_type;
  284. }
  285. if($.inArray(forced_type, ['image']) !== -1) {
  286. return forced_type;
  287. }
  288. src = src.toLowerCase();
  289. var img_regex = /^https?:\/\/(?:[a-z\-]+\.)+[a-z]{2,6}(?:\/[^\/#?]+)+\.(?:jpe?g|gif|png)$/;
  290. if(img_regex.test(src)) { // image matching
  291. return 'image';
  292. }
  293. return 'unknown';
  294. };
  295. /////////////
  296. /* smart images preload */
  297. var close_img_preload = function() {
  298. if(lcl_ai_vars.elems.length < 2 || !lcl_ai_opts.gallery) {return false;}
  299. if(lcl_ai_vars.elem_index > 0) { // prev
  300. maybe_preload(false, (lcl_ai_vars.elem_index - 1));
  301. }
  302. if(lcl_ai_vars.elem_index != (lcl_ai_vars.elems.length - 1)) { // next
  303. maybe_preload(false, (lcl_ai_vars.elem_index + 1));
  304. }
  305. };
  306. /* preload images and eventually trigger showing function - if index not specified, loads current index */
  307. var maybe_preload = function(show_when_ready, el_index) {
  308. var v = lcl_ai_vars;
  309. // if forced index is missing - use current one
  310. if(typeof(el_index) == 'undefined') {
  311. el_index = v.elem_index;
  312. }
  313. if(typeof(el_index) == 'undefined') { // if lightbox has alraedy been closed
  314. return false;
  315. }
  316. // is a preloadable element?
  317. if(v.elems[el_index].type == 'image') {
  318. var to_preload = (v.elems[el_index].type == 'image') ? v.elems[el_index].src : v.elems[el_index].poster;
  319. }
  320. else {var to_preload = '';}
  321. if(to_preload && typeof(v.img_sizes_cache[to_preload]) == 'undefined') {
  322. $('<img/>').bind("load", function(){
  323. v.img_sizes_cache[to_preload] = {
  324. w : this.width,
  325. h : this.height
  326. };
  327. // if sizes are zero, recalculate
  328. if(show_when_ready && el_index == v.elem_index) {
  329. show_element();
  330. }
  331. }).attr('src', to_preload);
  332. }
  333. else {
  334. if(show_when_ready) {
  335. show_element();
  336. }
  337. }
  338. };
  339. /////////////
  340. /* elements parsing */
  341. var elems_parsing = function(inst_obj, $clicked_obj) {
  342. var o = $.data(inst_obj, 'lcl_settings');
  343. var vars = $.data(inst_obj, 'lcl_vars');
  344. // direct array initialization - validate and setup hashes
  345. if(vars.is_arr_instance) {
  346. var elems = [];
  347. $.each(inst_obj, function(i,v) {
  348. var el = {};
  349. var el_type = (typeof(v.type) == 'undefined' && o.global_type) ? o.global_type : false;
  350. if(typeof(v.type) != 'undefined') {el_type = v.type;}
  351. if(el_type && $.inArray(el_type, ['image']) !== -1) {
  352. if(typeof(v.src) != 'undefined' && v.src) {
  353. el.src = v.src;
  354. el.type = el_type;
  355. el.hash = get_hash(v.src);
  356. el.title = (typeof(v.title) == 'undefined') ? '' : revert_html_entit(v.title);
  357. el.txt = (typeof(v.txt) == 'undefined') ? '' : revert_html_entit(v.txt);
  358. el.author = (typeof(v.author) == 'undefined') ? '' : revert_html_entit(v.author);
  359. el.force_outer_cmd = (typeof(v.force_outer_cmd) == 'undefined') ? false : v.force_outer_cmd;
  360. el.canonical_url = (typeof(v.canonical_url) == 'undefined') ? false : v.canonical_url;
  361. el.thumb = (typeof(v.thumb) == 'undefined') ? false : v.thumb;
  362. el.download = ((el_type != 'image') || typeof(v.download) == 'undefined') ? false : el.download;
  363. elems.push(el);
  364. }
  365. }
  366. else {
  367. var el = {
  368. src : el.src,
  369. type : 'unknown',
  370. hash : (o.deeplink) ? get_hash(el.src) : false
  371. };
  372. elems.push(el);
  373. }
  374. });
  375. vars.elems = elems;
  376. }
  377. // if is from DOM object - prepare elements object
  378. else {
  379. var $subj = inst_obj;
  380. // can fetch elements in real-time? save selector
  381. if(o.live_elements && vars.elems_selector) {
  382. var consider_group = ($clicked_obj && o.gallery && o.gallery_hook && typeof($(obj[0]).attr(o.gallery_hook)) != 'undefined') ? true : false;
  383. var sel = (consider_group) ? vars.elems_selector +'['+ o.gallery_hook +'='+ $clicked_obj.attr( o.gallery_hook ) +']' : vars.elems_selector;
  384. $subj = $(sel);
  385. }
  386. if(!setup_elems_obj($subj)) {
  387. if(!o.live_elements || (o.live_elements && !vars.elems_selector)) {
  388. console.error('LC Lightbox - no valid elements found');
  389. }
  390. return false;
  391. }
  392. }
  393. // if preload every image on document's ready
  394. if(o.preload_all && !vars.preload_all_used) {
  395. vars.preload_all_used = true;
  396. $(document).ready(function(e) {
  397. $.each(vars.elems, function(i, v) {
  398. maybe_preload(false, i);
  399. });
  400. });
  401. }
  402. /////
  403. // elements parsed - throw callback
  404. if(typeof(o.elems_parsed) == 'function') {
  405. o.elems_parsed.call({opts : lcl_ai_opts, vars: lcl_ai_vars});
  406. }
  407. // elements parsed | args: elements array
  408. if(!vars.is_arr_instance) {
  409. var $subj = (vars.elems_selector) ? $(vars.elems_selector) : inst_obj;
  410. $subj.first().trigger('lcl_elems_parsed', [vars.elems]);
  411. }
  412. return true;
  413. };
  414. elems_parsing(obj); // parsing on lightbox INIT
  415. ////////////////////////////////////////////////////////////
  416. /* open lightbox */
  417. var open_lb = function(inst_obj, $clicked_obj) {
  418. if(lcl_shown || lcl_is_active) {return false;}
  419. lcl_shown = true;
  420. lcl_is_active = true;
  421. // setup static globals
  422. lcl_curr_obj = inst_obj;
  423. lcl_ai_opts = $.data(inst_obj, 'lcl_settings');
  424. lcl_ai_vars = $.data(inst_obj, 'lcl_vars');
  425. lcl_curr_opts = lcl_ai_opts;
  426. lcl_curr_vars = lcl_ai_vars;
  427. var o = lcl_ai_opts;
  428. var v = lcl_ai_vars;
  429. var $co = (typeof($clicked_obj) != 'undefined') ? $clicked_obj : false;
  430. // check instance existence
  431. if(!lcl_ai_vars) {
  432. console.error('LC Lightbox - cannot open. Object not initialized');
  433. return false;
  434. }
  435. // set gallery hook value
  436. v.gallery_hook_val = ($co && o.gallery && o.gallery_hook && typeof($co.attr(o.gallery_hook)) != 'undefined') ? $co.attr(o.gallery_hook) : false;
  437. // parse elements
  438. if(!elems_parsing(inst_obj, $clicked_obj)) {
  439. return false;
  440. }
  441. // if there is a clicked element - set selected index
  442. if($co) {
  443. $.each(v.elems, function(i, e) {
  444. if( e.src == $co.attr(o.src_attr) ) {
  445. v.elem_index = i;
  446. return false;
  447. }
  448. });
  449. }
  450. // array or deeplink initialization - check index existence
  451. else {
  452. if(parseInt(v.elem_index, 10) >= v.elems_count) {
  453. console.error('LC Lightbox - selected index does not exist');
  454. return false;
  455. }
  456. }
  457. // try recalling cached images to already shape lightbox
  458. maybe_preload(false);
  459. // setup lightbox code
  460. setup_code();
  461. touch_events();
  462. // directly fullscreen?
  463. if(v.force_fullscreen) {
  464. enter_fullscreen(true, true);
  465. }
  466. // prepare thumbs nav
  467. if($('#lcl_thumbs_nav').length) {
  468. setup_thumbs_nav();
  469. }
  470. // prepare first element and show
  471. maybe_preload(true);
  472. close_img_preload();
  473. };
  474. /* remove lightbox pre-show classes */
  475. var rm_pre_show_classes = function() {
  476. // show window and overlay
  477. $('#lcl_wrap').removeClass('lcl_pre_show').addClass('lcl_shown');
  478. //setTimeout(function() {
  479. $('#lcl_loader').removeClass('lcl_loader_pre_first_el');
  480. //}, (lcl_ai_opts.ol_time_diff));
  481. };
  482. /* setup lightbox code */
  483. var setup_code = function() {
  484. var o = lcl_ai_opts;
  485. var v = lcl_ai_vars;
  486. var wrap_classes = [];
  487. var css = '';
  488. // add class if IE <= 11 and for commands positions
  489. if(typeof(document.documentMode) == 'number') {
  490. $('body').addClass('lcl_old_ie');
  491. // actually disable middle nav
  492. if(o.cmd_position != 'outer') {o.nav_btn_pos = 'normal';}
  493. }
  494. if($('#lcl_wrap').length) {$('#lcl_wrap').remove();}
  495. $('body').append(lb_code);
  496. // command positions classes
  497. wrap_classes.push('lcl_'+o.ins_close_pos+'_close lcl_nav_btn_'+o.nav_btn_pos+' lcl_'+ o.ins_close_pos +'_close lcl_nav_btn_'+ o.nav_btn_pos);
  498. // hidden thumbs nav class
  499. if(
  500. o.tn_hidden === true ||
  501. (typeof(o.tn_hidden) == 'number' && ($(window).width() < o.tn_hidden || $(window).height() < o.tn_hidden))
  502. ) {
  503. wrap_classes.push('lcl_tn_hidden');
  504. }
  505. // hide texts class
  506. if(
  507. o.txt_hidden === true ||
  508. (typeof(o.txt_hidden) == 'number' && ($(window).width() < o.txt_hidden || $(window).height() < o.txt_hidden))
  509. ) {
  510. wrap_classes.push('lcl_hidden_txt');
  511. }
  512. // no carousel class
  513. if(!o.carousel) {
  514. wrap_classes.push('lcl_no_carousel');
  515. }
  516. // mobile class
  517. if(lcl_on_mobile) {wrap_classes.push('lcl_on_mobile');}
  518. // custom classes
  519. if(o.wrap_class) {wrap_classes.push(o.wrap_class);}
  520. // manage elements
  521. wrap_classes.push('lcl_'+ o.cmd_position +'_cmd');
  522. if(o.cmd_position != 'inner') {
  523. var nav = $('#lcl_nav_cmd').detach();
  524. $('#lcl_wrap').prepend(nav);
  525. }
  526. if(!o.slideshow) {$('.lcl_play').remove();}
  527. if(!o.txt_toggle_cmd) {$('.lcl_txt_toggle').remove();}
  528. if(!o.socials) {$('.lcl_socials').remove();}
  529. if(!o.download) {$('.lcl_download').remove();}
  530. if(!o.counter || v.elems.length < 2) {$('.lcl_counter').remove();}
  531. if(!o.img_zoom) {$('.lcl_zoom_icon').remove();}
  532. // fullscreen
  533. v.force_fullscreen = false;
  534. if(!o.fullscreen) {
  535. $('.lcl_fullscreen').remove();
  536. }
  537. else if(o.fs_only === true || (typeof(o.fs_only) == 'number' && ($(window).width() < o.fs_only || $(window).height() < o.fs_only))) {
  538. $('.lcl_fullscreen').remove();
  539. lcl_ai_vars.force_fullscreen = true;
  540. }
  541. // prev/next buttons
  542. if(v.elems.length < 2) {
  543. $('.lcl_prev, .lcl_play, .lcl_next').remove();
  544. } else {
  545. if(o.nav_btn_pos == 'middle') {
  546. css += '.lcl_prev, .lcl_next {margin: '+ o.padding +'px;}';
  547. }
  548. }
  549. // thumbs nav
  550. if(!o.thumbs_nav || lcl_ai_vars.elems.length < 2) {
  551. $('#lcl_thumbs_nav, .lcl_thumbs_toggle').remove();
  552. }
  553. else {
  554. $('#lcl_thumbs_nav').css('height', o.thumbs_h); // use JS to pick outerHeight after
  555. var th_margins = $('#lcl_thumbs_nav').outerHeight(true) - o.thumbs_h;
  556. css += '#lcl_window {margin-top: '+ ((o.thumbs_h - th_margins ) * -1) +'px;}';
  557. }
  558. //////
  559. // apply skin and layout
  560. wrap_classes.push('lcl_txt_'+ o.data_position +' lcl_'+ o.skin);
  561. css += set_wrap_padding();
  562. css += '#lcl_overlay {background-color: '+ o.thumbs_h +'px; opacity: '+ o.ol_opacity +';}';
  563. if(o.ol_pattern) {$('#lcl_overlay').addClass('lcl_pattern_'+ o.ol_pattern);}
  564. if(o.modal) {$('#lcl_overlay').addClass('lcl_modal');}
  565. if(o.border_w) {css += '#lcl_window {border: '+ o.border_w +'px solid '+ o.border_col +';}';}
  566. if(o.padding) {css += '#lcl_subj, #lcl_txt, #lcl_nav_cmd {margin: '+ o.padding +'px;}';}
  567. if(o.radius) {css += '#lcl_window, #lcl_contents_wrap {border-radius: '+ o.radius +'px;}';}
  568. if(o.shadow) {css += '#lcl_window {box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);}';}
  569. if(o.cmd_position == 'inner' && o.ins_close_pos == 'corner') {
  570. css += '#lcl_corner_close {'+
  571. 'top: '+ ((o.border_w + Math.ceil($('#lcl_corner_close').outerWidth() / 2)) * -1) +'px;'+
  572. 'right: '+ ((o.border_w + Math.ceil($('#lcl_corner_close').outerHeight() / 2)) * -1) +';'+
  573. '}';
  574. }
  575. // custom CSS
  576. if($('#lcl_inline_style').length) {$('#lcl_inline_style').remove();}
  577. $('head').append(
  578. '<style type="text/css" id="lcl_inline_style">'+
  579. css +
  580. '#lcl_overlay {'+
  581. 'background-color: '+o.ol_color+';'+
  582. 'opacity: '+o.ol_opacity+';'+
  583. '}'+
  584. '#lcl_window, #lcl_txt, #lcl_subj {'+
  585. '-webkit-transition-duration: '+o.animation_time+'ms; transition-duration: '+o.animation_time+'ms;'+
  586. '}'+
  587. '#lcl_overlay {'+
  588. '-webkit-transition-duration: '+o.open_close_time+'ms; transition-duration: '+o.open_close_time+'ms;'+
  589. '}'+
  590. '.lcl_first_sizing #lcl_window, .lcl_is_closing #lcl_window {'+
  591. '-webkit-transition-duration: '+(o.open_close_time - o.ol_time_diff)+'ms; transition-duration: '+(o.open_close_time - o.ol_time_diff)+'ms;'+
  592. '}'+
  593. '.lcl_first_sizing #lcl_window {'+
  594. '-webkit-transition-delay: '+o.ol_time_diff+'ms; transition-delay: '+o.ol_time_diff+'ms;'+
  595. '}'+
  596. '#lcl_loader, #lcl_contents_wrap, #lcl_corner_close {'+
  597. '-webkit-transition-duration: '+o.fading_time+'ms; transition-duration: '+o.fading_time+'ms;'+
  598. '}'+
  599. '.lcl_toggling_txt #lcl_subj {'+ /* delay to allow sizing on text hiding */
  600. '-webkit-transition-delay: '+(o.fading_time + 200)+'ms !important; transition-delay: '+(o.fading_time + 200)+'ms !important;'+
  601. '}'+
  602. '.lcl_fullscreen_mode.lcl_txt_over:not(.lcl_tn_hidden) #lcl_txt, .lcl_fullscreen_mode.lcl_force_txt_over:not(.lcl_tn_hidden) #lcl_txt {'+ /* fs txt margin when thumbs are shown */
  603. 'max-height: calc(100% - 42px - '+ o.thumbs_h +'px);'+
  604. '}'+
  605. '.lcl_fullscreen_mode.lcl_playing_video.lcl_txt_over:not(.lcl_tn_hidden) #lcl_txt,'+
  606. '.lcl_fullscreen_mode.lcl_playing_video.lcl_force_txt_over:not(.lcl_tn_hidden) #lcl_txt {'+ /* fullscreen txt over margin when thumbs are shown */
  607. 'max-height: calc(100% - 42px - 45px - '+ o.thumbs_h +'px);'+
  608. '}</style>');
  609. //////
  610. // backup html/body inline CSS
  611. if(o.remove_scrollbar) {
  612. lcl_ai_vars.html_style = (typeof(jQuery('html').attr('style')) != 'undefined') ? jQuery('html').attr('style') : '';
  613. lcl_ai_vars.body_style = (typeof(jQuery('body').attr('style')) != 'undefined') ? jQuery('body').attr('style') : '';
  614. // avoid page scrolling and maintain contents position
  615. var orig_page_w = $(window).width();
  616. $('html').css('overflow', 'hidden');
  617. $('html').css({
  618. 'margin-right' : ($(window).width() - orig_page_w),
  619. 'touch-action' : 'none'
  620. });
  621. $('body').css({
  622. 'overflow' : 'visible',
  623. 'touch-action' : 'none'
  624. });
  625. }
  626. // opening element could already be shaped?
  627. var el = lcl_ai_vars.elems[v.elem_index];
  628. if(el.type != 'image' || (el.type == 'image' && typeof(v.img_sizes_cache[el.src]) != 'undefined')) {
  629. wrap_classes.push('lcl_show_already_shaped');
  630. } else {
  631. rm_pre_show_classes();
  632. }
  633. // apply wrap classes
  634. $('#lcl_wrap').addClass( wrap_classes.join(' ') );
  635. //////
  636. // html is appended and ready - callback
  637. if(typeof(o.html_is_ready) == 'function') {
  638. o.html_is_ready.call({opts : lcl_ai_opts, vars: lcl_ai_vars});
  639. }
  640. // lightbox html has been appended and managed
  641. if(!lcl_ai_vars.is_arr_instance) {
  642. var $subj = (lcl_ai_vars.elems_selector) ? $(lcl_ai_vars.elems_selector) : lcl_curr_obj;
  643. $subj.first().trigger('lcl_html_is_ready', [lcl_ai_opts, lcl_ai_vars]);
  644. }
  645. };
  646. /* returns wrapper padding css */
  647. var set_wrap_padding = function(entering_fullscreen) {
  648. if(typeof(entering_fullscreen) == 'undefined') {
  649. var padd_horiz = (100 - parseInt(lcl_ai_opts.max_width, 10)) / 2;
  650. var padd_vert = (100 - parseInt(lcl_ai_opts.max_height, 10)) / 2;
  651. return '#lcl_wrap {padding: '+ padd_vert+'vh '+padd_horiz+'vw;}';
  652. }
  653. else {
  654. return '#lcl_wrap {padding: 0;}';
  655. }
  656. };
  657. // prevent page touch scroll while moving a specific element
  658. var no_body_touch_scroll = function(selector) {
  659. var _overlay = $(selector)[0];
  660. var _clientY = null; // remember Y position on touch start
  661. _overlay.addEventListener('touchstart', function (event) {
  662. if (event.targetTouches.length === 1) {
  663. // detect single touch
  664. _clientY = event.targetTouches[0].clientY;
  665. }
  666. }, false);
  667. _overlay.addEventListener('touchmove', function (event) {
  668. if (event.targetTouches.length === 1) {
  669. // detect single touch
  670. disableRubberBand(event);
  671. }
  672. }, false);
  673. function disableRubberBand(event) {
  674. var clientY = event.targetTouches[0].clientY - _clientY;
  675. if (_overlay.scrollTop === 0 && clientY > 0) {
  676. // element is at the top of its scroll
  677. event.preventDefault();
  678. }
  679. if (isOverlayTotallyScrolled() && clientY < 0) {
  680. //element is at the top of its scroll
  681. event.preventDefault();
  682. }
  683. }
  684. function isOverlayTotallyScrolled() {
  685. // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions
  686. return _overlay.scrollHeight - _overlay.scrollTop <= _overlay.clientHeight;
  687. }
  688. };
  689. /* show element in lightbox */
  690. var show_element = function() {
  691. if(!lcl_shown) {return false;}
  692. var v = lcl_ai_vars;
  693. var el = v.elems[v.elem_index];
  694. $('#lcl_wrap').attr('lc-lelem', v.elem_index);
  695. // if not carousel - set classes
  696. if(!lcl_ai_opts.carousel) {
  697. $('#lcl_wrap').removeClass('lcl_first_elem lcl_last_elem');
  698. if(!v.elem_index) {
  699. $('#lcl_wrap').addClass('lcl_first_elem');
  700. }
  701. else if(v.elem_index == (v.elems.length - 1)) {
  702. $('#lcl_wrap').addClass('lcl_last_elem');
  703. }
  704. }
  705. // global trigger - before element population | args: element object, element index
  706. $(document).trigger('lcl_before_populate_global', [el, v.elem_index]);
  707. // populate
  708. populate_lb(el);
  709. //////
  710. // trigger right before EVERY element showing | args: element index, element object
  711. if(!v.is_arr_instance) {
  712. var $subj = (v.elems_selector) ? $(v.elems_selector) : lcl_curr_obj;
  713. $subj.first().trigger('lcl_before_show', [el, v.elem_index]);
  714. }
  715. // global trigger - before EVERY element showing | args: element object, element index
  716. $(document).trigger('lcl_before_show_global', [el, v.elem_index]);
  717. //////
  718. // actions on first opening
  719. if($('#lcl_wrap').hasClass('lcl_pre_first_el')) {
  720. // first element show - callback
  721. if(typeof(lcl_ai_opts.on_open) == 'function') {
  722. lcl_ai_opts.on_open.call({opts : lcl_ai_opts, vars: lcl_ai_vars});
  723. }
  724. // first element show | args: element
  725. if(!v.is_arr_instance) {
  726. var $subj = (v.elems_selector) ? $(v.elems_selector) : lcl_curr_obj;
  727. $subj.first().trigger('lcl_on_open', [el, v.elem_index]);
  728. }
  729. }
  730. //////
  731. // set sizes and display
  732. size_elem(el);
  733. //////
  734. $('#lcl_subj').removeClass('lcl_switching_el');
  735. };
  736. /* element has text ? */
  737. var elem_has_txt = function(el) {
  738. return (el.title || el.txt || el.author) ? true : false;
  739. };
  740. /* populate lightbox */
  741. var populate_lb = function(el){
  742. var el_index = lcl_ai_vars.elem_index;
  743. // reset
  744. $('#lcl_elem_wrap').removeAttr('style').removeAttr('class').empty();
  745. // set classes/atts
  746. $('#lcl_wrap').attr('lcl-type', el.type);
  747. $('#lcl_elem_wrap').addClass('lcl_'+ el.type +'_elem');
  748. // setup subect
  749. switch(el.type) {
  750. case 'image' :
  751. $('#lcl_elem_wrap').html('<img class="lcl_elem" style="visibility: hidden;" src="'+ el.src +'" />');
  752. $('#lcl_elem_wrap').css('background-image', 'url(\''+ el.src +'\')');
  753. break;
  754. default : // error message size
  755. $('#lcl_elem_wrap').html('<div id="lcl_inline" class="lcl_elem"><br/><br/>Error loading the resource .. </div>');
  756. break;
  757. }
  758. if(el.download) {
  759. $('.lcl_download').show();
  760. var arr = el.download.split('/');
  761. var filename = arr[ (arr.length -1) ];
  762. $('.lcl_download').html('<a href="'+ el.download +'" target="_blank" download="'+ filename +'"></a>');
  763. } else {
  764. $('.lcl_download').hide();
  765. }
  766. // counter
  767. $('.lcl_counter').html( (el_index+1) +' / '+ lcl_ai_vars.elems.length );
  768. // texts
  769. if(elem_has_txt(el) && el.type != 'unknown') {
  770. $('#lcl_wrap').removeClass('lcl_no_txt');
  771. $('.lcl_txt_toggle').show();
  772. if(el.title) {$('#lcl_txt').append('<h3 id="lcl_title">'+ el.title +'</h3>');}
  773. if(el.author) {$('#lcl_txt').append('<h5 id="lcl_author">by '+ el.author +'</h5>');}
  774. if(el.txt) {$('#lcl_txt').append('<section id="lcl_descr">'+ el.txt +'</section>');}
  775. // set class for bottom border
  776. if(el.txt) {
  777. if(el.title && el.author) {
  778. $('#lcl_txt h5').addClass('lcl_txt_border');
  779. }
  780. else {
  781. if($('#lcl_txt h3').length) {
  782. $('#lcl_txt h3').addClass('lcl_txt_border');
  783. } else {
  784. $('#lcl_txt h5').addClass('lcl_txt_border');
  785. }
  786. }
  787. }
  788. }
  789. else {
  790. $('.lcl_txt_toggle').hide();
  791. $('#lcl_wrap').addClass('lcl_no_txt');
  792. }
  793. // prevent body scroll moving text
  794. no_body_touch_scroll('#lcl_txt');
  795. };
  796. /* set element sizes */
  797. var size_elem = function(el, flags, txt_und_sizes) { // flags: no_txt_under, inner_cmd_checked
  798. var o = lcl_ai_opts;
  799. var w, h;
  800. if(typeof(flags) == 'undefined') {flags = {};}
  801. var fs_mode = ($('.lcl_fullscreen_mode').length) ? true : false;
  802. // calculate padding and borders
  803. var add_space = (fs_mode) ? 0 : ((parseInt(o.border_w, 10) * 2) + (parseInt(o.padding, 10) * 2));
  804. // is side-text layout? remove forced on hover
  805. if(typeof(flags.side_txt_checked) == 'undefined') {
  806. $('#lcl_wrap').removeClass('lcl_force_txt_over');
  807. }
  808. var side_txt = (!$('.lcl_force_txt_over').length && !$('.lcl_hidden_txt').length && $.inArray(o.data_position, ['rside', 'lside']) !== -1 && elem_has_txt(el)) ? $('#lcl_txt').outerWidth() : 0;
  809. // has thumbs nav?
  810. var thumbs_nav = (!fs_mode && $('#lcl_thumbs_nav').length && !$('.lcl_tn_hidden').length) ? $('#lcl_thumbs_nav').outerHeight(true) : 0;
  811. // outer commands?
  812. var cmd_h = (!fs_mode && $('.lcl_outer_cmd').length) ? $('#lcl_nav_cmd').outerHeight() : 0;
  813. // calculate max sizes
  814. var max_w = (fs_mode) ? $(window).width() : Math.floor($('#lcl_wrap').width()) - add_space - side_txt;
  815. var max_h = (fs_mode) ? $(window).height() : Math.floor($('#lcl_wrap').height()) - add_space - thumbs_nav - cmd_h;
  816. /////////
  817. // sizes already calculated by text under processor
  818. if(typeof(lcl_ai_vars.txt_und_sizes) == 'object') {
  819. w = lcl_ai_vars.txt_und_sizes.w;
  820. h = lcl_ai_vars.txt_und_sizes.h;
  821. }
  822. // normal processing
  823. else {
  824. switch(el.type) {
  825. case 'image' : // discard forced sizes
  826. $('#lcl_elem_wrap').css('bottom', 0);
  827. var img_sizes = lcl_ai_vars.img_sizes_cache[ el.src ];
  828. $('#lcl_elem_wrap img').css({
  829. 'maxWidth' : (img_sizes.w < max_w) ? img_sizes.w : max_w,
  830. 'maxHeight': (img_sizes.h < max_h) ? img_sizes.h : max_h
  831. });
  832. w = $('#lcl_elem_wrap img').width();
  833. h = $('#lcl_elem_wrap img').height();
  834. // is zero? then recurse waiting a bit
  835. if(!w || !h) {
  836. setTimeout(function() {
  837. size_elem(el, flags, txt_und_sizes);
  838. }, 30);
  839. return false;
  840. }
  841. // calculate text under
  842. if(elem_has_txt(el) && !$('.lcl_hidden_txt').length && o.data_position == 'under' && typeof(flags.no_txt_under) == 'undefined') {
  843. txt_under_h(w, h, max_h);
  844. $(document).off('lcl_txt_und_calc').on('lcl_txt_und_calc', function() {
  845. if(lcl_ai_vars.txt_und_sizes) {
  846. if(lcl_ai_vars.txt_und_sizes == 'no_under') {
  847. flags.no_txt_under = true;
  848. }
  849. return size_elem(el, flags);
  850. }
  851. });
  852. return false;
  853. }
  854. else {
  855. $('#lcl_subj').css('maxHeight', 'none');
  856. }
  857. break;
  858. default : // error message size
  859. w = 280;
  860. h = 125;
  861. break;
  862. }
  863. }
  864. // text on side - turn into text over if small screen or tiny lb
  865. if(
  866. (o.data_position == 'rside' || o.data_position == 'lside') &&
  867. !$('.lcl_no_txt').length && typeof(flags.side_txt_checked) == 'undefined'
  868. ) {
  869. var sto_w = w + add_space;
  870. var sto_h = h + add_space;
  871. var img_sizes = (el.type == 'image') ? lcl_ai_vars.img_sizes_cache[ el.src ] : '';
  872. if( // if image size or custom size is already tiny - skip
  873. (img_sizes && img_sizes.w > 400 && img_sizes.h > 400) ||
  874. (typeof(cust_w) != 'undefined' && (!cust_w || cust_w > 400)) ||
  875. (typeof(cust_h) != 'undefined' && (!cust_h || cust_h > 400))
  876. ) {
  877. if(!side_to_over_txt(sto_w, sto_h, side_txt)) {
  878. flags.side_txt_checked = true;
  879. return size_elem(el, flags);
  880. }
  881. }
  882. }
  883. // reset text under var
  884. lcl_ai_vars.txt_und_sizes = false;
  885. // force outer commands?
  886. if(
  887. typeof(flags.inner_cmd_checked) == 'undefined' &&
  888. (o.cmd_position == 'inner' || el.force_outer_cmd) &&
  889. inner_to_outer_cmd(el, w)
  890. ) {
  891. flags.inner_cmd_checked = true;
  892. return size_elem(el, flags);
  893. }
  894. // set lb window sizes
  895. $('#lcl_wrap').removeClass('lcl_pre_first_el');
  896. $('#lcl_window').css({
  897. 'width' : (fs_mode) ? '100%' : w + add_space + side_txt,
  898. 'height': (fs_mode) ? '100%' : h + add_space
  899. });
  900. // if has to be shown already shaped
  901. if($('.lcl_show_already_shaped').length) {
  902. setTimeout(function() { // allow CSS propagation
  903. $('#lcl_wrap').removeClass('lcl_show_already_shaped');
  904. rm_pre_show_classes();
  905. }, 10);
  906. }
  907. // check thumbs nav arrows visibility
  908. thumbs_nav_arrows_vis();
  909. if(typeof(lcl_size_n_show_timeout) != 'undefined') {clearTimeout(lcl_size_n_show_timeout);}
  910. var timing = ($('.lcl_first_sizing').length) ? o.open_close_time : o.animation_time;
  911. if($('.lcl_browser_resize').length) {timing = 0;}
  912. lcl_size_n_show_timeout = setTimeout(function() {
  913. if(lcl_is_active) {lcl_is_active = false;}
  914. // autoplay if first opening
  915. if($('.lcl_first_sizing').length) {
  916. if( o.autoplay && lcl_ai_vars.elems.length > 1 &&
  917. (o.carousel || lcl_ai_vars.elem_index < (lcl_ai_vars.elems.length - 1))
  918. ) {
  919. lcl_start_slideshow();
  920. }
  921. }
  922. // fullscreen - image rendering manag
  923. if(el.type == 'image') {
  924. if($('.lcl_fullscreen_mode').length) {
  925. fs_img_manag();
  926. } else {
  927. $('.lcl_image_elem').css('background-size', 'cover');
  928. }
  929. }
  930. $('#lcl_wrap').removeClass('lcl_first_sizing lcl_switching_elem lcl_is_resizing lcl_browser_resize');
  931. $(document).trigger('lcl_resized_window');
  932. }, timing);
  933. };
  934. /* track window size changes */
  935. $(window).resize(function() {
  936. if(!lcl_shown || obj != lcl_curr_obj || $('.lcl_toggling_fs').length) {return false;}
  937. $('#lcl_wrap').addClass('lcl_browser_resize');
  938. if(typeof(lcl_rs_defer) != 'undefined') {clearTimeout(lcl_rs_defer);}
  939. lcl_rs_defer = setTimeout(function() {
  940. lcl_resize();
  941. }, 50);
  942. });
  943. /* calculate text under size - return new element's width and height in an object */
  944. var txt_under_h = function(curr_w, curr_h, max_height, recursive_count) {
  945. var rc = (typeof(recursive_count) == 'undefined') ? 1 : recursive_count;
  946. var fs_mode = $('.lcl_fullscreen_mode').length;
  947. var old_txt_h = Math.ceil( $('#lcl_txt').outerHeight() );
  948. var w_ratio = curr_w / curr_h;
  949. // fullscreen mode and thumbs - text always over
  950. if(fs_mode && $('#lcl_thumbs_nav').length) {
  951. $('#lcl_wrap').addClass('lcl_force_txt_over');
  952. $('#lcl_subj').css('maxHeight', 'none');
  953. $('#lcl_txt').css({
  954. 'right' : 0,
  955. 'width' : 'auto'
  956. });
  957. lcl_ai_vars.txt_und_sizes = 'no_under';
  958. $(document).trigger('lcl_txt_und_calc');
  959. return false;
  960. }
  961. // reset
  962. $('#lcl_wrap').removeClass('lcl_force_txt_over').addClass('lcl_txt_under_calc');
  963. if(!fs_mode) {
  964. $('#lcl_txt').css({
  965. 'right' : 'auto',
  966. 'width' : curr_w
  967. });
  968. } else {
  969. $('#lcl_txt').css({
  970. 'right' : 0,
  971. 'width' : 'auto'
  972. });
  973. }
  974. // wait for CSS to be rendered
  975. if(typeof(lcl_txt_under_calc) != 'undefined') {clearInterval(lcl_txt_under_calc);}
  976. lcl_txt_under_calc = setTimeout(function() {
  977. var txt_h = Math.ceil( $('#lcl_txt').outerHeight() );
  978. var overflow = (curr_h + txt_h) - max_height;
  979. // fullscreen mode (no thumbs) - just set max height
  980. if(fs_mode) {
  981. $('#lcl_wrap').removeClass('lcl_txt_under_calc');
  982. $('#lcl_subj').css('maxHeight', (curr_h - txt_h));
  983. lcl_ai_vars.txt_und_sizes = {w: curr_w, h: curr_h};
  984. $(document).trigger('lcl_txt_und_calc');
  985. return false;
  986. }
  987. // there's overflow - recurse
  988. if(overflow > 0 && ( typeof(recursive_count) == 'undefined' || recursive_count < 10)) {
  989. var new_h = curr_h - overflow;
  990. var new_w = Math.floor(new_h * w_ratio);
  991. if(new_w < 200 || new_h < 200) {
  992. $('#lcl_wrap').removeClass('lcl_txt_under_calc').addClass('lcl_force_txt_over'); // screen too small or image excessively tall - switch to text over
  993. $('#lcl_subj').css('maxHeight', 'none');
  994. $('#lcl_txt').css({
  995. 'right' : 0,
  996. 'width' : 'auto'
  997. });
  998. lcl_ai_vars.txt_und_sizes = 'no_under';
  999. $(document).trigger('lcl_txt_und_calc');
  1000. return true;
  1001. }
  1002. return txt_under_h(new_w, new_h, max_height, (rc + 1));
  1003. }
  1004. // no overflow - ok
  1005. else {
  1006. /*$('#lcl_txt').css({
  1007. 'right' : 0,
  1008. 'width' : 'auto'
  1009. });*/
  1010. $('#lcl_wrap').removeClass('lcl_txt_under_calc');
  1011. $('#lcl_subj').css('maxHeight', (curr_h + lcl_ai_opts.padding));
  1012. lcl_ai_vars.txt_und_sizes = {
  1013. w: curr_w,
  1014. h: (curr_h + txt_h)
  1015. };
  1016. $(document).trigger('lcl_txt_und_calc');
  1017. return true;
  1018. }
  1019. }, 80); // min val to let CSS propagate
  1020. };
  1021. /* is lightbox too small to show contents with side text? turn into over txt */
  1022. var side_to_over_txt = function(w, h, side_txt_w) {
  1023. var already_forced = $('.lcl_force_txt_over').length;
  1024. if(w < 400 || h < 400) {
  1025. if(already_forced) {return true;}
  1026. $('#lcl_wrap').addClass('lcl_force_txt_over');
  1027. }
  1028. else {
  1029. if(!already_forced) {return true;}
  1030. $('#lcl_wrap').removeClass('lcl_force_txt_over');
  1031. }
  1032. return false;
  1033. };
  1034. /* are inner commands too wide for lb window? move to outer */
  1035. var inner_to_outer_cmd = function(el, window_width) {
  1036. var o = lcl_ai_opts;
  1037. var fs_mode = ($('.lcl_fullscreen_mode').length) ? true : false;
  1038. // if already acted - reset
  1039. if($('.lcl_forced_outer_cmd').length) {
  1040. $('#lcl_wrap').removeClass('lcl_forced_outer_cmd');
  1041. $('#lcl_wrap').removeClass('lcl_outer_cmd').addClass('lcl_inner_cmd');
  1042. var nav = $('#lcl_nav_cmd').detach();
  1043. $('#lcl_window').prepend(nav);
  1044. }
  1045. // calculate
  1046. if(!fs_mode && lcl_ai_vars.inner_cmd_w === false) {
  1047. lcl_ai_vars.inner_cmd_w = 0;
  1048. jQuery('#lcl_nav_cmd .lcl_icon').each(function() {
  1049. if(($(this).hasClass('lcl_prev') || $(this).hasClass('lcl_next')) && o.nav_btn_pos == 'middle') {
  1050. return true;
  1051. }
  1052. lcl_ai_vars.inner_cmd_w = lcl_ai_vars.inner_cmd_w + $(this).outerWidth(true);
  1053. });
  1054. }
  1055. // is wider?
  1056. if(fs_mode || el.force_outer_cmd || window_width <= lcl_ai_vars.inner_cmd_w) {
  1057. $('#lcl_wrap').addClass('lcl_forced_outer_cmd');
  1058. $('#lcl_wrap').removeClass('lcl_inner_cmd').addClass('lcl_outer_cmd');
  1059. var nav = $('#lcl_nav_cmd').detach();
  1060. $('#lcl_wrap').prepend(nav);
  1061. return true;
  1062. }
  1063. else {
  1064. return false;
  1065. }
  1066. };
  1067. //////////////////////////////////////////////////////////////
  1068. /* switch element - new_el could be "next", "prev" or element index */
  1069. var switch_elem = function(new_el, slideshow_switch) {
  1070. var v = lcl_ai_vars;
  1071. var carousel = lcl_ai_opts.carousel;
  1072. if(lcl_is_active || v.elems.length < 2 || $('.lcl_switching_elem').length) {return false;}
  1073. // find and sanitize new index
  1074. if(new_el == 'next'){
  1075. if(v.elem_index == (v.elems.length - 1)) {
  1076. if(!carousel) {return false;}
  1077. new_el = 0;
  1078. }
  1079. else {
  1080. new_el = v.elem_index + 1;
  1081. }
  1082. }
  1083. else if(new_el == 'prev') {
  1084. if(!v.elem_index) {
  1085. if(!carousel) {return false;}
  1086. new_el = (v.elems.length - 1);
  1087. }
  1088. else {
  1089. new_el = v.elem_index - 1;
  1090. }
  1091. }
  1092. else {
  1093. new_el = parseInt(new_el, 10);
  1094. if(new_el < 0 || new_el >= v.elems.length || new_el == v.elem_index) {
  1095. return false;
  1096. }
  1097. }
  1098. // if slideshow is active
  1099. if(typeof(lcl_slideshow) != 'undefined') {
  1100. // if isn't a slideshow switch and it is active || if isn't carousel and index is latest one - stop ss
  1101. if(typeof(slideshow_switch) == 'undefined' || (!carousel && new_el == (v.elems.length - 1))) {
  1102. lcl_stop_slideshow();
  1103. }
  1104. }
  1105. // hide current element and set a new one
  1106. lcl_is_active = true;
  1107. thumbs_nav_scroll_to_item(new_el);
  1108. $('#lcl_wrap').addClass('lcl_switching_elem');
  1109. setTimeout(function() {
  1110. $('#lcl_wrap').removeClass('lcl_playing_video');
  1111. // switching element - callback
  1112. if(typeof(lcl_ai_opts.on_elem_switch) == 'function') {
  1113. lcl_ai_opts.on_elem_switch.call({opts : lcl_ai_opts, vars: lcl_ai_vars, new_el : new_el});
  1114. }
  1115. // switching | args: old_elem_id, new_elem_id
  1116. if(!v.is_arr_instance && lcl_curr_obj) {
  1117. var $subj = (v.elems_selector) ? $(v.elems_selector) : lcl_curr_obj;
  1118. $subj.first().trigger('lcl_on_elem_switch', [v.elem_index, new_el]);
  1119. }
  1120. //////
  1121. $('#lcl_wrap').removeClass('lcl_no_txt lcl_loading_iframe');
  1122. $('#lcl_txt').empty();
  1123. v.elem_index = new_el;
  1124. maybe_preload(true);
  1125. close_img_preload();
  1126. }, lcl_ai_opts.fading_time);
  1127. };
  1128. /* temporary stop slideshow (to wait a preloader for example) */
  1129. var temp_slideshow_stop = function() {
  1130. if(typeof(lcl_slideshow) == 'undefined') {return false;}
  1131. clearInterval(lcl_slideshow);
  1132. };
  1133. /* progressbar animation management */
  1134. var progbar_animate = function(first_run) {
  1135. var o = lcl_ai_opts;
  1136. if(!o.progressbar) {return false;}
  1137. var delay = (first_run) ? 0 : (o.animation_time + o.fading_time);
  1138. var time = o.slideshow_time + o.animation_time - delay;
  1139. if(!$('#lcl_progressbar').length) {
  1140. $('#lcl_wrap').append('<div id="lcl_progressbar"></div>');
  1141. }
  1142. if(typeof(lcl_pb_timeout) != 'undefined') {clearTimeout(lcl_pb_timeout);}
  1143. lcl_pb_timeout = setTimeout(function() {
  1144. $('#lcl_progressbar').stop(true).removeAttr('style').css('width', 0).animate({width: '100%'}, time, 'linear', function() {
  1145. $('#lcl_progressbar').fadeTo(0, 0); // duration through CSS
  1146. });
  1147. }, delay);
  1148. };
  1149. /* close lightbox */
  1150. var close_lb = function() {
  1151. if(!lcl_shown) {return false;}
  1152. // lightbox is about to be closed - callback
  1153. if(typeof(lcl_ai_opts.on_close) == 'function') {
  1154. lcl_ai_opts.on_close.call({opts : lcl_ai_opts, vars: lcl_ai_vars});
  1155. }
  1156. // event on lightbox closing
  1157. if(!lcl_ai_vars.is_arr_instance) {
  1158. var $subj = (lcl_ai_vars.elems_selector) ? $(lcl_ai_vars.elems_selector) : lcl_curr_obj;
  1159. $subj.first().trigger('lcl_on_close');
  1160. }
  1161. // global trigger - on lightbox closing
  1162. $(document).trigger('lcl_on_close_global');
  1163. //////
  1164. $('#lcl_wrap').removeClass('lcl_shown').addClass('lcl_is_closing lcl_tn_hidden');
  1165. lcl_stop_slideshow();
  1166. // exit fullscreen
  1167. if($('.lcl_fullscreen_mode').length) {
  1168. exit_browser_fs();
  1169. }
  1170. // remove lb - wait for animations
  1171. setTimeout(function() {
  1172. $('#lcl_wrap, #lcl_inline_style').remove();
  1173. // restore html/body inline CSS
  1174. if(lcl_ai_opts.remove_scrollbar) {
  1175. jQuery('html').attr('style', lcl_ai_vars.html_style);
  1176. jQuery('body').attr('style', lcl_ai_vars.body_style);
  1177. }
  1178. // global trigger - lightybox has been closed and code removed
  1179. $(document).trigger('lcl_closed_global');
  1180. lcl_curr_obj = false;
  1181. lcl_curr_opts = false;
  1182. lcl_curr_vars = false;
  1183. lcl_shown = false;
  1184. lcl_is_active = false;
  1185. }, (lcl_ai_opts.open_close_time + 80));
  1186. if(typeof(lcl_size_check) != 'undefined') {clearTimeout(lcl_size_check);}
  1187. };
  1188. //////////////////////////////////////////////////////////////
  1189. /* Setup fullscreen mode */
  1190. var enter_fullscreen = function(set_browser_status, on_opening) {
  1191. if(typeof(on_opening) == 'undefined') {on_opening = false;}
  1192. if(!lcl_shown || !lcl_ai_opts.fullscreen || (!on_opening && lcl_is_active)) {return false;}
  1193. var o = lcl_ai_opts;
  1194. var v = lcl_ai_vars;
  1195. // hide window elements
  1196. $('#lcl_wrap').addClass('lcl_toggling_fs');
  1197. // enbale browser's fs
  1198. if(o.browser_fs_mode && typeof(set_browser_status) != 'undefined') {
  1199. if (document.documentElement.requestFullscreen) {
  1200. document.documentElement.requestFullscreen();
  1201. } else if (document.documentElement.msRequestFullscreen) {
  1202. document.documentElement.msRequestFullscreen();
  1203. } else if (document.documentElement.mozRequestFullScreen) {
  1204. document.documentElement.mozRequestFullScreen();
  1205. } else if (document.documentElement.webkitRequestFullscreen) {
  1206. document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
  1207. }
  1208. }
  1209. // set wrap class - recalculate sizes - show
  1210. var timing = (on_opening) ? o.open_close_time : o.fading_time;
  1211. setTimeout(function() {
  1212. $('#lcl_wrap').addClass('lcl_fullscreen_mode');
  1213. set_wrap_padding(true);
  1214. if(!on_opening) {
  1215. size_elem( v.elems[v.elem_index] );
  1216. }
  1217. // disable fs toogle class when has been sized
  1218. $(document).on('lcl_resized_window', function() {
  1219. $(document).off('lcl_resized_window');
  1220. // text under or on opening - recalculate
  1221. if(on_opening || (lcl_curr_opts.data_position == 'under' && !$('.lcl_force_txt_over').length)) {
  1222. size_elem( lcl_curr_vars.elems[lcl_curr_vars.elem_index] );
  1223. }
  1224. setTimeout(function() {
  1225. $('#lcl_wrap').removeClass('lcl_toggling_fs');
  1226. }, 150 + 50); // 150 is forced sizing timing for fs switch
  1227. });
  1228. }, timing);
  1229. //////
  1230. // entering fullscreen - callback
  1231. if(typeof(o.on_fs_enter) == 'function') {
  1232. o.on_fs_enter.call({opts : o, vars: v});
  1233. }
  1234. // entering fullscreen - action
  1235. if(!lcl_ai_vars.is_arr_instance) {
  1236. lcl_curr_obj.first().trigger('lcl_on_fs_enter');
  1237. }
  1238. };
  1239. /* fullscreen image rendering manag - smart/fit/fill */
  1240. var fs_img_manag = function() {
  1241. var behav = lcl_ai_opts.fs_img_behavior;
  1242. if(lcl_ai_vars.elems[lcl_ai_vars.elem_index].type != 'image') {return false;}
  1243. var img_sizes = lcl_ai_vars.img_sizes_cache[ lcl_ai_vars.elems[lcl_ai_vars.elem_index].src ];
  1244. // if image is smaller than screen - bg size = auto
  1245. if($('.lcl_fullscreen_mode').length && img_sizes.w <= $('#lcl_subj').width() && img_sizes.h <= $('#lcl_subj').height()) {
  1246. $('.lcl_image_elem').css('background-size', 'auto');
  1247. return false;
  1248. }
  1249. // fit into screen
  1250. if(behav == 'fit') {
  1251. $('.lcl_image_elem').css('background-size', 'contain');
  1252. }
  1253. // fill screen
  1254. else if(behav == 'fill') {
  1255. $('.lcl_image_elem').css('background-size', 'cover');
  1256. }
  1257. // smart - fill only if is bigger than screen or same aspect ratio
  1258. else {
  1259. if(typeof(img_sizes) == 'undefined') {
  1260. $('.lcl_image_elem').css('background-size', 'cover');
  1261. return false;
  1262. }
  1263. var ratio_diff = ($(window).width() / $(window).height()) - (img_sizes.w / img_sizes.h);
  1264. var w_diff = $(window).width() - img_sizes.w;
  1265. var h_diff = $(window).height() - img_sizes.h;
  1266. if( (ratio_diff <= 1.15 && ratio_diff >= -1.15) && (w_diff <= 350 && h_diff <= 350) ) { // fill
  1267. $('.lcl_image_elem').css('background-size', 'cover');
  1268. }
  1269. else { // fit
  1270. $('.lcl_image_elem').css('background-size', 'contain');
  1271. }
  1272. }
  1273. };
  1274. /* exit fullscreen */
  1275. var exit_fullscreen = function(set_browser_status) {
  1276. if(!lcl_shown || !lcl_ai_opts.fullscreen || lcl_is_active) {return false;}
  1277. var o = lcl_ai_opts;
  1278. // hide window elements
  1279. $('#lcl_wrap').addClass('lcl_toggling_fs');
  1280. // set wrap class - recalculate sizes - show
  1281. setTimeout(function() {
  1282. // disable browser's fs
  1283. if(o.browser_fs_mode && typeof(set_browser_status) != 'undefined') {
  1284. exit_browser_fs();
  1285. }
  1286. set_wrap_padding();
  1287. $('#lcl_wrap').removeClass('lcl_fullscreen_mode');
  1288. // resize after a little while
  1289. setTimeout(function() {
  1290. size_elem( lcl_ai_vars.elems[lcl_ai_vars.elem_index] );
  1291. // disable fs toogle class
  1292. setTimeout(function() {
  1293. $('#lcl_wrap').removeClass('lcl_toggling_fs');
  1294. }, o.animation_time); // 150 is forced sizing timing for fs switch
  1295. }, 550); // 550 - wait browser to exit fs
  1296. }, o.fading_time);
  1297. //////
  1298. // exiting fullscreen - callback
  1299. if(typeof(o.on_fs_exit) == 'function') {
  1300. o.on_fs_exit.call({opts : lcl_ai_opts, vars: lcl_ai_vars});
  1301. }
  1302. // exiting fullscreen - action
  1303. if(!lcl_ai_vars.is_arr_instance) {
  1304. var $subj = (lcl_ai_vars.elems_selector) ? $(lcl_ai_vars.elems_selector) : lcl_curr_obj;
  1305. $subj.first().trigger('lcl_on_fs_exit');
  1306. }
  1307. };
  1308. /* trigger browser instruction to exit fullscreen mode */
  1309. var exit_browser_fs = function() {
  1310. if (document.exitFullscreen) {
  1311. document.exitFullscreen();
  1312. } else if (document.msExitFullscreen) {
  1313. document.msExitFullscreen();
  1314. } else if (document.mozCancelFullScreen) {
  1315. document.mozCancelFullScreen();
  1316. } else if (document.webkitExitFullscreen) {
  1317. document.webkitExitFullscreen();
  1318. }
  1319. };
  1320. //////////////////////////////////////////////////////////////
  1321. /* setup thumbnails navigator */
  1322. var setup_thumbs_nav = function() {
  1323. var mixed_types = false;
  1324. var tracked_type = false;
  1325. var uniq_id = Date.now();
  1326. $('#lcl_thumbs_nav').append('<span class="lcl_tn_prev"></span><ul class="lcl_tn_inner"></ul><span class="lcl_tn_next"></span>');
  1327. $('#lcl_thumbs_nav').attr('rel', uniq_id);
  1328. $.each(lcl_ai_vars.elems, function(i, v) {
  1329. if(v.type != 'unknown') {
  1330. if(!mixed_types) {
  1331. if(!tracked_type || tracked_type == v.type) {
  1332. tracked_type = v.type;
  1333. }
  1334. else {
  1335. mixed_types = true;
  1336. }
  1337. }
  1338. var bg = '',
  1339. bg_img = '';
  1340. tpc = ''; // thumbs preload class
  1341. // has got a specific thumbnail?
  1342. if(v.thumb) {
  1343. bg_img = v.thumb;
  1344. bg = 'style="background-image: url(\''+ v.thumb +'\');"';
  1345. }
  1346. else {
  1347. // find thumbnail for each source
  1348. switch(v.type) {
  1349. case 'image' : bg_img = v.src; break;
  1350. }
  1351. if(bg_img) {
  1352. // has thumbs maker?
  1353. if(lcl_ai_opts.thumbs_maker_url && v.poster) {
  1354. var base = lcl_ai_opts.thumbs_maker_url;
  1355. bg_img = base.replace('%URL%', encodeURIComponent(bg_img)).replace('%W%', lcl_ai_opts.thumbs_w).replace('%H%', lcl_ai_opts.thumbs_h);
  1356. }
  1357. bg = 'style="background-image: url(\''+ bg_img +'\');"';
  1358. }
  1359. }
  1360. // if iframe and html and no poster - skip
  1361. if((v.type == 'html' || v.type == 'iframe') && !bg) {return true;}
  1362. // video preview
  1363. var vp = (v.type == 'video' && !bg) ? '<video src="'+ v.src +'"></video>' : '';
  1364. // thumbs preload class
  1365. //if(!tpc && bg && typeof(lcl_ai_vars.img_sizes_cache[ bg_img ]) == 'undefined') {tpc = 'lcl_tn_preload';}
  1366. tpc = 'lcl_tn_preload';
  1367. // append
  1368. $('.lcl_tn_inner').append('<li class="lcl_tn_'+ v.type +' '+ tpc +'" title="'+ v.title +'" rel="'+i+'" '+ bg +'>'+ vp +'</li>');
  1369. // thumbs image preload
  1370. if(tpc) {
  1371. thumbs_nav_img_preload(bg_img, i, uniq_id);
  1372. }
  1373. }
  1374. });
  1375. // be sure at least 2 elements are left
  1376. if($('.lcl_tn_inner > li').length < 2) {
  1377. $('#lcl_thumbs_nav').remove();
  1378. return false;
  1379. }
  1380. $('.lcl_tn_inner > li').css('width', lcl_ai_opts.thumbs_w);
  1381. if(!lcl_on_mobile) {
  1382. $('.lcl_tn_inner').lcl_smoothscroll(0.3, 400, false, true);
  1383. }
  1384. // mixed type class
  1385. if(mixed_types && lcl_ai_opts.tn_icons) {
  1386. $('.lcl_tn_inner').addClass('lcl_tn_mixed_types');
  1387. }
  1388. // elem offset
  1389. thumbs_nav_scroll_to_item(lcl_ai_vars.elem_index);
  1390. };
  1391. /* thumbs image preload */
  1392. var thumbs_nav_img_preload = function(img_url, el_index, uniq_id) {
  1393. $('<img/>').bind("load", function(){
  1394. if(!lcl_ai_vars) {return false;}
  1395. lcl_ai_vars.img_sizes_cache[ img_url ] = {
  1396. w : this.width,
  1397. h : this.height
  1398. };
  1399. $('#lcl_thumbs_nav[rel='+ uniq_id +'] li[rel='+ el_index +']').removeClass('lcl_tn_preload');
  1400. setTimeout(function() {
  1401. thumbs_nav_arrows_vis();
  1402. thumbs_nav_arrows_opacity();
  1403. }, 500);
  1404. }).attr('src', img_url);
  1405. };
  1406. /* thumbs navigator - thumbs total width */
  1407. var thumbs_nav_elems_w = function() {
  1408. var thumbs_w = 0;
  1409. $('.lcl_tn_inner > li').each(function() {thumbs_w = thumbs_w + $(this).outerWidth(true);});
  1410. return thumbs_w;
  1411. };
  1412. /* thumbs navigator - arrows visibility */
  1413. var thumbs_nav_arrows_vis = function() {
  1414. if(!$('#lcl_thumbs_nav').length) {return false;}
  1415. if(thumbs_nav_elems_w() > $('.lcl_tn_inner').width()) {
  1416. $('#lcl_thumbs_nav').addClass('lcl_tn_has_arr');
  1417. } else {
  1418. $('#lcl_thumbs_nav').removeClass('lcl_tn_has_arr');
  1419. }
  1420. };
  1421. /* thumbs navigator - arrows opacity */
  1422. var thumbs_nav_arrows_opacity = function() {
  1423. var sl = $('.lcl_tn_inner').scrollLeft();
  1424. if(!sl) {
  1425. $('.lcl_tn_prev').addClass('lcl_tn_disabled_arr').stop(true).fadeTo(150, 1);
  1426. } else {
  1427. $('.lcl_tn_prev').removeClass('lcl_tn_disabled_arr').stop(true).fadeTo(150, 1);
  1428. }
  1429. if(sl >= (thumbs_nav_elems_w() - $('.lcl_tn_inner').width())) {
  1430. $('.lcl_tn_next').addClass('lcl_tn_disabled_arr').stop(true).fadeTo(150, 1);
  1431. } else {
  1432. $('.lcl_tn_next').removeClass('lcl_tn_disabled_arr').stop(true).fadeTo(150, 1);
  1433. }
  1434. };
  1435. $(document).on('lcl_smoothscroll_end', '.lcl_tn_inner', function(e) {
  1436. if(obj != lcl_curr_obj) {return true;}
  1437. thumbs_nav_arrows_opacity();
  1438. });
  1439. /* thumbs navigator - scroll to shown element - centering it */
  1440. var thumbs_nav_scroll_to_item = function(elem_id) {
  1441. var $subj = $('.lcl_tn_inner > li[rel='+ elem_id +']');
  1442. if(!$subj.length) {return false;}
  1443. var id = 0;
  1444. $('.lcl_tn_inner > li').each(function(i,v) {
  1445. if($(this).attr('rel') == elem_id) {
  1446. id = i;
  1447. return false;
  1448. }
  1449. });
  1450. // center thumb with scroll
  1451. var elem_w = $('.lcl_tn_inner > li').last().outerWidth();
  1452. var margin = parseInt($('.lcl_tn_inner > li').last().css('margin-left'), 10);
  1453. var wrap_w = $('.lcl_tn_inner').width();
  1454. var to_center = Math.floor( ($('.lcl_tn_inner').width() - elem_w - margin) / 2 );
  1455. var new_offset = ((elem_w * id) + margin * (id - 1)) + Math.floor(margin / 2) - to_center;
  1456. $('.lcl_tn_inner').stop(true).animate({"scrollLeft" : new_offset}, 500, function() {
  1457. $('.lcl_tn_inner').trigger('lcl_smoothscroll_end');
  1458. });
  1459. // set selected nav thumb class
  1460. $('.lcl_tn_inner > li').removeClass('lcl_sel_thumb');
  1461. $subj.addClass('lcl_sel_thumb');
  1462. };
  1463. /* lc smooth scroll system */
  1464. // suggested ratio = 0.3
  1465. // suggested duration = 400
  1466. $.fn.lcl_smoothscroll = function(ratio, duration, ignoreX, ignoreY) {
  1467. if(lcl_on_mobile) {return false;}
  1468. this.off("mousemove mousedown mouseup mouseenter mouseleave");
  1469. var $subj = this,
  1470. trackX = (typeof(ignoreX) == 'undefined' || !ignoreX) ? true : false,
  1471. trackY = (typeof(ignoreY) == 'undefined' || !ignoreY) ? true : false,
  1472. mouseout_timeout = false,
  1473. curDown = false,
  1474. curYPos = 0,
  1475. curXPos = 0,
  1476. startScrollY = 0,
  1477. startScrollX = 0,
  1478. scrollDif = 0;
  1479. $subj.mousemove(function(m){
  1480. if(curDown === true) {
  1481. $subj.stop(true);
  1482. if(trackX) {
  1483. $subj.scrollLeft(startScrollX + (curXPos - m.pageX));
  1484. }
  1485. if(trackY) {
  1486. $subj.scrollTop(startScrollY + (curYPos - m.pageY));
  1487. }
  1488. }
  1489. });
  1490. $subj.mouseover(function() {
  1491. if(mouseout_timeout) {
  1492. clearTimeout(mouseout_timeout);
  1493. }
  1494. });
  1495. $subj.mouseout(function() {
  1496. mouseout_timeout = setTimeout(function() {
  1497. curDown = false;
  1498. mouseout_timeout = false;
  1499. }, 500);
  1500. });
  1501. $subj.mousedown(function(m){
  1502. if(typeof(lc_sms_timeout) != 'undefined') {clearTimeout(lc_sms_timeout);}
  1503. curDown = true;
  1504. startScrollY = $subj.scrollTop();
  1505. startScrollX = $subj.scrollLeft();
  1506. curYPos = m.pageY;
  1507. curXPos = m.pageX;
  1508. });
  1509. $subj.mouseup(function(m){
  1510. curDown = false;
  1511. // smooth scroll
  1512. var currScrollY = $subj.scrollTop();
  1513. var scrollDiffY = (startScrollY - currScrollY) * -1;
  1514. var newScrollY = currScrollY + ( scrollDiffY * ratio);
  1515. var currScrollX = $subj.scrollLeft();
  1516. var scrollDiffX = (startScrollX - currScrollX) * -1;
  1517. var newScrollX = currScrollX + ( scrollDiffX * ratio);
  1518. // thumbs nav - if is tiny movement, simulate a true click on element
  1519. if(
  1520. (scrollDiffY < 3 && scrollDiffY > -3) &&
  1521. (scrollDiffX < 3 && scrollDiffX > -3)
  1522. ) {
  1523. $(m.target).trigger('lcl_tn_elem_click');
  1524. return false;
  1525. }
  1526. // animate (only if movement was wide enough)
  1527. if(scrollDiffY > 20 || scrollDiffX > 20) {
  1528. var anim_obj = {};
  1529. if(trackY) {
  1530. anim_obj["scrollTop"] = newScrollY;
  1531. }
  1532. if(trackX) {
  1533. anim_obj["scrollLeft"] = newScrollX;
  1534. }
  1535. $subj.stop(true).animate(anim_obj, duration, 'linear', function() {
  1536. $subj.trigger('lcl_smoothscroll_end');
  1537. });
  1538. }
  1539. });
  1540. };
  1541. //////////////////////////////////////////////////////////////
  1542. /* setup elements - click handlers */
  1543. if(!lcl_vars.is_arr_instance) {
  1544. if(lcl_settings.live_elements && lcl_vars.elems_selector) { // switch between static and dynamic elements retrieval
  1545. $(document).off('click', lcl_vars.elems_selector)
  1546. .on('click', lcl_vars.elems_selector, function(e) {
  1547. e.preventDefault();
  1548. // update elements count - live
  1549. var vars = $.data(obj, 'lcl_vars');
  1550. vars.elems_count = $(lcl_vars.elems_selector).length;
  1551. // open lightbox
  1552. open_lb(obj, $(this));
  1553. // binded element click - lb should open | args: clicked element
  1554. obj.first().trigger('lcl_clicked_elem', [$(this)]);
  1555. });
  1556. }
  1557. else {
  1558. obj.off('click');
  1559. obj.on('click', function(e) {
  1560. e.preventDefault();
  1561. open_lb(obj, $(this));
  1562. // binded element click - lb should open
  1563. obj.first().trigger('lcl_clicked_elem', [$(this)]);
  1564. });
  1565. }
  1566. }
  1567. /* close clicking overlay or button */
  1568. $(document).on('click', '#lcl_overlay:not(.lcl_modal), .lcl_close, #lcl_corner_close', function(e) {
  1569. if(obj != lcl_curr_obj) {return true;}
  1570. close_lb();
  1571. });
  1572. /* navigation button - prev */
  1573. $(document).on('click', '.lcl_prev', function(e) {
  1574. if(obj != lcl_curr_obj) {return true;}
  1575. switch_elem('prev');
  1576. });
  1577. /* navigation button - next */
  1578. $(document).on('click', '.lcl_next', function(e) {
  1579. if(obj != lcl_curr_obj) {return true;}
  1580. switch_elem('next');
  1581. });
  1582. /* Keyboard events */
  1583. $(document).bind('keydown',function(e){
  1584. if(lcl_shown) {
  1585. if(obj != lcl_curr_obj) {return true;}
  1586. // next
  1587. if (e.keyCode == 39) {
  1588. e.preventDefault();
  1589. switch_elem('next');
  1590. }
  1591. // prev
  1592. else if (e.keyCode == 37) {
  1593. e.preventDefault();
  1594. switch_elem('prev');
  1595. }
  1596. // close
  1597. else if (e.keyCode == 27) {
  1598. e.preventDefault();
  1599. close_lb();
  1600. }
  1601. // fullscreen
  1602. else if(e.keyCode == 122 && lcl_ai_opts.fullscreen) {
  1603. if(typeof(lcl_fs_key_timeout) != 'undefined') {clearTimeout(lcl_fs_key_timeout);}
  1604. lcl_fs_key_timeout = setTimeout(function() {
  1605. if($('.lcl_fullscreen_mode').length) {
  1606. exit_fullscreen();
  1607. } else {
  1608. enter_fullscreen();
  1609. }
  1610. }, 50);
  1611. }
  1612. }
  1613. });
  1614. /* elems navigation with mousewheel */
  1615. $(document).on('wheel', '#lcl_overlay, #lcl_window, #lcl_thumbs_nav:not(.lcl_tn_has_arr)', function(e) {
  1616. if(obj != lcl_curr_obj) {return true;}
  1617. // if has scrollers - avoid
  1618. if( lcl_curr_opts.mousewheel && e.target.scrollHeight <= $(e.target).height()) {
  1619. e.preventDefault();
  1620. var delta = e.originalEvent.deltaY;
  1621. if(delta > 0) {switch_elem('next');}
  1622. else {switch_elem('prev');}
  1623. }
  1624. });
  1625. /* next element clicking on image or zoom (where available with doubleclick) */
  1626. $(document).on('click', '.lcl_image_elem', function(e) {
  1627. if(obj != lcl_curr_obj) {return true;}
  1628. lcl_img_click_track = setTimeout(function() {
  1629. if(!$('.lcl_zoom_wrap').length) {
  1630. switch_elem('next');
  1631. }
  1632. }, 250);
  1633. });
  1634. /* toggle text */
  1635. $(document).on('click', '.lcl_txt_toggle', function(e) {
  1636. if(obj != lcl_curr_obj) {return true;}
  1637. var o = lcl_ai_opts;
  1638. // class lcl_toggling_txt enables window sizing animations
  1639. if(!lcl_is_active && !$('.lcl_no_txt').length && !$('.lcl_toggling_txt').length) {
  1640. if(o.data_position != 'over') {
  1641. var txt_on_side = (o.data_position == 'rside' || o.data_position == 'lside') ? true : false;
  1642. var forced_over = $('.lcl_force_txt_over').length;
  1643. var timing = (o.animation_time < 150) ? o.animation_time : 150;
  1644. var classes_delay = 0;
  1645. // if text on side - hide subject
  1646. if(txt_on_side && !forced_over) {
  1647. $('#lcl_subj').fadeTo(timing, 0);
  1648. }
  1649. // text under - hide
  1650. else {
  1651. if(!forced_over) {
  1652. $('#lcl_contents_wrap').fadeTo(timing, 0);
  1653. classes_delay = timing;
  1654. }
  1655. }
  1656. setTimeout(function() {
  1657. $('#lcl_wrap').toggleClass('lcl_hidden_txt');
  1658. }, classes_delay);
  1659. if(!forced_over) {
  1660. lcl_is_active = true;
  1661. $('#lcl_wrap').addClass('lcl_toggling_txt');
  1662. // wait until text is hidden
  1663. setTimeout(function() {
  1664. lcl_is_active = false;
  1665. lcl_resize();
  1666. }, o.animation_time);
  1667. // after sizing - disable animations again
  1668. setTimeout(function() {
  1669. $('#lcl_wrap').removeClass('lcl_toggling_txt');
  1670. if(txt_on_side && !forced_over) {
  1671. $('#lcl_subj').fadeTo(timing, 1);
  1672. } else {
  1673. if(!forced_over) {
  1674. $('#lcl_contents_wrap').fadeTo(timing, 1);
  1675. }
  1676. }
  1677. }, (o.animation_time * 2) + 50);
  1678. }
  1679. }
  1680. // text over - just hide
  1681. else {
  1682. $('#lcl_wrap').toggleClass('lcl_hidden_txt');
  1683. }
  1684. }
  1685. });
  1686. /* start/end slideshow */
  1687. $(document).on('click', '.lcl_play', function(e) {
  1688. if(obj != lcl_curr_obj) {return true;}
  1689. if($('.lcl_is_playing').length) {
  1690. lcl_stop_slideshow();
  1691. } else {
  1692. lcl_start_slideshow();
  1693. }
  1694. });
  1695. /* toggle socials */
  1696. $(document).on('click', '.lcl_socials', function(e) {
  1697. if(obj != lcl_curr_obj) {return true;}
  1698. // show
  1699. if(!$('.lcl_socials > div').length) {
  1700. var el = lcl_curr_vars.elems[ lcl_curr_vars.elem_index ];
  1701. var page_url = encodeURIComponent(window.location.href);
  1702. var url = encodeURIComponent(el.src);
  1703. var title = encodeURIComponent(el.title);
  1704. var descr = encodeURIComponent(el.txt);
  1705. // prepare and append code
  1706. var code =
  1707. '<div class="lcl_socials_tt lcl_tooltip lcl_tt_bottom">'+
  1708. '<a class="lcl_icon lcl_fb" onClick="window.open(\'https://www.facebook.com/sharer?u='+ page_url +'&display=popup\',\'sharer\',\'toolbar=0,status=0,width=590,height=325\');" href="javascript: void(0)"></a>'+
  1709. '<a class="lcl_icon lcl_twit" onClick="window.open(\'https://twitter.com/share?text=Check%20out%20%22'+ title +'%22%20@&url='+ page_url +'\',\'sharer\',\'toolbar=0,status=0,width=548,height=325\');" href="javascript: void(0)"></a>';
  1710. // on mobile - use Whatsapp
  1711. if(lcl_on_mobile) {
  1712. code += '<br/><a class="lcl_icon lcl_wa" href="whatsapp://send?text='+ page_url +'" data-action="share/whatsapp/share"></a>';
  1713. }
  1714. code +=
  1715. '<a class="lcl_icon lcl_pint" onClick="window.open(\'http://pinterest.com/pin/create/button/?url='+ page_url +'&media='+ url +'&description='+ title +'\',\'sharer\',\'toolbar=0,status=0,width=575,height=330\');" href="javascript: void(0)"></a>'+
  1716. '</div>';
  1717. $('.lcl_socials').addClass('lcl_socials_shown').html(code);
  1718. setTimeout(function() { // delay to let CSS execute animation
  1719. $('.lcl_socials_tt').addClass('lcl_show_tt');
  1720. }, 20);
  1721. }
  1722. // hide
  1723. else {
  1724. $('.lcl_socials_tt').removeClass('lcl_show_tt');
  1725. setTimeout(function() {
  1726. $('.lcl_socials').removeClass('lcl_socials_shown').empty();
  1727. }, 260);
  1728. }
  1729. });
  1730. /* toggle fullscreen via button */
  1731. $(document).on('click', '.lcl_fullscreen', function(e) {
  1732. if(obj != lcl_curr_obj) {return true;}
  1733. if($('.lcl_fullscreen_mode').length) {
  1734. exit_fullscreen(true);
  1735. } else {
  1736. enter_fullscreen(true);
  1737. }
  1738. });
  1739. /* thumbs navigator - toggle */
  1740. $(document).on('click', '.lcl_thumbs_toggle', function(e) {
  1741. if(obj != lcl_curr_obj) {return true;}
  1742. var fs_mode = $('.lcl_fullscreen_mode').length;
  1743. $('#lcl_wrap').addClass('lcl_toggling_tn').toggleClass('lcl_tn_hidden');
  1744. // if not fullscreen - hide contents
  1745. if(!fs_mode) {
  1746. setTimeout(function() {
  1747. lcl_resize();
  1748. }, 160);
  1749. }
  1750. setTimeout(function() {
  1751. $('#lcl_wrap').removeClass('lcl_toggling_tn');
  1752. }, lcl_curr_opts.animation_time + 50);
  1753. });
  1754. /* thumbs navigator - switch element */
  1755. var tn_track_touch = (lcl_on_mobile) ? ' click' : '';
  1756. $(document).on('lcl_tn_elem_click'+tn_track_touch, '.lcl_tn_inner > li', function(e) {
  1757. if(obj != lcl_curr_obj) {return true;}
  1758. var elem_id = $(this).attr('rel');
  1759. switch_elem( elem_id );
  1760. });
  1761. /* thumbs navigator - navigate with arrows click */
  1762. $(document).on('click', '.lcl_tn_prev:not(.lcl_tn_disabled_arr)', function(e) {
  1763. if(obj != lcl_curr_obj) {return true;}
  1764. $('.lcl_tn_inner').stop(true).animate({"scrollLeft" : ($('.lcl_tn_inner').scrollLeft() - lcl_curr_opts.thumbs_w - 10)}, 300, 'linear', function() {
  1765. $('.lcl_tn_inner').trigger('lcl_smoothscroll_end');
  1766. });
  1767. });
  1768. $(document).on('click', '.lcl_tn_next:not(.lcl_tn_disabled_arr)', function(e) {
  1769. if(obj != lcl_curr_obj) {return true;}
  1770. $('.lcl_tn_inner').stop(true).animate({"scrollLeft" : ($('.lcl_tn_inner').scrollLeft() + lcl_curr_opts.thumbs_w + 10)}, 300, 'linear', function() {
  1771. $('.lcl_tn_inner').trigger('lcl_smoothscroll_end');
  1772. });
  1773. });
  1774. /* thumbs navigator - navigate with mousewheel */
  1775. $(document).on('wheel', '#lcl_thumbs_nav.lcl_tn_has_arr', function(e) {
  1776. if(obj != lcl_curr_obj) {return true;}
  1777. e.preventDefault();
  1778. var delta = e.originalEvent.deltaY;
  1779. if(delta > 0) {$('.lcl_tn_prev:not(.lcl_tn_disabled_arr)').trigger('click');}
  1780. else {$('.lcl_tn_next:not(.lcl_tn_disabled_arr)').trigger('click');}
  1781. });
  1782. /* right click prevent */
  1783. $(document).on("contextmenu", "#lcl_wrap *", function() {
  1784. if(obj != lcl_curr_obj) {return true;}
  1785. if(lcl_ai_opts.rclick_prevent) {
  1786. return false;
  1787. }
  1788. });
  1789. /* avoid page scrolling on touch devices */
  1790. $(window).on('touchmove', function(e) {
  1791. var $t = $(e.target);
  1792. if(!lcl_shown || !lcl_on_mobile) {return true;}
  1793. if(obj != lcl_curr_obj) {return true;}
  1794. if(!$(e.target).parents('#lcl_window').length && !$(e.target).parents('#lcl_thumbs_nav').length) {
  1795. e.preventDefault();
  1796. }
  1797. });
  1798. /////////////////////////////////////////////////////////////
  1799. // touchswipe & zoom on pinch - requires alloy_finger.min.js
  1800. var touch_events = function() {
  1801. if(typeof(AlloyFinger) != 'function') {return false;}
  1802. lcl_is_pinching = false;
  1803. var el = document.querySelector('#lcl_wrap');
  1804. var af = new AlloyFinger(el, {
  1805. singleTap: function(e) {
  1806. // close lb tapping on overlay
  1807. if($(e.target).attr('id') == 'lcl_overlay' && !lcl_ai_opts.modal) {
  1808. lcl_close();
  1809. }
  1810. },
  1811. doubleTap: function (e) {
  1812. e.preventDefault();
  1813. zoom(true);
  1814. },
  1815. pinch: function(e) {
  1816. e.preventDefault();
  1817. lcl_is_pinching = true;
  1818. if(typeof(lcl_swipe_delay) != 'undefined') {clearTimeout(lcl_swipe_delay);}
  1819. if(typeof(lcl_pinch_delay) != 'undefined') {clearTimeout(lcl_pinch_delay);}
  1820. lcl_pinch_delay = setTimeout(function() {
  1821. if(e.scale > 1.2) {
  1822. zoom(true);
  1823. }
  1824. else if(e.scale < 0.8) {
  1825. zoom(false);
  1826. }
  1827. // avoid swipe if zoom-out
  1828. setTimeout(function() {
  1829. lcl_is_pinching = false;
  1830. }, 300);
  1831. }, 20);
  1832. },
  1833. touchStart: function(e) {
  1834. lcl_touchstartX = e.changedTouches[0].clientX;
  1835. },
  1836. touchEnd: function(e) { // simulate swipe with treshold
  1837. var diff = lcl_touchstartX - e.changedTouches[0].clientX;
  1838. if((diff < -50 || diff > 50) && !lcl_is_pinching) {
  1839. // ignore if consulting thumbs nav
  1840. if($(e.target).parents('#lcl_thumbs_nav').length) {
  1841. return false;
  1842. }
  1843. // do not swipe on zoomed
  1844. if($(e.target).parents('.lcl_zoom_wrap').length) {
  1845. return false;
  1846. }
  1847. var delay = ($(e.target).parents('.lcl_zoomable').length) ? 250 : 0;
  1848. if(typeof(lcl_swipe_delay) != 'undefined') {clearTimeout(lcl_swipe_delay);}
  1849. lcl_swipe_delay = setTimeout(function() {
  1850. if(diff < -50) {
  1851. switch_elem('prev');
  1852. }
  1853. else {
  1854. switch_elem('next');
  1855. }
  1856. }, delay);
  1857. }
  1858. }
  1859. });
  1860. };
  1861. /////////////////////////////////////////////////////////////
  1862. //// PUBLIC METHODS
  1863. // set current settings and vars - for actions with lightbox opened - return false if object not initialized
  1864. var set_curr_vars = function() {
  1865. if(!lcl_curr_obj) {return false;}
  1866. lcl_ai_vars = $.data(lcl_curr_obj, 'lcl_vars');
  1867. lcl_ai_opts = $.data(lcl_curr_obj, 'lcl_settings');
  1868. if(!lcl_ai_vars) {
  1869. console.error('LC Lightbox. Object not initialized');
  1870. return false;
  1871. }
  1872. return true;
  1873. };
  1874. // open lightbox
  1875. lcl_open = function(obj, index) {
  1876. lcl_ai_vars = $.data(obj, 'lcl_vars');
  1877. var v = lcl_ai_vars;
  1878. // check instance existence
  1879. if(!v) {
  1880. console.error('LC Lightbox - cannot open. Object not initialized');
  1881. return false;
  1882. }
  1883. else if(typeof(v.elems[index]) == 'undefined') {
  1884. console.error('LC Lightbox - cannot open. Unexisting index');
  1885. return false;
  1886. }
  1887. else {
  1888. v.elem_index = index;
  1889. $clicked_obj = (v.is_arr_instance) ? false : $(obj[index]);
  1890. return open_lb(obj, $clicked_obj);
  1891. }
  1892. };
  1893. // resize lightbox
  1894. lcl_resize = function() {
  1895. if(!lcl_shown || lcl_is_active || !set_curr_vars()) {return false;}
  1896. var v = lcl_ai_vars;
  1897. if(typeof(lcl_size_check) != 'undefined') {clearTimeout(lcl_size_check);}
  1898. lcl_size_check = setTimeout(function() {
  1899. $('#lcl_wrap').addClass('lcl_is_resizing');
  1900. thumbs_nav_arrows_opacity();
  1901. var el = v.elems[ v.elem_index ];
  1902. return size_elem(el);
  1903. }, 20);
  1904. };
  1905. // close lightbox and destroy vars
  1906. lcl_close = function() {
  1907. if(!lcl_shown || lcl_is_active || !set_curr_vars()) {return false;}
  1908. return close_lb();
  1909. };
  1910. // pagination (next/prev/index)
  1911. lcl_switch = function(new_el) {
  1912. if(!lcl_shown || lcl_is_active || !set_curr_vars()) {return false;}
  1913. return switch_elem(new_el);
  1914. };
  1915. // start slideshow
  1916. lcl_start_slideshow = function(restart) {
  1917. if(!lcl_shown || (typeof(restart) == 'undefined' && typeof(lcl_slideshow) != 'undefined') || !set_curr_vars()) {return false;}
  1918. var o = lcl_ai_opts;
  1919. // if is latest element and isn't carousel - return false
  1920. if(!o.carousel && lcl_ai_vars.elem_index == (lcl_ai_vars.elems.length - 1)) {
  1921. return false;
  1922. }
  1923. if(typeof(lcl_slideshow) != 'undefined') {clearInterval(lcl_slideshow);} // if reset timing
  1924. $('#lcl_wrap').addClass('lcl_is_playing');
  1925. var time = o.animation_time + o.slideshow_time;
  1926. // use progressbar?
  1927. progbar_animate(true);
  1928. // start
  1929. lcl_slideshow = setInterval(function() {
  1930. progbar_animate(false);
  1931. switch_elem('next', true);
  1932. }, time);
  1933. //////
  1934. if(typeof(restart) == 'undefined') {
  1935. // slideshow start - callback
  1936. if(typeof(o.slideshow_start) == 'function') {
  1937. o.slideshow_start.call({opts : o, vars: lcl_ai_vars});
  1938. }
  1939. // slideshow start - hook | args: interval time
  1940. if(!lcl_ai_vars.is_arr_instance) {
  1941. var $subj = (lcl_ai_vars.elems_selector) ? $(lcl_ai_vars.elems_selector) : lcl_curr_obj;
  1942. $subj.first().trigger('lcl_slideshow_start', [time]);
  1943. }
  1944. }
  1945. return true;
  1946. };
  1947. // stop slideshow
  1948. lcl_stop_slideshow = function() {
  1949. if(!lcl_shown || typeof(lcl_slideshow) == 'undefined' || !set_curr_vars()) {return false;}
  1950. var o = lcl_ai_opts;
  1951. // check instance existence
  1952. if(!o) {
  1953. console.error('LC Lightbox. Object not initialized');
  1954. return false;
  1955. }
  1956. clearInterval(lcl_slideshow); lcl_slideshow = undefined;
  1957. $('#lcl_wrap').removeClass('lcl_is_playing');
  1958. $('#lcl_progressbar').stop(true).animate({'marginTop' : ($('#lcl_progressbar').height() * -3)}, 300, function() {
  1959. $(this).remove();
  1960. });
  1961. //////
  1962. // slideshow end - callback
  1963. if(typeof(o.slideshow_end) == 'function') {
  1964. o.slideshow_end.call({opts : lcl_ai_opts, vars: lcl_ai_vars});
  1965. }
  1966. // slideshow end - hook
  1967. if(!lcl_ai_vars.is_arr_instance) {
  1968. var $subj = (lcl_ai_vars.elems_selector) ? $(lcl_ai_vars.elems_selector) : lcl_curr_obj;
  1969. $subj.first().trigger('lcl_slideshow_end', []);
  1970. }
  1971. return true;
  1972. };
  1973. return obj;
  1974. };
  1975. })(jQuery);