Commit 49b00707d39e20cd317ac0dbfd77ae60095c649b

Authored by Karnovsky A
1 parent e559e7db

ArtboxImage lightbox

common/config/main.php
... ... @@ -122,8 +122,8 @@ return [
122 122 ],
123 123 'large' => [
124 124 'resize' => [
125   - 'width' => 600,
126   - 'height' => 600,
  125 + 'width' => 1200,
  126 + 'height' => 800,
127 127 'master' => null
128 128 ],
129 129 ],
... ...
frontend/views/catalog/product.php
... ... @@ -2,6 +2,9 @@
2 2  
3 3 use common\components\artboximage\ArtboxImageHelper;
4 4  
  5 +$this->registerCssFile(Yii::getAlias('@web/css/lightbox.css'));
  6 +$this->registerJsFile(Yii::getAlias('@web/js/lightbox.js'));
  7 +
5 8 /** @var $this \yii\web\View */
6 9 /** @var $dataProvider \yii\data\ActiveDataProvider */
7 10 $this->title = $product->name;
... ... @@ -19,7 +22,9 @@ $this->params['breadcrumbs'][] = $product->name .' #'. $product->variant->sku;
19 22 <?php if (empty($product->image)) :?>
20 23 <img src="/images/no_photo_big.png" alt="<?= $product->name?>">
21 24 <?php else :?>
22   - <?= $product->image->imageUrl ? ArtboxImageHelper::getImage($product->image->imageUrl, 'product') : ''?>
  25 + <a href="<?= ArtboxImageHelper::getImageSrc($product->image->imageUrl, 'large')?>" data-lightbox="product-<?= $product->product_id?>" data-title="<?= $product->name?>">
  26 + <?= ArtboxImageHelper::getImage($product->image->imageUrl, 'product')?>
  27 + </a>
