diff --git a/package.json b/package.json index c89aa01..2bb0a62 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lightbox", - "version": "4.0.1", + "version": "4.1.0", "description": "Image lightbox", "main": "src", "scripts": { diff --git a/sass/lightbox.scss b/sass/lightbox.scss index 536a0cc..a82f255 100644 --- a/sass/lightbox.scss +++ b/sass/lightbox.scss @@ -6,15 +6,6 @@ $button-padding: 40px; #{$property}: calc(#{$params}) #{$important}; } -.lightbox-active { - overflow: hidden; -} - -.lightbox-loading, -.lightbox-loading * { - cursor: wait; -} - .lightbox-link { cursor: pointer; } @@ -27,16 +18,17 @@ $button-padding: 40px; } #lightbox-blocking { - height: 100%; + bottom: 0; left: 0; position: fixed; + right: 0; top: 0; - width: 100%; z-index: 1001; } // #lightbox-blocking #lightbox-wrap { + display: flex; height: 100%; left: 0; position: fixed; @@ -50,7 +42,7 @@ $button-padding: 40px; visibility: visible; } - img { + .lightbox-contents { @extend %user-select-none; cursor: zoom-out; @@ -58,7 +50,6 @@ $button-padding: 40px; max-height: 100%; max-width: 100%; position: relative; - width: auto; } &.single { @@ -75,19 +66,21 @@ $button-padding: 40px; } // &.single - &.extras-hidden #lightbox-img-wrap > :not(img) { + &.extras-hidden #lightbox-img-wrap > :not(.lightbox-contents) { opacity: 0; transition: 1s; } + img { + max-height: 100vh; + max-width: 100vw; + } + } // #lightbox-wrap #lightbox-inner-wrap { - height: 90%; // height must be set explicitly for img sizing margin: auto; - max-height: 90%; - max-width: 90%; position: relative; .control { @@ -173,9 +166,3 @@ $button-padding: 40px; } // .close } // #lightbox-inner-wrap - -#lightbox-img-wrap { - display: inline-block; - height: 100%; - position: relative; -} diff --git a/src/Lightbox.js b/src/Lightbox.js index 8d8a3dc..bc87226 100644 --- a/src/Lightbox.js +++ b/src/Lightbox.js @@ -33,7 +33,9 @@ export default class Lightbox { this.$context.find(config.imageSelector).each((i, el) => { const $img = $(el); $img.data('img-id', i).addClass('lightbox-link'); - this.images[i] = new LightboxImage(this, $img.data(config.imageSrcDataAttr), i); + this.images[i] = new LightboxImage(this, + $img.data('picture') || $img.data(config.imageSrcDataAttr), + i); }); const self = this; @@ -58,7 +60,7 @@ export default class Lightbox { this.$activeImage.remove(); this.$activeImage = null; this.$body.find(this.$blocking).remove(); - this.$body.removeClass('lightbox-active'); + $('html').removeClass('lightbox-active'); this.activeImageId = false; }); } diff --git a/src/LightboxImage.js b/src/LightboxImage.js index 69cc0e1..b7359b1 100644 --- a/src/LightboxImage.js +++ b/src/LightboxImage.js @@ -23,7 +23,7 @@ const LIGHTBOX_TEMPLATE = ` - + @@ -38,10 +38,7 @@ export default class LightboxImage { this.$view = $(LIGHTBOX_TEMPLATE).hide(); } - loadImage($loadedImg) { - let top; - - this.lightbox.$body.removeClass('lightbox-loading'); + appendWrap() { this.lightbox.$body.append(this.$view); this.$view.fadeIn(this.lightbox.fadeTimeInMs); @@ -58,14 +55,8 @@ export default class LightboxImage { } this.lightbox.activeImageId = this.id; - if ($loadedImg.height()) { - top = ($(window).height() - $loadedImg.height()) / 2; - this.$view.addClass('shown'); - this.$view.css('top', top); - this.$view.find('.js-img-wrap').height($loadedImg.height()); - } - this._setCloseIconColor(this.$view, this.lightbox.bgColor); + this.$view.addClass('shown'); } showExtras() { @@ -81,10 +72,12 @@ export default class LightboxImage { return; } - const $img = this.$view.find('img'); + const $contents = this.$view.find('.js-contents'); + const isSrcPicture = (typeof this.src === 'object'); + this.lightbox.isLoading = true; - this.lightbox.$body.addClass('lightbox-active lightbox-loading'); + $('html').addClass('lightbox-active'); if (this.lightbox.isSingle) { this.$view.addClass('single'); @@ -99,17 +92,25 @@ export default class LightboxImage { this.lightbox.$body.append(this.lightbox.$blocking); } - $img.attr('src', this.src); - // because IOS doesnt fire load for cached images, - // but luckily this will be true immediately if that is the case - if ($img[0].complete) { - this.loadImage($img); + $contents.empty(); + + if (isSrcPicture) { + const $picture = $(''); + + this.src.sources.forEach(({ srcset, media_query: media }) => { + $('', { srcset, media }).appendTo($picture); + }); + + const { src, alt } = this.src.img; + $('', { src, alt }).appendTo($picture); + + $picture.appendTo($contents); } else { - $img.on('load', () => { - this.loadImage($img); - }); + $('', { src: this.src }).appendTo($contents); } + + this.appendWrap(); } _setCloseIconColor($context, bgColor) { diff --git a/test/specs/index.js b/test/specs/index.js index 3a9bbc9..5b0c3fd 100644 --- a/test/specs/index.js +++ b/test/specs/index.js @@ -74,4 +74,17 @@ describe('lightbox', function() { }, 15); }); }); + + it('should support data-picture in the lightbox image', function(done) { + affix(`.picture-lightbox[data-picture="${JSON.stringify({ + sources: [{ srcset: imagePath(1), media_query: '(min-width: 1px)' }], + img: { src: imagePath(1) } + }).replace(/"/g, '"')}"] img[style="width:50px;height:50px"]`); + lightbox.init({ imageSelector: '.picture-lightbox' }); + $('.picture-lightbox').first().click(); + tempWait(() => { + expect($('img[src$="1.png"]')).toBeVisible(); + done(); + }); + }); });