lc_lightbox.lite.js 80 KB

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