/*! lightgallery - v1.6.6 - 2017-12-20 * http://sachinchoolur.github.io/lightgallery/ * copyright (c) 2017 sachin n; licensed gplv3 */ (function (root, factory) { if (typeof define === 'function' && define.amd) { // amd. register as an anonymous module unless amdmoduleid is set define(['jquery'], function (a0) { return (factory(a0)); }); } else if (typeof exports === 'object') { // node. does not work with strict commonjs, but // only commonjs-like environments that support module.exports, // like node. module.exports = factory(require('jquery')); } else { factory(root["jquery"]); } }(this, function ($) { (function() { 'use strict'; var defaults = { mode: 'lg-slide', // ex : 'ease' csseasing: 'ease', //'for jquery animation' easing: 'linear', speed: 600, height: '100%', width: '100%', addclass: '', startclass: 'lg-start-zoom', backdropduration: 150, hidebarsdelay: 6000, useleft: false, closable: true, loop: true, esckey: true, keypress: true, controls: true, slideendanimatoin: true, hidecontrolonend: false, mousewheel: true, getcaptionfromtitleoralt: true, // .lg-item || '.lg-sub-html' appendsubhtmlto: '.lg-sub-html', subhtmlselectorrelative: false, /** * @desc number of preload slides * will exicute only after the current slide is fully loaded. * * @ex you clicked on 4th image and if preload = 1 then 3rd slide and 5th * slide will be loaded in the background after the 4th slide is fully loaded.. * if preload is 2 then 2nd 3rd 5th 6th slides will be preloaded.. ... ... * */ preload: 1, showafterload: true, selector: '', selectwithin: '', nexthtml: '', prevhtml: '', // 0, 1 index: false, iframemaxwidth: '100%', download: true, counter: true, appendcounterto: '.lg-toolbar', swipethreshold: 50, enableswipe: true, enabledrag: true, dynamic: false, dynamicel: [], galleryid: 1 }; function plugin(element, options) { // current lightgallery element this.el = element; // current jquery element this.$el = $(element); // lightgallery settings this.s = $.extend({}, defaults, options); // when using dynamic mode, ensure dynamicel is an array if (this.s.dynamic && this.s.dynamicel !== 'undefined' && this.s.dynamicel.constructor === array && !this.s.dynamicel.length) { throw ('when using dynamic mode, you must also define dynamicel as an array.'); } // lightgallery modules this.modules = {}; // false when lightgallery complete first slide; this.lgalleryon = false; this.lgbusy = false; // timeout function for hiding controls; this.hidebartimeout = false; // to determine browser supports for touch events; this.istouch = ('ontouchstart' in document.documentelement); // disable hidecontrolonend if sildeendanimation is true if (this.s.slideendanimatoin) { this.s.hidecontrolonend = false; } // gallery items if (this.s.dynamic) { this.$items = this.s.dynamicel; } else { if (this.s.selector === 'this') { this.$items = this.$el; } else if (this.s.selector !== '') { if (this.s.selectwithin) { this.$items = $(this.s.selectwithin).find(this.s.selector); } else { this.$items = this.$el.find($(this.s.selector)); } } else { this.$items = this.$el.children(); } } // .lg-item this.$slide = ''; // .lg-outer this.$outer = ''; this.init(); return this; } plugin.prototype.init = function() { var _this = this; // s.preload should not be more than $item.length if (_this.s.preload > _this.$items.length) { _this.s.preload = _this.$items.length; } // if dynamic option is enabled execute immediately var _hash = window.location.hash; if (_hash.indexof('lg=' + this.s.galleryid) > 0) { _this.index = parseint(_hash.split('&slide=')[1], 10); $('body').addclass('lg-from-hash'); if (!$('body').hasclass('lg-on')) { settimeout(function() { _this.build(_this.index); }); $('body').addclass('lg-on'); } } if (_this.s.dynamic) { _this.$el.trigger('onbeforeopen.lg'); _this.index = _this.s.index || 0; // prevent accidental double execution if (!$('body').hasclass('lg-on')) { settimeout(function() { _this.build(_this.index); $('body').addclass('lg-on'); }); } } else { // using different namespace for click because click event should not unbind if selector is same object('this') _this.$items.on('click.lgcustom', function(event) { // for ie8 try { event.preventdefault(); event.preventdefault(); } catch (er) { event.returnvalue = false; } _this.$el.trigger('onbeforeopen.lg'); _this.index = _this.s.index || _this.$items.index(this); // prevent accidental double execution if (!$('body').hasclass('lg-on')) { _this.build(_this.index); $('body').addclass('lg-on'); } }); } }; plugin.prototype.build = function(index) { var _this = this; _this.structure(); // module constructor $.each($.fn.lightgallery.modules, function(key) { _this.modules[key] = new $.fn.lightgallery.modules[key](_this.el); }); // initiate slide function _this.slide(index, false, false, false); if (_this.s.keypress) { _this.keypress(); } if (_this.$items.length > 1) { _this.arrow(); settimeout(function() { _this.enabledrag(); _this.enableswipe(); }, 50); if (_this.s.mousewheel) { _this.mousewheel(); } } else { _this.$slide.on('click.lg', function() { _this.$el.trigger('onslideclick.lg'); }); } _this.counter(); _this.closegallery(); _this.$el.trigger('onafteropen.lg'); // hide controllers if mouse doesn't move for some period _this.$outer.on('mousemove.lg click.lg touchstart.lg', function() { _this.$outer.removeclass('lg-hide-items'); cleartimeout(_this.hidebartimeout); // timeout will be cleared on each slide movement also _this.hidebartimeout = settimeout(function() { _this.$outer.addclass('lg-hide-items'); }, _this.s.hidebarsdelay); }); _this.$outer.trigger('mousemove.lg'); }; plugin.prototype.structure = function() { var list = ''; var controls = ''; var i = 0; var subhtmlcont = ''; var template; var _this = this; $('body').append('
'); $('.lg-backdrop').css('transition-duration', this.s.backdropduration + 'ms'); // create gallery items for (i = 0; i < this.$items.length; i++) { list += '
'; } // create controlls if (this.s.controls && this.$items.length > 1) { controls = '
' + '' + '' + '
'; } if (this.s.appendsubhtmlto === '.lg-sub-html') { subhtmlcont = '
'; } template = '
' + '
' + '
' + list + '
' + '
' + '' + '
' + controls + subhtmlcont + '
' + '
'; $('body').append(template); this.$outer = $('.lg-outer'); this.$slide = this.$outer.find('.lg-item'); if (this.s.useleft) { this.$outer.addclass('lg-use-left'); // set mode lg-slide if use left is true; this.s.mode = 'lg-slide'; } else { this.$outer.addclass('lg-use-css3'); } // for fixed height gallery _this.settop(); $(window).on('resize.lg orientationchange.lg', function() { settimeout(function() { _this.settop(); }, 100); }); // add class lg-current to remove initial transition this.$slide.eq(this.index).addclass('lg-current'); // add class for css support and transition mode if (this.docss()) { this.$outer.addclass('lg-css3'); } else { this.$outer.addclass('lg-css'); // set speed 0 because no animation will happen if browser doesn't support css3 this.s.speed = 0; } this.$outer.addclass(this.s.mode); if (this.s.enabledrag && this.$items.length > 1) { this.$outer.addclass('lg-grab'); } if (this.s.showafterload) { this.$outer.addclass('lg-show-after-load'); } if (this.docss()) { var $inner = this.$outer.find('.lg-inner'); $inner.css('transition-timing-function', this.s.csseasing); $inner.css('transition-duration', this.s.speed + 'ms'); } settimeout(function() { $('.lg-backdrop').addclass('in'); }); settimeout(function() { _this.$outer.addclass('lg-visible'); }, this.s.backdropduration); if (this.s.download) { this.$outer.find('.lg-toolbar').append(''); } // store the current scroll top value to scroll back after closing the gallery.. this.prevscrolltop = $(window).scrolltop(); }; // for fixed height gallery plugin.prototype.settop = function() { if (this.s.height !== '100%') { var wh = $(window).height(); var top = (wh - parseint(this.s.height, 10)) / 2; var $lgallery = this.$outer.find('.lg'); if (wh >= parseint(this.s.height, 10)) { $lgallery.css('top', top + 'px'); } else { $lgallery.css('top', '0px'); } } }; // find css3 support plugin.prototype.docss = function() { // check for css animation support var support = function() { var transition = ['transition', 'moztransition', 'webkittransition', 'otransition', 'mstransition', 'khtmltransition']; var root = document.documentelement; var i = 0; for (i = 0; i < transition.length; i++) { if (transition[i] in root.style) { return true; } } }; if (support()) { return true; } return false; }; /** * @desc check the given src is video * @param {string} src * @return {object} video type * ex:{ youtube : ["//www.youtube.com/watch?v=c0asjgsyxcy", "c0asjgsyxcy"] } */ plugin.prototype.isvideo = function(src, index) { var html; if (this.s.dynamic) { html = this.s.dynamicel[index].html; } else { html = this.$items.eq(index).attr('data-html'); } if (!src) { if(html) { return { html5: true }; } else { console.error('lightgallery :- data-src is not pvovided on slide item ' + (index + 1) + '. please make sure the selector property is properly configured. more info - http://sachinchoolur.github.io/lightgallery/demos/html-markup.html'); return false; } } var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)/i); var vimeo = src.match(/\/\/(?:www\.)?vimeo.com\/([0-9a-z\-_]+)/i); var dailymotion = src.match(/\/\/(?:www\.)?dai.ly\/([0-9a-z\-_]+)/i); var vk = src.match(/\/\/(?:www\.)?(?:vk\.com|vkontakte\.ru)\/(?:video_ext\.php\?)(.*)/i); if (youtube) { return { youtube: youtube }; } else if (vimeo) { return { vimeo: vimeo }; } else if (dailymotion) { return { dailymotion: dailymotion }; } else if (vk) { return { vk: vk }; } }; /** * @desc create image counter * ex: 1/10 */ plugin.prototype.counter = function() { if (this.s.counter) { $(this.s.appendcounterto).append('
' + (parseint(this.index, 10) + 1) + ' / ' + this.$items.length + '
'); } }; /** * @desc add sub-html into the slide * @param {number} index - index of the slide */ plugin.prototype.addhtml = function(index) { var subhtml = null; var subhtmlurl; var $currentele; if (this.s.dynamic) { if (this.s.dynamicel[index].subhtmlurl) { subhtmlurl = this.s.dynamicel[index].subhtmlurl; } else { subhtml = this.s.dynamicel[index].subhtml; } } else { $currentele = this.$items.eq(index); if ($currentele.attr('data-sub-html-url')) { subhtmlurl = $currentele.attr('data-sub-html-url'); } else { subhtml = $currentele.attr('data-sub-html'); if (this.s.getcaptionfromtitleoralt && !subhtml) { subhtml = $currentele.attr('title') || $currentele.find('img').first().attr('alt'); } } } if (!subhtmlurl) { if (typeof subhtml !== 'undefined' && subhtml !== null) { // get first letter of subhtml // if first letter starts with . or # get the html form the jquery object var fl = subhtml.substring(0, 1); if (fl === '.' || fl === '#') { if (this.s.subhtmlselectorrelative && !this.s.dynamic) { subhtml = $currentele.find(subhtml).html(); } else { subhtml = $(subhtml).html(); } } } else { subhtml = ''; } } if (this.s.appendsubhtmlto === '.lg-sub-html') { if (subhtmlurl) { this.$outer.find(this.s.appendsubhtmlto).load(subhtmlurl); } else { this.$outer.find(this.s.appendsubhtmlto).html(subhtml); } } else { if (subhtmlurl) { this.$slide.eq(index).load(subhtmlurl); } else { this.$slide.eq(index).append(subhtml); } } // add lg-empty-html class if title doesn't exist if (typeof subhtml !== 'undefined' && subhtml !== null) { if (subhtml === '') { this.$outer.find(this.s.appendsubhtmlto).addclass('lg-empty-html'); } else { this.$outer.find(this.s.appendsubhtmlto).removeclass('lg-empty-html'); } } this.$el.trigger('onafterappendsubhtml.lg', [index]); }; /** * @desc preload slides * @param {number} index - index of the slide */ plugin.prototype.preload = function(index) { var i = 1; var j = 1; for (i = 1; i <= this.s.preload; i++) { if (i >= this.$items.length - index) { break; } this.loadcontent(index + i, false, 0); } for (j = 1; j <= this.s.preload; j++) { if (index - j < 0) { break; } this.loadcontent(index - j, false, 0); } }; /** * @desc load slide content into slide. * @param {number} index - index of the slide. * @param {boolean} rec - if true call loadcontent() function again. * @param {boolean} delay - delay for adding complete class. it is 0 except first time. */ plugin.prototype.loadcontent = function(index, rec, delay) { var _this = this; var _hasposter = false; var _$img; var _src; var _poster; var _srcset; var _sizes; var _html; var getresponsivesrc = function(srcitms) { var rswidth = []; var rssrc = []; for (var i = 0; i < srcitms.length; i++) { var __src = srcitms[i].split(' '); // manage empty space if (__src[0] === '') { __src.splice(0, 1); } rssrc.push(__src[0]); rswidth.push(__src[1]); } var wwidth = $(window).width(); for (var j = 0; j < rswidth.length; j++) { if (parseint(rswidth[j], 10) > wwidth) { _src = rssrc[j]; break; } } }; if (_this.s.dynamic) { if (_this.s.dynamicel[index].poster) { _hasposter = true; _poster = _this.s.dynamicel[index].poster; } _html = _this.s.dynamicel[index].html; _src = _this.s.dynamicel[index].src; if (_this.s.dynamicel[index].responsive) { var srcdyitms = _this.s.dynamicel[index].responsive.split(','); getresponsivesrc(srcdyitms); } _srcset = _this.s.dynamicel[index].srcset; _sizes = _this.s.dynamicel[index].sizes; } else { if (_this.$items.eq(index).attr('data-poster')) { _hasposter = true; _poster = _this.$items.eq(index).attr('data-poster'); } _html = _this.$items.eq(index).attr('data-html'); _src = _this.$items.eq(index).attr('href') || _this.$items.eq(index).attr('data-src'); if (_this.$items.eq(index).attr('data-responsive')) { var srcitms = _this.$items.eq(index).attr('data-responsive').split(','); getresponsivesrc(srcitms); } _srcset = _this.$items.eq(index).attr('data-srcset'); _sizes = _this.$items.eq(index).attr('data-sizes'); } //if (_src || _srcset || _sizes || _poster) { var iframe = false; if (_this.s.dynamic) { if (_this.s.dynamicel[index].iframe) { iframe = true; } } else { if (_this.$items.eq(index).attr('data-iframe') === 'true') { iframe = true; } } var _isvideo = _this.isvideo(_src, index); if (!_this.$slide.eq(index).hasclass('lg-loaded')) { if (iframe) { _this.$slide.eq(index).prepend('
'); } else if (_hasposter) { var videoclass = ''; if (_isvideo && _isvideo.youtube) { videoclass = 'lg-has-youtube'; } else if (_isvideo && _isvideo.vimeo) { videoclass = 'lg-has-vimeo'; } else { videoclass = 'lg-has-html5'; } _this.$slide.eq(index).prepend('
'); } else if (_isvideo) { _this.$slide.eq(index).prepend('
'); _this.$el.trigger('hasvideo.lg', [index, _src, _html]); } else { _this.$slide.eq(index).prepend('
'); } _this.$el.trigger('onaferappendslide.lg', [index]); _$img = _this.$slide.eq(index).find('.lg-object'); if (_sizes) { _$img.attr('sizes', _sizes); } if (_srcset) { _$img.attr('srcset', _srcset); try { picturefill({ elements: [_$img[0]] }); } catch (e) { console.warn('lightgallery :- if you want srcset to be supported for older browser please include picturefil version 2 javascript library in your document.'); } } if (this.s.appendsubhtmlto !== '.lg-sub-html') { _this.addhtml(index); } _this.$slide.eq(index).addclass('lg-loaded'); } _this.$slide.eq(index).find('.lg-object').on('load.lg error.lg', function() { // for first time add some delay for displaying the start animation. var _speed = 0; // do not change the delay value because it is required for zoom plugin. // if gallery opened from direct url (hash) speed value should be 0 if (delay && !$('body').hasclass('lg-from-hash')) { _speed = delay; } settimeout(function() { _this.$slide.eq(index).addclass('lg-complete'); _this.$el.trigger('onslideitemload.lg', [index, delay || 0]); }, _speed); }); // @todo check load state for html5 videos if (_isvideo && _isvideo.html5 && !_hasposter) { _this.$slide.eq(index).addclass('lg-complete'); } if (rec === true) { if (!_this.$slide.eq(index).hasclass('lg-complete')) { _this.$slide.eq(index).find('.lg-object').on('load.lg error.lg', function() { _this.preload(index); }); } else { _this.preload(index); } } //} }; /** * @desc slide function for lightgallery ** slide() gets call on start ** ** set lg.on true once slide() function gets called. ** call loadcontent() on slide() function inside settimeout ** ** on first slide we do not want any animation like slide of fade ** ** so on first slide( if lg.on if false that is first slide) loadcontent() should start loading immediately ** ** else loadcontent() should wait for the transition to complete. ** ** so set timeout s.speed + 50 <=> ** loadcontent() will load slide content in to the particular slide ** ** it has recursion (rec) parameter. if rec === true loadcontent() will call preload() function. ** ** preload will execute only when the previous slide is fully loaded (images iframe) ** ** avoid simultaneous image load <=> ** preload() will check for s.preload value and call loadcontent() again accoring to preload value ** loadcontent() <====> preload(); * @param {number} index - index of the slide * @param {boolean} fromtouch - true if slide function called via touch event or mouse drag * @param {boolean} fromthumb - true if slide function called via thumbnail click * @param {string} direction - direction of the slide(next/prev) */ plugin.prototype.slide = function(index, fromtouch, fromthumb, direction) { var _previndex = this.$outer.find('.lg-current').index(); var _this = this; // prevent if multiple call // required for hsh plugin if (_this.lgalleryon && (_previndex === index)) { return; } var _length = this.$slide.length; var _time = _this.lgalleryon ? this.s.speed : 0; if (!_this.lgbusy) { if (this.s.download) { var _src; if (_this.s.dynamic) { _src = _this.s.dynamicel[index].downloadurl !== false && (_this.s.dynamicel[index].downloadurl || _this.s.dynamicel[index].src); } else { _src = _this.$items.eq(index).attr('data-download-url') !== 'false' && (_this.$items.eq(index).attr('data-download-url') || _this.$items.eq(index).attr('href') || _this.$items.eq(index).attr('data-src')); } if (_src) { $('#lg-download').attr('href', _src); _this.$outer.removeclass('lg-hide-download'); } else { _this.$outer.addclass('lg-hide-download'); } } this.$el.trigger('onbeforeslide.lg', [_previndex, index, fromtouch, fromthumb]); _this.lgbusy = true; cleartimeout(_this.hidebartimeout); // add title if this.s.appendsubhtmlto === lg-sub-html if (this.s.appendsubhtmlto === '.lg-sub-html') { // wait for slide animation to complete settimeout(function() { _this.addhtml(index); }, _time); } this.arrowdisable(index); if (!direction) { if (index < _previndex) { direction = 'prev'; } else if (index > _previndex) { direction = 'next'; } } if (!fromtouch) { // remove all transitions _this.$outer.addclass('lg-no-trans'); this.$slide.removeclass('lg-prev-slide lg-next-slide'); if (direction === 'prev') { //prevslide this.$slide.eq(index).addclass('lg-prev-slide'); this.$slide.eq(_previndex).addclass('lg-next-slide'); } else { // next slide this.$slide.eq(index).addclass('lg-next-slide'); this.$slide.eq(_previndex).addclass('lg-prev-slide'); } // give 50 ms for browser to add/remove class settimeout(function() { _this.$slide.removeclass('lg-current'); //_this.$slide.eq(_previndex).removeclass('lg-current'); _this.$slide.eq(index).addclass('lg-current'); // reset all transitions _this.$outer.removeclass('lg-no-trans'); }, 50); } else { this.$slide.removeclass('lg-prev-slide lg-current lg-next-slide'); var touchprev; var touchnext; if (_length > 2) { touchprev = index - 1; touchnext = index + 1; if ((index === 0) && (_previndex === _length - 1)) { // next slide touchnext = 0; touchprev = _length - 1; } else if ((index === _length - 1) && (_previndex === 0)) { // prev slide touchnext = 0; touchprev = _length - 1; } } else { touchprev = 0; touchnext = 1; } if (direction === 'prev') { _this.$slide.eq(touchnext).addclass('lg-next-slide'); } else { _this.$slide.eq(touchprev).addclass('lg-prev-slide'); } _this.$slide.eq(index).addclass('lg-current'); } if (_this.lgalleryon) { settimeout(function() { _this.loadcontent(index, true, 0); }, this.s.speed + 50); settimeout(function() { _this.lgbusy = false; _this.$el.trigger('onafterslide.lg', [_previndex, index, fromtouch, fromthumb]); }, this.s.speed); } else { _this.loadcontent(index, true, _this.s.backdropduration); _this.lgbusy = false; _this.$el.trigger('onafterslide.lg', [_previndex, index, fromtouch, fromthumb]); } _this.lgalleryon = true; if (this.s.counter) { $('#lg-counter-current').text(index + 1); } } _this.index = index; }; /** * @desc go to next slide * @param {boolean} fromtouch - true if slide function called via touch event */ plugin.prototype.gotonextslide = function(fromtouch) { var _this = this; var _loop = _this.s.loop; if (fromtouch && _this.$slide.length < 3) { _loop = false; } if (!_this.lgbusy) { if ((_this.index + 1) < _this.$slide.length) { _this.index++; _this.$el.trigger('onbeforenextslide.lg', [_this.index]); _this.slide(_this.index, fromtouch, false, 'next'); } else { if (_loop) { _this.index = 0; _this.$el.trigger('onbeforenextslide.lg', [_this.index]); _this.slide(_this.index, fromtouch, false, 'next'); } else if (_this.s.slideendanimatoin && !fromtouch) { _this.$outer.addclass('lg-right-end'); settimeout(function() { _this.$outer.removeclass('lg-right-end'); }, 400); } } } }; /** * @desc go to previous slide * @param {boolean} fromtouch - true if slide function called via touch event */ plugin.prototype.gotoprevslide = function(fromtouch) { var _this = this; var _loop = _this.s.loop; if (fromtouch && _this.$slide.length < 3) { _loop = false; } if (!_this.lgbusy) { if (_this.index > 0) { _this.index--; _this.$el.trigger('onbeforeprevslide.lg', [_this.index, fromtouch]); _this.slide(_this.index, fromtouch, false, 'prev'); } else { if (_loop) { _this.index = _this.$items.length - 1; _this.$el.trigger('onbeforeprevslide.lg', [_this.index, fromtouch]); _this.slide(_this.index, fromtouch, false, 'prev'); } else if (_this.s.slideendanimatoin && !fromtouch) { _this.$outer.addclass('lg-left-end'); settimeout(function() { _this.$outer.removeclass('lg-left-end'); }, 400); } } } }; plugin.prototype.keypress = function() { var _this = this; if (this.$items.length > 1) { $(window).on('keyup.lg', function(e) { if (_this.$items.length > 1) { if (e.keycode === 37) { e.preventdefault(); _this.gotoprevslide(); } if (e.keycode === 39) { e.preventdefault(); _this.gotonextslide(); } } }); } $(window).on('keydown.lg', function(e) { if (_this.s.esckey === true && e.keycode === 27) { e.preventdefault(); if (!_this.$outer.hasclass('lg-thumb-open')) { _this.destroy(); } else { _this.$outer.removeclass('lg-thumb-open'); } } }); }; plugin.prototype.arrow = function() { var _this = this; this.$outer.find('.lg-prev').on('click.lg', function() { _this.gotoprevslide(); }); this.$outer.find('.lg-next').on('click.lg', function() { _this.gotonextslide(); }); }; plugin.prototype.arrowdisable = function(index) { // disable arrows if s.hidecontrolonend is true if (!this.s.loop && this.s.hidecontrolonend) { if ((index + 1) < this.$slide.length) { this.$outer.find('.lg-next').removeattr('disabled').removeclass('disabled'); } else { this.$outer.find('.lg-next').attr('disabled', 'disabled').addclass('disabled'); } if (index > 0) { this.$outer.find('.lg-prev').removeattr('disabled').removeclass('disabled'); } else { this.$outer.find('.lg-prev').attr('disabled', 'disabled').addclass('disabled'); } } }; plugin.prototype.settranslate = function($el, xvalue, yvalue) { // jquery supports automatic css prefixing since jquery 1.8.0 if (this.s.useleft) { $el.css('left', xvalue); } else { $el.css({ transform: 'translate3d(' + (xvalue) + 'px, ' + yvalue + 'px, 0px)' }); } }; plugin.prototype.touchmove = function(startcoords, endcoords) { var distance = endcoords - startcoords; if (math.abs(distance) > 15) { // reset opacity and transition duration this.$outer.addclass('lg-dragging'); // move current slide this.settranslate(this.$slide.eq(this.index), distance, 0); // move next and prev slide with current slide this.settranslate($('.lg-prev-slide'), -this.$slide.eq(this.index).width() + distance, 0); this.settranslate($('.lg-next-slide'), this.$slide.eq(this.index).width() + distance, 0); } }; plugin.prototype.touchend = function(distance) { var _this = this; // keep slide animation for any mode while dragg/swipe if (_this.s.mode !== 'lg-slide') { _this.$outer.addclass('lg-slide'); } this.$slide.not('.lg-current, .lg-prev-slide, .lg-next-slide').css('opacity', '0'); // set transition duration settimeout(function() { _this.$outer.removeclass('lg-dragging'); if ((distance < 0) && (math.abs(distance) > _this.s.swipethreshold)) { _this.gotonextslide(true); } else if ((distance > 0) && (math.abs(distance) > _this.s.swipethreshold)) { _this.gotoprevslide(true); } else if (math.abs(distance) < 5) { // trigger click if distance is less than 5 pix _this.$el.trigger('onslideclick.lg'); } _this.$slide.removeattr('style'); }); // remove slide class once drag/swipe is completed if mode is not slide settimeout(function() { if (!_this.$outer.hasclass('lg-dragging') && _this.s.mode !== 'lg-slide') { _this.$outer.removeclass('lg-slide'); } }, _this.s.speed + 100); }; plugin.prototype.enableswipe = function() { var _this = this; var startcoords = 0; var endcoords = 0; var ismoved = false; if (_this.s.enableswipe && _this.docss()) { _this.$slide.on('touchstart.lg', function(e) { if (!_this.$outer.hasclass('lg-zoomed') && !_this.lgbusy) { e.preventdefault(); _this.manageswipeclass(); startcoords = e.originalevent.targettouches[0].pagex; } }); _this.$slide.on('touchmove.lg', function(e) { if (!_this.$outer.hasclass('lg-zoomed')) { e.preventdefault(); endcoords = e.originalevent.targettouches[0].pagex; _this.touchmove(startcoords, endcoords); ismoved = true; } }); _this.$slide.on('touchend.lg', function() { if (!_this.$outer.hasclass('lg-zoomed')) { if (ismoved) { ismoved = false; _this.touchend(endcoords - startcoords); } else { _this.$el.trigger('onslideclick.lg'); } } }); } }; plugin.prototype.enabledrag = function() { var _this = this; var startcoords = 0; var endcoords = 0; var isdraging = false; var ismoved = false; if (_this.s.enabledrag && _this.docss()) { _this.$slide.on('mousedown.lg', function(e) { // execute only on .lg-object if (!_this.$outer.hasclass('lg-zoomed')) { if ($(e.target).hasclass('lg-object') || $(e.target).hasclass('lg-video-play')) { e.preventdefault(); if (!_this.lgbusy) { _this.manageswipeclass(); startcoords = e.pagex; isdraging = true; // ** fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723 _this.$outer.scrollleft += 1; _this.$outer.scrollleft -= 1; // * _this.$outer.removeclass('lg-grab').addclass('lg-grabbing'); _this.$el.trigger('ondragstart.lg'); } } } }); $(window).on('mousemove.lg', function(e) { if (isdraging) { ismoved = true; endcoords = e.pagex; _this.touchmove(startcoords, endcoords); _this.$el.trigger('ondragmove.lg'); } }); $(window).on('mouseup.lg', function(e) { if (ismoved) { ismoved = false; _this.touchend(endcoords - startcoords); _this.$el.trigger('ondragend.lg'); } else if ($(e.target).hasclass('lg-object') || $(e.target).hasclass('lg-video-play')) { _this.$el.trigger('onslideclick.lg'); } // prevent execution on click if (isdraging) { isdraging = false; _this.$outer.removeclass('lg-grabbing').addclass('lg-grab'); } }); } }; plugin.prototype.manageswipeclass = function() { var _touchnext = this.index + 1; var _touchprev = this.index - 1; if (this.s.loop && this.$slide.length > 2) { if (this.index === 0) { _touchprev = this.$slide.length - 1; } else if (this.index === this.$slide.length - 1) { _touchnext = 0; } } this.$slide.removeclass('lg-next-slide lg-prev-slide'); if (_touchprev > -1) { this.$slide.eq(_touchprev).addclass('lg-prev-slide'); } this.$slide.eq(_touchnext).addclass('lg-next-slide'); }; plugin.prototype.mousewheel = function() { var _this = this; _this.$outer.on('mousewheel.lg', function(e) { if (!e.deltay) { return; } if (e.deltay > 0) { _this.gotoprevslide(); } else { _this.gotonextslide(); } e.preventdefault(); }); }; plugin.prototype.closegallery = function() { var _this = this; var mousedown = false; this.$outer.find('.lg-close').on('click.lg', function() { _this.destroy(); }); if (_this.s.closable) { // if you drag the slide and release outside gallery gets close on chrome // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer _this.$outer.on('mousedown.lg', function(e) { if ($(e.target).is('.lg-outer') || $(e.target).is('.lg-item ') || $(e.target).is('.lg-img-wrap')) { mousedown = true; } else { mousedown = false; } }); _this.$outer.on('mouseup.lg', function(e) { if ($(e.target).is('.lg-outer') || $(e.target).is('.lg-item ') || $(e.target).is('.lg-img-wrap') && mousedown) { if (!_this.$outer.hasclass('lg-dragging')) { _this.destroy(); } } }); } }; plugin.prototype.destroy = function(d) { var _this = this; if (!d) { _this.$el.trigger('onbeforeclose.lg'); $(window).scrolltop(_this.prevscrolltop); } /** * if d is false or undefined destroy will only close the gallery * plugins instance remains with the element * * if d is true destroy will completely remove the plugin */ if (d) { if (!_this.s.dynamic) { // only when not using dynamic mode is $items a jquery collection this.$items.off('click.lg click.lgcustom'); } $.removedata(_this.el, 'lightgallery'); } // unbind all events added by lightgallery this.$el.off('.lg.tm'); // distroy all lightgallery modules $.each($.fn.lightgallery.modules, function(key) { if (_this.modules[key]) { _this.modules[key].destroy(); } }); this.lgalleryon = false; cleartimeout(_this.hidebartimeout); this.hidebartimeout = false; $(window).off('.lg'); $('body').removeclass('lg-on lg-from-hash'); if (_this.$outer) { _this.$outer.removeclass('lg-visible'); } $('.lg-backdrop').removeclass('in'); settimeout(function() { if (_this.$outer) { _this.$outer.remove(); } $('.lg-backdrop').remove(); if (!d) { _this.$el.trigger('oncloseafter.lg'); } }, _this.s.backdropduration + 50); }; $.fn.lightgallery = function(options) { return this.each(function() { if (!$.data(this, 'lightgallery')) { $.data(this, 'lightgallery', new plugin(this, options)); } else { try { $(this).data('lightgallery').init(); } catch (err) { console.error('lightgallery has not initiated properly'); } } }); }; $.fn.lightgallery.modules = {}; })(); }));