23 28 <?php endif?>
24 29  
25 30 <!--<span class="new">НОВИНКА</span>
... ...
frontend/web/css/lightbox.css 0 → 100644
  1 +/* Preload images */
  2 +body:after {
  3 + content: url(../images/lightbox/close.png) url(../images/lightbox/loading.gif) url(../images/lightbox/prev.png) url(../images/lightbox/next.png);
  4 + display: none;
  5 +}
  6 +
  7 +body.lb-disable-scrolling {
  8 + overflow: hidden;
  9 +}
  10 +
  11 +.lightboxOverlay {
  12 + position: absolute;
  13 + top: 0;
  14 + left: 0;
  15 + z-index: 9999;
  16 + background-color: black;
  17 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
  18 + opacity: 0.8;
  19 + display: none;
  20 +}
  21 +
  22 +.lightbox {
  23 + position: absolute;
  24 + left: 0;
  25 + width: 100%;
  26 + z-index: 10000;
  27 + text-align: center;
  28 + line-height: 0;
  29 + font-weight: normal;
  30 +}
  31 +
  32 +.lightbox .lb-image {
  33 + display: block;
  34 + height: auto;
  35 + max-width: inherit;
  36 + border-radius: 3px;
  37 +}
  38 +
  39 +.lightbox a img {
  40 + border: none;
  41 +}
  42 +
  43 +.lb-outerContainer {
  44 + position: relative;
  45 + background-color: white;
  46 + *zoom: 1;
  47 + width: 250px;
  48 + height: 250px;
  49 + margin: 0 auto;
  50 + border-radius: 4px;
  51 +}
  52 +
  53 +.lb-outerContainer:after {
  54 + content: "";
  55 + display: table;
  56 + clear: both;
  57 +}
  58 +
  59 +.lb-container {
  60 + padding: 4px;
  61 +}
  62 +
  63 +.lb-loader {
  64 + position: absolute;
  65 + top: 43%;
  66 + left: 0;
  67 + height: 25%;
  68 + width: 100%;
  69 + text-align: center;
  70 + line-height: 0;
  71 +}
  72 +
  73 +.lb-cancel {
  74 + display: block;
  75 + width: 32px;
  76 + height: 32px;
  77 + margin: 0 auto;
  78 + background: url(../images/lightbox/loading.gif) no-repeat;
  79 +}
  80 +
  81 +.lb-nav {
  82 + position: absolute;
  83 + top: 0;
  84 + left: 0;
  85 + height: 100%;
  86 + width: 100%;
  87 + z-index: 10;
  88 +}
  89 +
  90 +.lb-container > .nav {
  91 + left: 0;
  92 +}
  93 +
  94 +.lb-nav a {
  95 + outline: none;
  96 + background-image: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
  97 +}
  98 +
  99 +.lb-prev, .lb-next {
  100 + height: 100%;
  101 + cursor: pointer;
  102 + display: block;
  103 +}
  104 +
  105 +.lb-nav a.lb-prev {
  106 + width: 34%;
  107 + left: 0;
  108 + float: left;
  109 + background: url(../images/lightbox/prev.png) left 48% no-repeat;
  110 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
  111 + opacity: 0;
  112 + -webkit-transition: opacity 0.6s;
  113 + -moz-transition: opacity 0.6s;
  114 + -o-transition: opacity 0.6s;
  115 + transition: opacity 0.6s;
  116 +}
  117 +
  118 +.lb-nav a.lb-prev:hover {
  119 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
  120 + opacity: 1;
  121 +}
  122 +
  123 +.lb-nav a.lb-next {
  124 + width: 64%;
  125 + right: 0;
  126 + float: right;
  127 + background: url(../images/lightbox/next.png) right 48% no-repeat;
  128 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
  129 + opacity: 0;
  130 + -webkit-transition: opacity 0.6s;
  131 + -moz-transition: opacity 0.6s;
  132 + -o-transition: opacity 0.6s;
  133 + transition: opacity 0.6s;
  134 +}
  135 +
  136 +.lb-nav a.lb-next:hover {
  137 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
  138 + opacity: 1;
  139 +}
  140 +
  141 +.lb-dataContainer {
  142 + margin: 0 auto;
  143 + padding-top: 5px;
  144 + *zoom: 1;
  145 + width: 100%;
  146 + -moz-border-radius-bottomleft: 4px;
  147 + -webkit-border-bottom-left-radius: 4px;
  148 + border-bottom-left-radius: 4px;
  149 + -moz-border-radius-bottomright: 4px;
  150 + -webkit-border-bottom-right-radius: 4px;
  151 + border-bottom-right-radius: 4px;
  152 +}
  153 +
  154 +.lb-dataContainer:after {
  155 + content: "";
  156 + display: table;
  157 + clear: both;
  158 +}
  159 +
  160 +.lb-data {
  161 + padding: 0 4px;
  162 + color: #ccc;
  163 +}
  164 +
  165 +.lb-data .lb-details {
  166 + width: 85%;
  167 + float: left;
  168 + text-align: left;
  169 + line-height: 1.1em;
  170 +}
  171 +
  172 +.lb-data .lb-caption {
  173 + font-size: 13px;
  174 + font-weight: bold;
  175 + line-height: 1em;
  176 +}
  177 +
  178 +.lb-data .lb-number {
  179 + display: block;
  180 + clear: left;
  181 + padding-bottom: 1em;
  182 + font-size: 12px;
  183 + color: #999999;
  184 +}
  185 +
  186 +.lb-data .lb-close {
  187 + display: block;
  188 + float: right;
  189 + width: 30px;
  190 + height: 30px;
  191 + background: url(../images/lightbox/close.png) top right no-repeat;
  192 + text-align: right;
  193 + outline: none;
  194 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
  195 + opacity: 0.7;
  196 + -webkit-transition: opacity 0.2s;
  197 + -moz-transition: opacity 0.2s;
  198 + -o-transition: opacity 0.2s;
  199 + transition: opacity 0.2s;
  200 +}
  201 +
  202 +.lb-data .lb-close:hover {
  203 + cursor: pointer;
  204 + filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
  205 + opacity: 1;
  206 +}
