(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: "", alwaysShowNavOnTouchDevices: false, fadeDuration: 100, fitImagesInViewport: true, imageFadeDuration: 0, // maxWidth: 800, // maxHeight: 600, positionFromTop: 50, resizeDuration: 00, 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; $( '
' ).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); } // Fit image inside the viewport. if (self.options.fitImagesInViewport) { // 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 < 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(); });