diff --git a/js/lightbox.js b/js/lightbox.js index 5f4b8af2..54301fb3 100644 --- a/js/lightbox.js +++ b/js/lightbox.js @@ -7,405 +7,577 @@ * - Attribution requires leaving author name, author link, and the license info intact */ -(function() { - // Use local alias - var $ = jQuery; - - var LightboxOptions = (function() { - function LightboxOptions() { - this.fadeDuration = 500; - this.fitImagesInViewport = true; - this.resizeDuration = 700; - this.positionFromTop = 50; - this.showImageNumberLabel = true; - this.alwaysShowNavOnTouchDevices = false; - this.wrapAround = false; - } - - // Change to localize to non-english language - LightboxOptions.prototype.albumLabel = function(curImageNum, albumSize) { - return "Image " + curImageNum + " of " + albumSize; - }; - - return LightboxOptions; - })(); - - - var Lightbox = (function() { - function Lightbox(options) { - this.options = options; - this.album = []; - this.currentImageIndex = void 0; - this.init(); - } - - 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(); +(function() +{ + // Use local alias + var $ = jQuery; + + var LightboxOptions = (function() + { + function LightboxOptions() + { + this.fadeDuration = 200; + this.fitImagesInViewport = true; + this.resizeDuration = 300; + this.positionFromTop = 50; + this.showImageNumberLabel = true; + this.alwaysShowNavOnTouchDevices = true; + this.wrapAround = true; + this.twitterHandle = "MyTwitterHandle"; + this.facebookAppID = "MyFacebookAppID"; } - 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; - } + // Change to localize to non-english language + LightboxOptions.prototype.albumLabel = function(curImageNum, albumSize) + { + return "Image " + curImageNum + " of " + albumSize; + }; + + return LightboxOptions; + })(); + + + var Lightbox = (function() + { + function Lightbox(options) + { + this.options = options; + this.album = []; + this.currentImageIndex = void 0; + this.init(); } - } 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; + + 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; + var content = "
"; + content += "
"; + + $(content).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'); + this.$socialContainer = this.$lightbox.find('.lb-socialContainer'); + + // 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('class') === 'social') + { + return true; + } + + if ($(event.target.parentElement).attr('class') === 'lb-social') + { + return true; + } + + if ($(event.target).attr('id') === 'lightbox') + { + self.end(); + } + if ($(event.target).attr('class') === 'social') + { + return true; + } + + + 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; + }); + + this.$socialContainer.on('click', function(event) + { + return true; + }); + + }; + + // 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') + }); } - } - } - } - - // 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); - - 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, imageHeight, imageWidth, maxImageHeight, maxImageWidth, windowHeight, 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; - - // 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); + + // 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; + } + } } - } - } - 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($(window).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 it's details and begin preload neighboring images. - Lightbox.prototype.showImage = function() { - this.$lightbox.find('.lb-loader').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'); + 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; + } + } + } } - } - if (this.currentImageIndex < this.album.length - 1) { - this.$lightbox.find('.lb-next').show(); - if (alwaysShowNav) { - this.$lightbox.find('.lb-next').css('opacity', '1'); + + // 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); + + 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, imageHeight, imageWidth, maxImageHeight, maxImageWidth, windowHeight, 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; + + // 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($(window).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(); } - } - } - } - }; - - // 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){ - location.href = $(this).attr('href'); - }); - } - - if (this.album.length > 1 && this.options.showImageNumberLabel) { - this.$lightbox.find('.lb-number').text(this.options.albumLabel(this.currentImageIndex + 1, this.album.length)).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" - }); - }; - - return Lightbox; - - })(); - - $(function() { - var options = new LightboxOptions(); - var lightbox = new Lightbox(options); - }); + + if (oldWidth !== newWidth || oldHeight !== newHeight) + { + this.$outerContainer.animate( + { + width: newWidth, + height: newHeight + }, this.options.resizeDuration, 'swing', function() + { + postResize(); + }); + } + else + { + postResize(); + } + }; + + // Display the image and it's details and begin preload neighboring images. + Lightbox.prototype.showImage = function() + { + this.$lightbox.find('.lb-loader').hide(); + this.$lightbox.find('.lb-image').fadeIn('slow'); + + this.updateNav(); + this.updateDetails(); + this.updateSocial(); + 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) + { + location.href = $(this).attr('href'); + }); + } + + if (this.album.length > 1 && this.options.showImageNumberLabel) + { + this.$lightbox.find('.lb-number').text(this.options.albumLabel(this.currentImageIndex + 1, this.album.length)).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.updateSocial = function() + { + var self = this; + + var imageURL = encodeURIComponent(location.protocol + "//" + location.hostname + "/" + self.album[this.currentImageIndex].link); + var pageRef = encodeURIComponent(location.protocol + "//" + location.hostname); + + var description = ""; + if (typeof this.album[this.currentImageIndex].title !== 'undefined' && this.album[this.currentImageIndex].title !== "") + description = encodeURIComponent(self.album[this.currentImageIndex].title); + + var pinterestHref = "https://www.pinterest.com/pin/create/button/?" + + "url=" + pageRef + + "&media=" + imageURL + + "&description=" + description + " " + pageRef; + var socialPinterest = this.$lightbox.find('#lb-social-pinterest a'); + socialPinterest.attr('href', pinterestHref); + + var facebookHref = "https://www.facebook.com/dialog/feed?display=popup&app_id=" + this.options.facebookAppID + + "&redirect_uri=" + pageRef + + "&link=" + pageRef + + "&picture=" + imageURL + + "&caption=" + pageRef + + "&description=" + description; + var socialFacebook = this.$lightbox.find('#lb-social-facebook a'); + socialFacebook.attr('href', facebookHref); + + var twitterHref = "https://twitter.com/intent/tweet?" + + "&url=" + imageURL + + "&via=" + this.options.twitterHandle + + "&text=" + description; + var socialTwitter = this.$lightbox.find('#lb-social-twitter a'); + socialTwitter.attr('href', twitterHref); + }; + + + // 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" + }); + }; + + return Lightbox; + + })(); + + $(function() + { + var options = new LightboxOptions(); + var lightbox = new Lightbox(options); + }); }).call(this);