(function (root, factory) { if (typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if (typeof exports === 'object') { module.exports = factory(require('jquery')); } else { root.lightbox = factory(root.jQuery); } }(this, function ($) {
function Lightbox(options) { this.album = []; this.currentImageIndex = void 0; this.init();
this.options = $.extend({}, this.constructor.defaults); this.option(options); }
Lightbox.defaults = { albumLabel: 'Image %1 of %2', alwaysShowNavOnTouchDevices: false, fadeDuration: 600, fitImagesInViewport: true, imageFadeDuration: 600, positionFromTop: 50, resizeDuration: 700, showImageNumberLabel: true, wrapAround: false, disableScrolling: false,
sanitizeTitle: 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 () { var self = this; $(document).ready(function () { self.enable(); self.build(); }); };
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; }); };
Lightbox.prototype.build = function () { if ($('#lightbox').length > 0) { return; }
var self = this;
$('<div id="lightboxOverlay" tabindex="-1" class="lightboxOverlay"></div><div id="lightbox" tabindex="-1" class="lightbox"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt=""/><div class="lb-nav"><a class="lb-prev" aria-label="Previous image" href="" ></a><a class="lb-next" aria-label="Next image" href="" ></a></div><div class="lb-loader"><a class="lb-cancel"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a class="lb-close"></a></div></div></div></div>').appendTo($('body'));
this.$lightbox = $('#lightbox'); this.$overlay = $('#lightboxOverlay'); this.$outerContainer = this.$lightbox.find('.lb-outerContainer'); this.$container = this.$lightbox.find('.lb-container'); this.$image = this.$lightbox.find('.lb-image'); this.$nav = this.$lightbox.find('.lb-nav');
this.containerPadding = { top: parseInt(this.$container.css('padding-top'), 10), right: parseInt(this.$container.css('padding-right'), 10), bottom: parseInt(this.$container.css('padding-bottom'), 10), left: parseInt(this.$container.css('padding-left'), 10) };
this.imageBorderWidth = { top: parseInt(this.$image.css('border-top-width'), 10), right: parseInt(this.$image.css('border-right-width'), 10), bottom: parseInt(this.$image.css('border-bottom-width'), 10), left: parseInt(this.$image.css('border-left-width'), 10) };
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(); } });
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.$nav.on('mousedown', function (event) { if (event.which === 3) { self.$nav.css('pointer-events', 'none');
self.$lightbox.one('contextmenu', function () { setTimeout(function () { this.$nav.css('pointer-events', 'auto'); }.bind(self), 0); }); } });
this.$lightbox.find('.lb-loader, .lb-close').on('click', function () { self.end(); return false; }); };
Lightbox.prototype.start = function ($link) { var self = this; var $window = $(window);
$window.on('resize', $.proxy(this.sizeOverlay, this));
this.sizeOverlay();
this.album = []; var imageNumber = 0;
function addToAlbum($link) { self.album.push({ alt: $link.attr('data-alt'), link: $link.attr('href'), title: $link.attr('data-title') || $link.attr('title') }); }
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') { addToAlbum($link); } else { $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; } } } }
var top = $window.scrollTop() + this.options.positionFromTop; var left = $window.scrollLeft(); this.$lightbox.css({ top: top + 'px', left: left + 'px' }).fadeIn(this.options.fadeDuration);
if (this.options.disableScrolling) { $('body').addClass('lb-disable-scrolling'); }
this.changeImage(imageNumber); };
Lightbox.prototype.changeImage = function (imageNumber) { var self = this; var filename = this.album[imageNumber].link; var filetype = filename.split('.').slice(-1)[0]; var $image = this.$lightbox.find('.lb-image');
this.disableKeyboardNav();
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');
var preloader = new Image(); preloader.onload = function () { var $preloader; var imageHeight; var imageWidth; var maxImageHeight; var maxImageWidth; var windowHeight; var windowWidth;
$image.attr({ 'alt': self.album[imageNumber].alt, 'src': filename });
$preloader = $(preloader);
$image.width(preloader.width); $image.height(preloader.height); windowWidth = $(window).width(); windowHeight = $(window).height();
maxImageWidth = windowWidth - self.containerPadding.left - self.containerPadding.right - self.imageBorderWidth.left - self.imageBorderWidth.right - 20; maxImageHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.imageBorderWidth.top - self.imageBorderWidth.bottom - self.options.positionFromTop - 70;
if (filetype === 'svg') { $image.width(maxImageWidth); $image.height(maxImageHeight); }
if (self.options.fitImagesInViewport) {
if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) { maxImageWidth = self.options.maxWidth; } if (self.options.maxHeight && self.options.maxHeight < maxImageHeight) { maxImageHeight = self.options.maxHeight; }
} else { maxImageWidth = self.options.maxWidth || preloader.width || maxImageWidth; maxImageHeight = self.options.maxHeight || preloader.height || maxImageHeight; }
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; };
Lightbox.prototype.sizeOverlay = function () { var self = this;
setTimeout(function () { self.$overlay .width($(document).width()) .height($(document).height());
}, 0); };
Lightbox.prototype.sizeContainer = function (imageWidth, imageHeight) { var self = this;
var oldWidth = this.$outerContainer.outerWidth(); var oldHeight = this.$outerContainer.outerHeight(); var newWidth = imageWidth + this.containerPadding.left + this.containerPadding.right + this.imageBorderWidth.left + this.imageBorderWidth.right; var newHeight = imageHeight + this.containerPadding.top + this.containerPadding.bottom + this.imageBorderWidth.top + this.imageBorderWidth.bottom;
function postResize() { self.$lightbox.find('.lb-dataContainer').width(newWidth); self.$lightbox.find('.lb-prevLink').height(newHeight); self.$lightbox.find('.lb-nextLink').height(newHeight);
self.$overlay.focus();
self.showImage(); }
if (oldWidth !== newWidth || oldHeight !== newHeight) { this.$outerContainer.animate({ width: newWidth, height: newHeight }, this.options.resizeDuration, 'swing', function () { postResize(); }); } else { postResize(); } };
Lightbox.prototype.showImage = function () { this.$lightbox.find('.lb-loader').stop(true).hide(); this.$lightbox.find('.lb-image').fadeIn(this.options.imageFadeDuration);
this.updateNav(); this.updateDetails(); this.preloadNeighboringImages(); this.enableKeyboardNav(); };
Lightbox.prototype.updateNav = function () { 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'); } } } } };
Lightbox.prototype.updateDetails = function () { var self = this;
if (typeof this.album[this.currentImageIndex].title !== 'undefined' && this.album[this.currentImageIndex].title !== '') { var $caption = this.$lightbox.find('.lb-caption'); if (this.options.sanitizeTitle) { $caption.text(this.album[this.currentImageIndex].title); } else { $caption.html(this.album[this.currentImageIndex].title); } $caption.fadeIn('fast'); }
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(); }); };
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 () { this.$lightbox.on('keyup.keyboard', $.proxy(this.keyboardAction, this)); this.$overlay.on('keyup.keyboard', $.proxy(this.keyboardAction, this)); };
Lightbox.prototype.disableKeyboardNav = function () { this.$lightbox.off('.keyboard'); this.$overlay.off('.keyboard'); };
Lightbox.prototype.keyboardAction = function (event) { var KEYCODE_ESC = 27; var KEYCODE_LEFTARROW = 37; var KEYCODE_RIGHTARROW = 39;
var keycode = event.keyCode; if (keycode === KEYCODE_ESC) { event.stopPropagation(); this.end(); } else if (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 (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); } } };
Lightbox.prototype.end = function () { this.disableKeyboardNav(); $(window).off('resize', this.sizeOverlay); this.$lightbox.fadeOut(this.options.fadeDuration); this.$overlay.fadeOut(this.options.fadeDuration);
if (this.options.disableScrolling) { $('body').removeClass('lb-disable-scrolling'); } };
return new Lightbox(); }));
|