/*! * lightbox v2.8.2 * by lokesh dhakar * * more info: * http://lokeshdhakar.com/projects/lightbox2/ * * copyright 2007, 2015 lokesh dhakar * released under the mit license * https://github.com/lokesh/lightbox2/blob/master/license */ // uses node, amd or browser globals to create a module. (function (root, factory) { if (typeof define === 'function' && define.amd) { // amd. register as an anonymous module. define(['jquery'], factory); } 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 { // browser globals (root is window) root.lightbox = factory(root.jquery); } }(this, function ($) { function lightbox(options) { this.album = []; this.currentimageindex = void 0; this.init(); // options this.options = $.extend({}, this.constructor.defaults); this.option(options); } // descriptions of all options available on the demo site: // http://lokeshdhakar.com/projects/lightbox2/index.html#options lightbox.defaults = { albumlabel: 'image %1 of %2', alwaysshownavontouchdevices: false, fadeduration: 500, fitimagesinviewport: true, // maxwidth: 800, // maxheight: 600, positionfromtop: 50, resizeduration: 700, showimagenumberlabel: true, wraparound: false, disablescrolling: false }; lightbox.prototype.option = function(options) { $.extend(this.options, options); }; lightbox.prototype.imagecountlabel = function(currentimagenum, totalimages) { return this.options.albumlabel.replace(/%1/g, currentimagenum).replace(/%2/g, totalimages); }; lightbox.prototype.init = function() { this.enable(); this.build(); }; // loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes // that contain 'lightbox'. when these are clicked, start lightbox. lightbox.prototype.enable = function() { var self = this; $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) { self.start($(event.currenttarget)); return false; }); }; // build html for the lightbox and the overlay. // attach event handlers to the new dom elements. click click click lightbox.prototype.build = function() { var self = this; $('
').appendto($('body')); // cache jquery objects this.$lightbox = $('#lightbox'); this.$overlay = $('#lightboxoverlay'); this.$outercontainer = this.$lightbox.find('.lb-outercontainer'); this.$container = this.$lightbox.find('.lb-container'); // store css values for future lookup this.containertoppadding = parseint(this.$container.css('padding-top'), 10); this.containerrightpadding = parseint(this.$container.css('padding-right'), 10); this.containerbottompadding = parseint(this.$container.css('padding-bottom'), 10); this.containerleftpadding = parseint(this.$container.css('padding-left'), 10); // attach event handlers to the newly minted dom elements this.$overlay.hide().on('click', function() { self.end(); return false; }); this.$lightbox.hide().on('click', function(event) { if ($(event.target).attr('id') === 'lightbox') { self.end(); } return false; }); this.$outercontainer.on('click', function(event) { if ($(event.target).attr('id') === 'lightbox') { self.end(); } return false; }); this.$lightbox.find('.lb-prev').on('click', function() { if (self.currentimageindex === 0) { self.changeimage(self.album.length - 1); } else { self.changeimage(self.currentimageindex - 1); } return false; }); this.$lightbox.find('.lb-next').on('click', function() { if (self.currentimageindex === self.album.length - 1) { self.changeimage(0); } else { self.changeimage(self.currentimageindex + 1); } return false; }); this.$lightbox.find('.lb-loader, .lb-close').on('click', function() { self.end(); return false; }); }; // show overlay and lightbox. if the image is part of a set, add siblings to album array. lightbox.prototype.start = function($link) { var self = this; var $window = $(window); $window.on('resize', $.proxy(this.sizeoverlay, this)); $('select, object, embed').css({ visibility: 'hidden' }); this.sizeoverlay(); this.album = []; var imagenumber = 0; function addtoalbum($link) { self.album.push({ link: $link.attr('href'), title: $link.attr('data-title') || $link.attr('title') }); } // support both data-lightbox attribute and rel attribute implementations var datalightboxvalue = $link.attr('data-lightbox'); var $links; if (datalightboxvalue) { $links = $($link.prop('tagname') + '[data-lightbox="' + datalightboxvalue + '"]'); for (var i = 0; i < $links.length; i = ++i) { addtoalbum($($links[i])); if ($links[i] === $link[0]) { imagenumber = i; } } } else { if ($link.attr('rel') === 'lightbox') { // if image is not part of a set addtoalbum($link); } else { // if image is part of a set $links = $($link.prop('tagname') + '[rel="' + $link.attr('rel') + '"]'); for (var j = 0; j < $links.length; j = ++j) { addtoalbum($($links[j])); if ($links[j] === $link[0]) { imagenumber = j; } } } } // position lightbox var top = $window.scrolltop() + this.options.positionfromtop; var left = $window.scrollleft(); this.$lightbox.css({ top: top + 'px', left: left + 'px' }).fadein(this.options.fadeduration); // disable scrolling of the page while open if (this.options.disablescrolling) { $('body').addclass('lb-disable-scrolling'); } this.changeimage(imagenumber); }; // hide most ui elements in preparation for the animated resizing of the lightbox. lightbox.prototype.changeimage = function(imagenumber) { var self = this; this.disablekeyboardnav(); var $image = this.$lightbox.find('.lb-image'); this.$overlay.fadein(this.options.fadeduration); $('.lb-loader').fadein('slow'); this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-datacontainer, .lb-numbers, .lb-caption').hide(); this.$outercontainer.addclass('animating'); // when image to show is preloaded, we send the width and height to sizecontainer() var preloader = new image(); preloader.onload = function() { var $preloader; var imageheight; var imagewidth; var maximageheight; var maximagewidth; var windowheight; var windowwidth; $image.attr('src', self.album[imagenumber].link); $preloader = $(preloader); $image.width(preloader.width); $image.height(preloader.height); if (self.options.fitimagesinviewport) { // fit image inside the viewport. // take into account the border around the image and an additional 10px gutter on each side. windowwidth = $(window).width(); windowheight = $(window).height(); maximagewidth = windowwidth - self.containerleftpadding - self.containerrightpadding - 20; maximageheight = windowheight - self.containertoppadding - self.containerbottompadding - 120; // check if image size is larger then maxwidth|maxheight in settings if (self.options.maxwidth && self.options.maxwidth < maximagewidth) { maximagewidth = self.options.maxwidth; } if (self.options.maxheight && self.options.maxheight < maximagewidth) { maximageheight = self.options.maxheight; } // is there a fitting issue? if ((preloader.width > maximagewidth) || (preloader.height > maximageheight)) { if ((preloader.width / maximagewidth) > (preloader.height / maximageheight)) { imagewidth = maximagewidth; imageheight = parseint(preloader.height / (preloader.width / imagewidth), 10); $image.width(imagewidth); $image.height(imageheight); } else { imageheight = maximageheight; imagewidth = parseint(preloader.width / (preloader.height / imageheight), 10); $image.width(imagewidth); $image.height(imageheight); } } } self.sizecontainer($image.width(), $image.height()); }; preloader.src = this.album[imagenumber].link; this.currentimageindex = imagenumber; }; // stretch overlay to fit the viewport lightbox.prototype.sizeoverlay = function() { this.$overlay .width($(document).width()) .height($(document).height()); }; // animate the size of the lightbox to fit the image we are showing lightbox.prototype.sizecontainer = function(imagewidth, imageheight) { var self = this; var oldwidth = this.$outercontainer.outerwidth(); var oldheight = this.$outercontainer.outerheight(); var newwidth = imagewidth + this.containerleftpadding + this.containerrightpadding; var newheight = imageheight + this.containertoppadding + this.containerbottompadding; function postresize() { self.$lightbox.find('.lb-datacontainer').width(newwidth); self.$lightbox.find('.lb-prevlink').height(newheight); self.$lightbox.find('.lb-nextlink').height(newheight); self.showimage(); } if (oldwidth !== newwidth || oldheight !== newheight) { this.$outercontainer.animate({ width: newwidth, height: newheight }, this.options.resizeduration, 'swing', function() { postresize(); }); } else { postresize(); } }; // display the image and its details and begin preload neighboring images. lightbox.prototype.showimage = function() { this.$lightbox.find('.lb-loader').stop(true).hide(); this.$lightbox.find('.lb-image').fadein('slow'); this.updatenav(); this.updatedetails(); this.preloadneighboringimages(); this.enablekeyboardnav(); }; // display previous and next navigation if appropriate. lightbox.prototype.updatenav = function() { // check to see if the browser supports touch events. if so, we take the conservative approach // and assume that mouse hover events are not supported and always show prev/next navigation // arrows in image sets. var alwaysshownav = false; try { document.createevent('touchevent'); alwaysshownav = (this.options.alwaysshownavontouchdevices) ? true : false; } catch (e) {} this.$lightbox.find('.lb-nav').show(); if (this.album.length > 1) { if (this.options.wraparound) { if (alwaysshownav) { this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1'); } this.$lightbox.find('.lb-prev, .lb-next').show(); } else { if (this.currentimageindex > 0) { this.$lightbox.find('.lb-prev').show(); if (alwaysshownav) { this.$lightbox.find('.lb-prev').css('opacity', '1'); } } if (this.currentimageindex < this.album.length - 1) { this.$lightbox.find('.lb-next').show(); if (alwaysshownav) { this.$lightbox.find('.lb-next').css('opacity', '1'); } } } } }; // display caption, image number, and closing button. lightbox.prototype.updatedetails = function() { var self = this; // enable anchor clicks in the injected caption html. // thanks nate wright for the fix. @https://github.com/natewr if (typeof this.album[this.currentimageindex].title !== 'undefined' && this.album[this.currentimageindex].title !== '') { this.$lightbox.find('.lb-caption') .html(this.album[this.currentimageindex].title) .fadein('fast') .find('a').on('click', function(event) { if ($(this).attr('target') !== undefined) { window.open($(this).attr('href'), $(this).attr('target')); } else { location.href = $(this).attr('href'); } }); } if (this.album.length > 1 && this.options.showimagenumberlabel) { var labeltext = this.imagecountlabel(this.currentimageindex + 1, this.album.length); this.$lightbox.find('.lb-number').text(labeltext).fadein('fast'); } else { this.$lightbox.find('.lb-number').hide(); } this.$outercontainer.removeclass('animating'); this.$lightbox.find('.lb-datacontainer').fadein(this.options.resizeduration, function() { return self.sizeoverlay(); }); }; // preload previous and next images in set. lightbox.prototype.preloadneighboringimages = function() { if (this.album.length > this.currentimageindex + 1) { var preloadnext = new image(); preloadnext.src = this.album[this.currentimageindex + 1].link; } if (this.currentimageindex > 0) { var preloadprev = new image(); preloadprev.src = this.album[this.currentimageindex - 1].link; } }; lightbox.prototype.enablekeyboardnav = function() { $(document).on('keyup.keyboard', $.proxy(this.keyboardaction, this)); }; lightbox.prototype.disablekeyboardnav = function() { $(document).off('.keyboard'); }; lightbox.prototype.keyboardaction = function(event) { var keycode_esc = 27; var keycode_leftarrow = 37; var keycode_rightarrow = 39; var keycode = event.keycode; var key = string.fromcharcode(keycode).tolowercase(); if (keycode === keycode_esc || key.match(/x|o|c/)) { this.end(); } else if (key === 'p' || keycode === keycode_leftarrow) { if (this.currentimageindex !== 0) { this.changeimage(this.currentimageindex - 1); } else if (this.options.wraparound && this.album.length > 1) { this.changeimage(this.album.length - 1); } } else if (key === 'n' || keycode === keycode_rightarrow) { if (this.currentimageindex !== this.album.length - 1) { this.changeimage(this.currentimageindex + 1); } else if (this.options.wraparound && this.album.length > 1) { this.changeimage(0); } } }; // closing time. :-( lightbox.prototype.end = function() { this.disablekeyboardnav(); $(window).off('resize', this.sizeoverlay); this.$lightbox.fadeout(this.options.fadeduration); this.$overlay.fadeout(this.options.fadeduration); $('select, object, embed').css({ visibility: 'visible' }); if (this.options.disablescrolling) { $('body').removeclass('lb-disable-scrolling'); } }; return new lightbox(); }));