diff --git a/src/baguetteBox.js b/src/baguetteBox.js index 9f6946d5..b55694a1 100644 --- a/src/baguetteBox.js +++ b/src/baguetteBox.js @@ -62,8 +62,10 @@ var touch = {}; // If set to true ignore touch events because animation was already fired var touchFlag = false; - // Regex pattern to match image files - var regex = /.+\.(gif|jpe?g|png|webp)/i; + // Regex pattern to match image & video files + var regex = /.+\.(gif|jpe?g|png|webp|mp4|webm)/i; + // Pattern to match only videos + var videoRegex = /.+\.(mp4|webm)/i; // Object of all used galleries var data = {}; // Array containing temporary images DOM elements @@ -467,21 +469,36 @@ options.afterHide(); } }, 500); + + pauseAnyVideoPlaying(); + documentLastFocus.focus(); } + function pauseAnyVideoPlaying() { + [].forEach.call(imagesElements, function(imageElement) { + if (imageElement.getElementsByTagName('video').length > 0) { + imageElement.getElementsByTagName('video')[0].pause(); + } + }); + } + function loadImage(index, callback) { var imageContainer = imagesElements[index]; var galleryItem = currentGallery[index]; + var isVideo = false; + if (typeof imageContainer !== 'undefined') { + isVideo = videoRegex.test(galleryItem.imageElement.href); + } // Return if the index exceeds prepared images in the overlay // or if the current gallery has been changed / closed - if (imageContainer === undefined || galleryItem === undefined) { + if (typeof imageContainer === 'undefined' || typeof galleryItem === 'undefined') { return; } - // If image is already loaded run callback and return - if (imageContainer.getElementsByTagName('img')[0]) { + // If image is already loaded run callback and return OR If video is already loaded run callback and return + if (imageContainer.getElementsByTagName('img').length > 0 || imageContainer.getElementsByTagName('video').length > 0) { if (callback) { callback(); } @@ -490,11 +507,11 @@ // Get element reference, optional caption and source path var imageElement = galleryItem.imageElement; - var thumbnailElement = imageElement.getElementsByTagName('img')[0]; + var thumbnailElement = isVideo ? imageElement.getElementsByTagName('video')[0] : imageElement.getElementsByTagName('img')[0]; var imageCaption = typeof options.captions === 'function' ? options.captions.call(currentGallery, imageElement) : imageElement.getAttribute('data-caption') || imageElement.title; - var imageSrc = getImageSrc(imageElement); + var imageSrc = isVideo ? getVideoSrc(imageElement) : getImageSrc(imageElement); // Prepare figure element var figure = create('figure'); @@ -512,22 +529,43 @@ } imageContainer.appendChild(figure); - // Prepare gallery img element - var image = create('img'); - image.onload = function() { - // Remove loader element - var spinner = document.querySelector('#baguette-img-' + index + ' .baguetteBox-spinner'); - figure.removeChild(spinner); - if (!options.async && callback) { - callback(); + if (isVideo) { + // Prepare gallery video element + var video = create('video'); + //video.onload = function() { + video.addEventListener('loadeddata', function() { + //Remove loader element + var spinner = document.querySelector('#baguette-img-' + index + ' .baguetteBox-spinner'); + figure.removeChild(spinner); + if (!options.async && callback) { + callback(); + } + }); + var source = create('source'); + source.setAttribute('src', imageSrc); + video.appendChild(source); + if (options.titleTag && imageCaption) { + video.title = imageCaption; } - }; - image.setAttribute('src', imageSrc); - image.alt = thumbnailElement ? thumbnailElement.alt || '' : ''; - if (options.titleTag && imageCaption) { - image.title = imageCaption; + figure.appendChild(video); + } else { + // Prepare gallery img element + var image = create('img'); + image.onload = function() { + // Remove loader element + var spinner = document.querySelector('#baguette-img-' + index + ' .baguetteBox-spinner'); + figure.removeChild(spinner); + if (!options.async && callback) { + callback(); + } + }; + image.setAttribute('src', imageSrc); + image.alt = thumbnailElement ? thumbnailElement.alt || '' : ''; + if (options.titleTag && imageCaption) { + image.title = imageCaption; + } + figure.appendChild(image); } - figure.appendChild(image); // Run callback if (options.async && callback) { @@ -535,6 +573,35 @@ } } + // Get video source location, mostly used for responsive images + function getVideoSrc(image) { + // Set default image path from href + var result = image.getElementsByTagName('video')[0].getElementsByTagName('source')[0].src; + // If dataset is supported find the most suitable image + if (image.dataset) { + var srcs = []; + // Get all possible image versions depending on the resolution + for (var item in image.dataset) { + if (item.substring(0, 3) === 'at-' && !isNaN(item.substring(3))) { + srcs[item.replace('at-', '')] = image.dataset[item]; + } + } + // Sort resolutions ascending + var keys = Object.keys(srcs).sort(function(a, b) { + return parseInt(a, 10) < parseInt(b, 10) ? -1 : 1; + }); + // Get real screen resolution + var width = window.innerWidth * window.devicePixelRatio; + // Find the first image bigger than or equal to the current width + var i = 0; + while (i < keys.length - 1 && keys[i] < width) { + i++; + } + result = srcs[keys[i]] || result; + } + return result; + } + // Get image source location, mostly used for responsive images function getImageSrc(image) { // Set default image path from href @@ -609,6 +676,7 @@ } function updateOffset() { + pauseAnyVideoPlaying(); var offset = -currentIndex * 100 + '%'; if (options.animation === 'fadeIn') { slider.style.opacity = 0; @@ -625,6 +693,9 @@ slider.style.transform = slider.style.webkitTransform = 'translate3d(' + offset + ',0,0)' : slider.style.left = offset; } + if (imagesElements[currentIndex].getElementsByTagName('video').length > 0) { + imagesElements[currentIndex].getElementsByTagName('video')[0].play(); + } } // CSS 3D Transforms test diff --git a/src/baguetteBox.scss b/src/baguetteBox.scss index 5fa07604..b2bbae21 100644 --- a/src/baguetteBox.scss +++ b/src/baguetteBox.scss @@ -36,7 +36,7 @@ height: 100%; // Opera 12 image stretching fix } - img { + img, video { // IE8 fix display: inline-block; width: auto; @@ -48,6 +48,7 @@ box-shadow: 0 0 8px rgba(0,0,0,.6); } + figcaption { display: block; position: absolute;