... ...
frontend/web/js/lightbox.js 0 → 100644
  1 +/*!
  2 + * Lightbox v2.8.2
  3 + * by Lokesh Dhakar
  4 + *
  5 + * More info:
  6 + * http://lokeshdhakar.com/projects/lightbox2/
  7 + *
  8 + * Copyright 2007, 2015 Lokesh Dhakar
  9 + * Released under the MIT license
  10 + * https://github.com/lokesh/lightbox2/blob/master/LICENSE
  11 + */
  12 +
  13 +// Uses Node, AMD or browser globals to create a module.
  14 +(function (root, factory) {
  15 + if (typeof define === 'function' && define.amd) {
  16 + // AMD. Register as an anonymous module.
  17 + define(['jquery'], factory);
  18 + } else if (typeof exports === 'object') {
  19 + // Node. Does not work with strict CommonJS, but
  20 + // only CommonJS-like environments that support module.exports,
  21 + // like Node.
  22 + module.exports = factory(require('jquery'));
  23 + } else {
  24 + // Browser globals (root is window)
  25 + root.lightbox = factory(root.jQuery);
  26 + }
  27 +}(this, function ($) {
  28 +
  29 + function Lightbox(options) {
  30 + this.album = [];
  31 + this.currentImageIndex = void 0;
  32 + this.init();
  33 +
  34 + // options
  35 + this.options = $.extend({}, this.constructor.defaults);
  36 + this.option(options);
  37 + }
  38 +
  39 + // Descriptions of all options available on the demo site:
  40 + // http://lokeshdhakar.com/projects/lightbox2/index.html#options
  41 + Lightbox.defaults = {
  42 + albumLabel: 'Image %1 of %2',
  43 + alwaysShowNavOnTouchDevices: false,
  44 + fadeDuration: 500,
  45 + fitImagesInViewport: true,
  46 + // maxWidth: 800,
  47 + // maxHeight: 600,
  48 + positionFromTop: 50,
  49 + resizeDuration: 700,
  50 + showImageNumberLabel: true,
  51 + wrapAround: false,
  52 + disableScrolling: false
  53 + };
  54 +
  55 + Lightbox.prototype.option = function(options) {
  56 + $.extend(this.options, options);
  57 + };
  58 +
  59 + Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) {
  60 + return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages);
  61 + };
  62 +
  63 + Lightbox.prototype.init = function() {
  64 + this.enable();
  65 + this.build();
  66 + };
  67 +
  68 + // Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes
  69 + // that contain 'lightbox'. When these are clicked, start lightbox.
  70 + Lightbox.prototype.enable = function() {
  71 + var self = this;
  72 + $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) {
  73 + self.start($(event.currentTarget));
  74 + return false;
  75 + });
  76 + };
  77 +
  78 + // Build html for the lightbox and the overlay.
  79 + // Attach event handlers to the new DOM elements. click click click
  80 + Lightbox.prototype.build = function() {
  81 + var self = this;
  82 + $('<div id="lightboxOverlay" class="lightboxOverlay"></div><div id="lightbox" class="lightbox"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" /><div class="lb-nav"><a class="lb-prev" href="" ></a><a class="lb-next" 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'));
  83 +
  84 + // Cache jQuery objects
  85 + this.$lightbox = $('#lightbox');
  86 + this.$overlay = $('#lightboxOverlay');
  87 + this.$outerContainer = this.$lightbox.find('.lb-outerContainer');
  88 + this.$container = this.$lightbox.find('.lb-container');
  89 +
  90 + // Store css values for future lookup
  91 + this.containerTopPadding = parseInt(this.$container.css('padding-top'), 10);
  92 + this.containerRightPadding = parseInt(this.$container.css('padding-right'), 10);
  93 + this.containerBottomPadding = parseInt(this.$container.css('padding-bottom'), 10);
  94 + this.containerLeftPadding = parseInt(this.$container.css('padding-left'), 10);
  95 +
  96 + // Attach event handlers to the newly minted DOM elements
  97 + this.$overlay.hide().on('click', function() {
  98 + self.end();
  99 + return false;
  100 + });
  101 +
  102 + this.$lightbox.hide().on('click', function(event) {
  103 + if ($(event.target).attr('id') === 'lightbox') {
  104 + self.end();
  105 + }
  106 + return false;
  107 + });
  108 +
  109 + this.$outerContainer.on('click', function(event) {
  110 + if ($(event.target).attr('id') === 'lightbox') {
  111 + self.end();
  112 + }
  113 + return false;
  114 + });
  115 +
  116 + this.$lightbox.find('.lb-prev').on('click', function() {
  117 + if (self.currentImageIndex === 0) {
  118 + self.changeImage(self.album.length - 1);
  119 + } else {
  120 + self.changeImage(self.currentImageIndex - 1);
  121 + }
  122 + return false;
  123 + });
  124 +
  125 + this.$lightbox.find('.lb-next').on('click', function() {
  126 + if (self.currentImageIndex === self.album.length - 1) {
  127 + self.changeImage(0);
  128 + } else {
  129 + self.changeImage(self.currentImageIndex + 1);
  130 + }
  131 + return false;
  132 + });
  133 +
  134 + this.$lightbox.find('.lb-loader, .lb-close').on('click', function() {
  135 + self.end();
  136 + return false;
  137 + });
  138 + };
  139 +
  140 + // Show overlay and lightbox. If the image is part of a set, add siblings to album array.
  141 + Lightbox.prototype.start = function($link) {
  142 + var self = this;
  143 + var $window = $(window);
  144 +
  145 + $window.on('resize', $.proxy(this.sizeOverlay, this));
  146 +
  147 + $('select, object, embed').css({
  148 + visibility: 'hidden'
  149 + });
  150 +
  151 + this.sizeOverlay();
  152 +
  153 + this.album = [];
  154 + var imageNumber = 0;
  155 +
  156 + function addToAlbum($link) {
  157 + self.album.push({
  158 + link: $link.attr('href'),
  159 + title: $link.attr('data-title') || $link.attr('title')
  160 + });
  161 + }
  162 +
  163 + // Support both data-lightbox attribute and rel attribute implementations
  164 + var dataLightboxValue = $link.attr('data-lightbox');
  165 + var $links;
  166 +
  167 + if (dataLightboxValue) {
  168 + $links = $($link.prop('tagName') + '[data-lightbox="' + dataLightboxValue + '"]');
  169 + for (var i = 0; i < $links.length; i = ++i) {
  170 + addToAlbum($($links[i]));
  171 + if ($links[i] === $link[0]) {
  172 + imageNumber = i;
  173 + }
  174 + }
  175 + } else {
  176 + if ($link.attr('rel') === 'lightbox') {
  177 + // If image is not part of a set
  178 + addToAlbum($link);
  179 + } else {
  180 + // If image is part of a set
  181 + $links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]');
  182 + for (var j = 0; j < $links.length; j = ++j) {
  183 + addToAlbum($($links[j]));
  184 + if ($links[j] === $link[0]) {
  185 + imageNumber = j;
  186 + }
  187 + }
  188 + }
  189 + }
  190 +
  191 + // Position Lightbox
  192 + var top = $window.scrollTop() + this.options.positionFromTop;
  193 + var left = $window.scrollLeft();
  194 + this.$lightbox.css({
  195 + top: top + 'px',
  196 + left: left + 'px'
  197 + }).fadeIn(this.options.fadeDuration);
  198 +
  199 + // Disable scrolling of the page while open
  200 + if (this.options.disableScrolling) {
  201 + $('body').addClass('lb-disable-scrolling');
  202 + }
  203 +
  204 + this.changeImage(imageNumber);
  205 + };
  206 +
  207 + // Hide most UI elements in preparation for the animated resizing of the lightbox.
  208 + Lightbox.prototype.changeImage = function(imageNumber) {
  209 + var self = this;
  210 +
  211 + this.disableKeyboardNav();
  212 + var $image = this.$lightbox.find('.lb-image');
  213 +
  214 + this.$overlay.fadeIn(this.options.fadeDuration);
  215 +
  216 + $('.lb-loader').fadeIn('slow');
  217 + this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide();
  218 +
  219 + this.$outerContainer.addClass('animating');
  220 +
  221 + // When image to show is preloaded, we send the width and height to sizeContainer()
  222 + var preloader = new Image();
  223 + preloader.onload = function() {
  224 + var $preloader;
  225 + var imageHeight;
  226 + var imageWidth;
  227 + var maxImageHeight;
  228 + var maxImageWidth;
  229 + var windowHeight;
  230 + var windowWidth;
  231 +
  232 + $image.attr('src', self.album[imageNumber].link);
  233 +
  234 + $preloader = $(preloader);
  235 +
  236 + $image.width(preloader.width);
  237 + $image.height(preloader.height);
  238 +
  239 + if (self.options.fitImagesInViewport) {
  240 + // Fit image inside the viewport.
  241 + // Take into account the border around the image and an additional 10px gutter on each side.
  242 +
  243 + windowWidth = $(window).width();
  244 + windowHeight = $(window).height();
  245 + maxImageWidth = windowWidth - self.containerLeftPadding - self.containerRightPadding - 20;
  246 + maxImageHeight = windowHeight - self.containerTopPadding - self.containerBottomPadding - 120;
  247 +
  248 + // Check if image size is larger then maxWidth|maxHeight in settings
  249 + if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) {
  250 + maxImageWidth = self.options.maxWidth;
  251 + }
  252 + if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) {
  253 + maxImageHeight = self.options.maxHeight;
  254 + }
  255 +
  256 + // Is there a fitting issue?
  257 + if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) {
  258 + if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) {
  259 + imageWidth = maxImageWidth;
  260 + imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10);
  261 + $image.width(imageWidth);
  262 + $image.height(imageHeight);
  263 + } else {
  264 + imageHeight = maxImageHeight;
  265 + imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10);
  266 + $image.width(imageWidth);
  267 + $image.height(imageHeight);
  268 + }
  269 + }
  270 + }
  271 + self.sizeContainer($image.width(), $image.height());
  272 + };
  273 +
  274 + preloader.src = this.album[imageNumber].link;
  275 + this.currentImageIndex = imageNumber;
  276 + };
  277 +
  278 + // Stretch overlay to fit the viewport
  279 + Lightbox.prototype.sizeOverlay = function() {
  280 + this.$overlay
  281 + .width($(document).width())
  282 + .height($(document).height());
  283 + };
  284 +
  285 + // Animate the size of the lightbox to fit the image we are showing
  286 + Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {
  287 + var self = this;
  288 +
  289 + var oldWidth = this.$outerContainer.outerWidth();
  290 + var oldHeight = this.$outerContainer.outerHeight();
  291 + var newWidth = imageWidth + this.containerLeftPadding + this.containerRightPadding;
  292 + var newHeight = imageHeight + this.containerTopPadding + this.containerBottomPadding;
  293 +
  294 + function postResize() {
  295 + self.$lightbox.find('.lb-dataContainer').width(newWidth);
  296 + self.$lightbox.find('.lb-prevLink').height(newHeight);
  297 + self.$lightbox.find('.lb-nextLink').height(newHeight);
  298 + self.showImage();
  299 + }
  300 +
  301 + if (oldWidth !== newWidth || oldHeight !== newHeight) {
  302 + this.$outerContainer.animate({
  303 + width: newWidth,
  304 + height: newHeight
  305 + }, this.options.resizeDuration, 'swing', function() {
  306 + postResize();
  307 + });
  308 + } else {
  309 + postResize();
  310 + }
  311 + };
  312 +
  313 + // Display the image and its details and begin preload neighboring images.
  314 + Lightbox.prototype.showImage = function() {
  315 + this.$lightbox.find('.lb-loader').stop(true).hide();
  316 + this.$lightbox.find('.lb-image').fadeIn('slow');
  317 +
  318 + this.updateNav();
  319 + this.updateDetails();
  320 + this.preloadNeighboringImages();
  321 + this.enableKeyboardNav();
  322 + };
  323 +
  324 + // Display previous and next navigation if appropriate.
  325 + Lightbox.prototype.updateNav = function() {
  326 + // Check to see if the browser supports touch events. If so, we take the conservative approach
  327 + // and assume that mouse hover events are not supported and always show prev/next navigation
  328 + // arrows in image sets.
  329 + var alwaysShowNav = false;
  330 + try {
  331 + document.createEvent('TouchEvent');
  332 + alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false;
  333 + } catch (e) {}
  334 +
  335 + this.$lightbox.find('.lb-nav').show();
  336 +
  337 + if (this.album.length > 1) {
  338 + if (this.options.wrapAround) {
  339 + if (alwaysShowNav) {
  340 + this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1');
  341 + }
  342 + this.$lightbox.find('.lb-prev, .lb-next').show();
  343 + } else {
  344 + if (this.currentImageIndex > 0) {
  345 + this.$lightbox.find('.lb-prev').show();
  346 + if (alwaysShowNav) {
  347 + this.$lightbox.find('.lb-prev').css('opacity', '1');
  348 + }
  349 + }
  350 + if (this.currentImageIndex < this.album.length - 1) {
  351 + this.$lightbox.find('.lb-next').show();
  352 + if (alwaysShowNav) {
  353 + this.$lightbox.find('.lb-next').css('opacity', '1');
  354 + }
  355 + }
  356 + }
  357 + }
  358 + };
  359 +
  360 + // Display caption, image number, and closing button.
  361 + Lightbox.prototype.updateDetails = function() {
  362 + var self = this;
  363 +
  364 + // Enable anchor clicks in the injected caption html.
  365 + // Thanks Nate Wright for the fix. @https://github.com/NateWr
  366 + if (typeof this.album[this.currentImageIndex].title !== 'undefined' &&
  367 + this.album[this.currentImageIndex].title !== '') {
  368 + this.$lightbox.find('.lb-caption')
  369 + .html(this.album[this.currentImageIndex].title)
  370 + .fadeIn('fast')
  371 + .find('a').on('click', function(event) {
  372 + if ($(this).attr('target') !== undefined) {
  373 + window.open($(this).attr('href'), $(this).attr('target'));
  374 + } else {
  375 + location.href = $(this).attr('href');
  376 + }
  377 + });
  378 + }
  379 +
  380 + if (this.album.length > 1 && this.options.showImageNumberLabel) {
  381 + var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);
  382 + this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast');
  383 + } else {
  384 + this.$lightbox.find('.lb-number').hide();
  385 + }
  386 +
  387 + this.$outerContainer.removeClass('animating');
  388 +
  389 + this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() {
  390 + return self.sizeOverlay();
  391 + });
  392 + };
  393 +
  394 + // Preload previous and next images in set.
  395 + Lightbox.prototype.preloadNeighboringImages = function() {
  396 + if (this.album.length > this.currentImageIndex + 1) {
  397 + var preloadNext = new Image();
  398 + preloadNext.src = this.album[this.currentImageIndex + 1].link;
  399 + }
  400 + if (this.currentImageIndex > 0) {
  401 + var preloadPrev = new Image();
  402 + preloadPrev.src = this.album[this.currentImageIndex - 1].link;
  403 + }
  404 + };
  405 +
  406 + Lightbox.prototype.enableKeyboardNav = function() {
  407 + $(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this));
  408 + };
  409 +
  410 + Lightbox.prototype.disableKeyboardNav = function() {
  411 + $(document).off('.keyboard');
  412 + };
  413 +
  414 + Lightbox.prototype.keyboardAction = function(event) {
  415 + var KEYCODE_ESC = 27;
  416 + var KEYCODE_LEFTARROW = 37;
  417 + var KEYCODE_RIGHTARROW = 39;
  418 +
  419 + var keycode = event.keyCode;
  420 + var key = String.fromCharCode(keycode).toLowerCase();
  421 + if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) {
  422 + this.end();
  423 + } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) {
  424 + if (this.currentImageIndex !== 0) {
  425 + this.changeImage(this.currentImageIndex - 1);
  426 + } else if (this.options.wrapAround && this.album.length > 1) {
  427 + this.changeImage(this.album.length - 1);
  428 + }
  429 + } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) {
  430 + if (this.currentImageIndex !== this.album.length - 1) {
  431 + this.changeImage(this.currentImageIndex + 1);
  432 + } else if (this.options.wrapAround && this.album.length > 1) {
  433 + this.changeImage(0);
  434 + }
  435 + }
  436 + };
  437 +
  438 + // Closing time. :-(
  439 + Lightbox.prototype.end = function() {
  440 + this.disableKeyboardNav();
  441 + $(window).off('resize', this.sizeOverlay);
  442 + this.$lightbox.fadeOut(this.options.fadeDuration);
  443 + this.$overlay.fadeOut(this.options.fadeDuration);
  444 + $('select, object, embed').css({
  445 + visibility: 'visible'
  446 + });
  447 + if (this.options.disableScrolling) {
  448 + $('body').removeClass('lb-disable-scrolling');
  449 + }
  450 + };
  451 +
  452 + return new Lightbox();
  453 +}));
... ...