web-assets/venobox/v2/dist/venobox.js
2023-12-30 22:34:25 +01:00

1014 lines
34 KiB
JavaScript

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.VenoBox = factory());
}(this, (function () { 'use strict';
/**
* VenoBox 2.0.4
* Copyright 2013-2021 Nicola Franchini
* @license: https://github.com/nicolafranchini/VenoBox/blob/master/LICENSE
*/
let backdrop, blocknum, blockshare, blocktitle, core, container, content, current_item, current_index, diffX, diffY, endY, elPreloader, elPreloaderInner;
let gallIndex, images, infinigall, items, navigationDisabled, newcontent, numeratio, nextok, prevok, overlay;
let set_maxWidth, set_overlayColor, set_ratio, set_autoplay, set_href, set_customclass, startY, thenext, theprev, thisborder, thisgall, title, throttle;
const svgOpen = '<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor">';
const svgClose = '</svg>';
const downloadIcon = svgOpen + '<path d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/><path d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>' + svgClose;
const shareIcon = svgOpen + '<path fill-rule="evenodd" d="M3.5 6a.5.5 0 0 0-.5.5v8a.5.5 0 0 0 .5.5h9a.5.5 0 0 0 .5-.5v-8a.5.5 0 0 0-.5-.5h-2a.5.5 0 0 1 0-1h2A1.5 1.5 0 0 1 14 6.5v8a1.5 1.5 0 0 1-1.5 1.5h-9A1.5 1.5 0 0 1 2 14.5v-8A1.5 1.5 0 0 1 3.5 5h2a.5.5 0 0 1 0 1h-2z"/><path fill-rule="evenodd" d="M7.646.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 1.707V10.5a.5.5 0 0 1-1 0V1.707L5.354 3.854a.5.5 0 1 1-.708-.708l3-3z"/>' + svgClose;
const linkIcon = svgOpen + '<path fill-rule="evenodd" d="M10.854 7.146a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 1 1 .708-.708L7.5 9.793l2.646-2.647a.5.5 0 0 1 .708 0z"/><path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/><path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/>' + svgClose;
const imagesHolder = document.createElement('div');
let startX = 0;
let endX = 0;
let diff = 0;
let threshold = 50;
let startouch = false;
let imgLoader = new Image();
const spinners = {
'bounce': ['sk-bounce', 'sk-bounce-dot', 2],
'chase': ['sk-chase', 'sk-chase-dot', 6],
'circle': ['sk-circle', 'sk-circle-dot', 12],
'circle-fade': ['sk-circle-fade', 'sk-circle-fade-dot', 12],
'flow': ['sk-flow', 'sk-flow-dot', 3],
'fold': ['sk-fold', 'sk-fold-cube', 4],
'grid': ['sk-grid', 'sk-grid-cube', 9],
'plane': ['sk-plane', '', 0],
'pulse': ['sk-pulse', '', 5],
'swing': ['sk-swing', 'sk-swing-dot', 2],
'wander': ['sk-wander', 'sk-wander-cube', 3],
'wave': ['sk-wave', 'sk-wave-rec', 5]
};
// Default settings
const defaults = {
selector: '.venobox',
autoplay : false,
bgcolor: '#fff',
border: '0',
customClass: false,
infinigall: false,
maxWidth: '100%',
navigation: true,
navKeyboard: true,
navTouch: true,
navSpeed: 300,
numeration: false,
overlayClose: true,
overlayColor: 'rgba(23,23,23,0.95)',
popup: false,
ratio: '16x9', // '1x1' | '4x3' | '16x9' | '21x9'
share: false,
shareStyle: 'pill', // 'bar' | 'block' | 'pill' | 'transparent'
spinner: 'bounce', // 'plane' | 'chase' | 'bounce' | 'wave' | 'pulse' | 'flow' | 'swing' | 'circle' | 'circle-fade' | 'grid' | 'fold' | 'wander'
spinColor : '#d2d2d2',
titleattr: 'title',
titlePosition: 'top', // 'top' || 'bottom'
titleStyle: 'bar', // 'bar' | 'block' | 'pill' | 'transparent'
toolsBackground: '#1C1C1C', // 'transparent'
toolsColor: '#d2d2d2',
onPreOpen: function(){ return true; }, // Return the selected object - set return false to prevent opening
onPostOpen: function(){}, // Return: current_item, gallIndex, thenext, theprev
onPreClose: function(){ return true; }, // Return: current_item, gallIndex, thenext, theprev - set return false to prevent closing
onNavComplete: function(){}, // Return: current_item, gallIndex, thenext, theprev
onContentLoaded: function(){}, // Return: newcontent
onInit: function(){}, // Return: plugin obj
jQuerySelectors: false,
};
/**
* Generate spinner html
* @param {Array} spinarray Selected spinner
*/
function createspinner(spinarray){
if (!spinarray) {
return 'Loading...';
}
let spinner = '<div class="sk-center ' + spinarray[0] + '">';
let i = 0;
for (i = 0; i < spinarray[2]; i++) {
spinner += '<div class="' + spinarray[1] + '"></div>';
}
spinner += '</div>';
return spinner;
}
/**
* A simple forEach() implementation for Arrays, Objects and NodeLists
* @param {Array|Object|NodeList} collection Collection of items to iterate
* @param {Function} callback Callback function for each iteration
* @param {Array|Object|NodeList} scope Object/NodeList/Array that forEach is iterating over (aka `this`)
*/
function forEach(collection, callback, scope) {
if (Object.prototype.toString.call(collection) === '[object Object]') {
let prop;
for (prop in collection) {
if (Object.prototype.hasOwnProperty.call(collection, prop)) {
callback.call(scope, collection[prop], prop, collection);
}
}
} else {
let i = 0;
let len = collection.length;
for (i = 0; i < len; i++) {
callback.call(scope, collection[i], i, collection);
}
}
}
/**
* Merge defaults with user options
* @param {Object} defaults Default settings
* @param {Object} options User options
* @returns {Object} Merged values of defaults and options
*/
function extend( defaults, options ) {
let extended = {};
forEach(defaults, function (value, prop) {
extended[prop] = defaults[prop];
});
forEach(options, function (value, prop) {
extended[prop] = options[prop];
});
return extended;
}
/**
* Linear animation timing
*/
function timingLinear(timeFraction){
return timeFraction;
}
/**
* Animate with callback
* https://javascript.info/js-animation
*/
function animate({timing, draw, duration}) {
let start = performance.now();
requestAnimationFrame(function animate(time) {
// timeFraction goes from 0 to 1
let timeFraction = (time - start) / duration;
if (timeFraction > 1) {
timeFraction = 1;
}
// calculate the current animation state
let progress = timing(timeFraction);
draw(progress); // draw it
if (timeFraction < 1) {
requestAnimationFrame(animate);
}
});
}
/**
* Parse Youtube or Vimeo videos and get host & ID
*/
function parseVideo(url) {
let type, match, vid;
let regYt = /(https?:\/\/)?((www\.)?(youtube(-nocookie)?|youtube.googleapis)\.com.*(v\/|v=|vi=|vi\/|e\/|embed\/|user\/.*\/u\/\d+\/)|youtu\.be\/)([_0-9a-z-]+)/i;
match = url.match(regYt);
if (match && match[7]) {
type = 'youtube';
vid = match[7];
} else {
let regVim = /^.*(vimeo\.com\/)((channels\/[A-z]+\/)|(groups\/[A-z]+\/videos\/))?([0-9]+)/;
match = url.match(regVim);
if (match && match[5]) {
type = 'vimeo';
vid = match[5];
}
}
return {
type: type,
id: vid
};
}
/**
* Get additional url parameters
*/
function getUrlParameter(url) {
let result = '';
let sPageURL = decodeURIComponent(url);
let firstsplit = sPageURL.split('?');
if (firstsplit[1] !== undefined) {
let sURLVariables = firstsplit[1].split('&');
let sParameterName;
let i;
for (i = 0; i < sURLVariables.length; i++) {
sParameterName = sURLVariables[i].split('=');
result = result + '&'+ sParameterName[0]+'='+ sParameterName[1];
}
}
return encodeURI(result);
}
/**
* Get all images from string
*/
function getImages(string) {
imagesHolder.innerHTML = string;
return imagesHolder.querySelectorAll('img');
}
/**
* Update item settings.
*/
function updateVars(obj){
if (!obj) {
return false;
}
navigationDisabled = true;
current_item = obj;
nextok = false;
prevok = false;
set_maxWidth = obj.getAttribute("data-maxwidth") || obj.settings.maxWidth;
set_overlayColor = obj.getAttribute("data-overlay") || obj.settings.overlayColor;
set_ratio = obj.getAttribute("data-ratio") || obj.settings.ratio;
set_autoplay = obj.getAttribute("data-autoplay") || obj.settings.autoplay;
set_href = obj.getAttribute("data-href") || obj.getAttribute('href');
set_customclass = obj.getAttribute("data-customclass") || obj.settings.customClass;
title = obj.getAttribute(obj.settings.titleattr) || '';
thisborder = obj.getAttribute("data-border") || obj.settings.border;
}
/**
* Close modal.
*/
function close() {
if (!current_item || !document.body.classList.contains('vbox-open')) {
return false;
}
if (current_item.settings.onPreClose && typeof current_item.settings.onPreClose === 'function') {
current_item.settings.onPreClose(current_item, gallIndex, thenext, theprev);
if (current_item.settings.onPreClose === false) {
return false;
}
}
document.body.removeEventListener('keydown', keyboardHandler);
document.body.classList.remove('vbox-open');
current_item.focus();
animate({
duration: 200,
timing: timingLinear,
draw: function(progress) {
overlay.style.opacity = 1 - progress;
if (progress === 1){
overlay.remove();
}
}
});
}
/**
* Navigate gallery.
*/
function next() {
navigateGall(thenext);
}
function prev() {
navigateGall(theprev);
}
/**
* Keyboard navigation.
*/
function keyboardHandler(e) {
if (e.keyCode === 27) { // esc
close();
}
if (!throttle) {
if (e.keyCode == 37 && prevok === true) { // <
navigateGall(theprev);
}
if (e.keyCode == 39 && nextok === true) { // >
navigateGall(thenext);
}
/* prevent keyboard processing until timer completed */
throttle = setTimeout(() => {
throttle = null;
}, 100);
}
}
/**
* Append and fade-in new content
*/
function contentLoaded(){
navigationDisabled = false;
content.style.opacity = 0;
content.innerHTML = newcontent;
let vboxChild = content.querySelector(":first-child");
vboxChild.classList.add('vbox-child');
vboxChild.style.backgroundColor = current_item.settings.bgcolor;
vboxChild.style.maxWidth = set_maxWidth;
vboxChild.style.transform = 'scale(0.9)';
vboxChild.style.transition = 'transform 200ms';
// Fix weird drag
let childImageLock = content.querySelector('.vbox-child img');
if (childImageLock) {
childImageLock.addEventListener('dragstart', function(e) {
e.preventDefault();
});
}
// reset content scroll
container.scrollTo(0, 0);
vboxChild.style.transform = 'scale(1)';
overlay.style.setProperty('--vbox-padding', thisborder);
// Reset custom classes.
forEach(overlay.classList, function(obj){
if (obj !== 'vbox-overlay') {
overlay.classList.remove(obj);
}
});
// Set custom class.
if (set_customclass){
overlay.classList.add(set_customclass);
}
animate({
duration: 200,
timing: timingLinear,
draw: function(progress) {
content.style.opacity = progress;
if (progress === 1){
elPreloader.classList.add('vbox-hidden');
}
}
});
if (current_item.settings.onContentLoaded && typeof current_item.settings.onContentLoaded === 'function') {
current_item.settings.onContentLoaded(newcontent);
}
}
/**
* Check animation state
* @param {string} state 'loading' | 'animated'
*/
function checkState(state) {
if (!content.classList.contains('vbox-' + state)) {
contentLoaded();
}
}
/**
* Load iFrame
*/
function loadIframe(dest, ratio){
content.classList.add("vbox-loading");
newcontent = '<div class="venoratio venoratio-' + ratio + '"><iframe src="' + dest + '"></iframe></div>';
content.classList.remove("vbox-loading");
checkState('animated');
}
/**
* Load videos
*/
function loadVid(dest, ratio, autoplay){
content.classList.add("vbox-loading");
let stringAutoplay;
// check if it's a video file - thanks to @alexxandar
if (dest.search(/.+\.mp4|og[gv]|webm/) !== -1) {
stringAutoplay = autoplay ? " autoplay" : "";
newcontent = '<div class="venoratio venoratio-' + ratio + '"><video src="' + dest + '"' + stringAutoplay + ' controls>Your browser does not support the video tag.</video></div>';
} else {
let player;
let videoObj = parseVideo(dest);
// set rel=0 to hide related videos at the end of YT + optional autoplay
stringAutoplay = autoplay ? "?rel=0&autoplay=1" : "?rel=0";
let queryvars = stringAutoplay + getUrlParameter(dest);
if (videoObj.type == 'vimeo') {
player = 'https://player.vimeo.com/video/';
} else if (videoObj.type == 'youtube') {
player = 'https://www.youtube.com/embed/';
}
newcontent = '<div class="venoratio venoratio-' + ratio + '"><iframe webkitallowfullscreen mozallowfullscreen allowfullscreen allow="autoplay" frameborder="0" src="'+player+videoObj.id+queryvars+'"></iframe></div>';
}
content.classList.remove("vbox-loading");
checkState('animated');
}
/**
* Load inline content
*/
function loadInline(dest){
let inlineContent = document.querySelector(dest);
if (inlineContent) {
content.classList.add("vbox-loading");
newcontent = '<div class="vbox-inline">' + inlineContent.innerHTML + '</div>';
content.classList.remove("vbox-loading");
checkState('animated');
}
}
/**
* Preload images from ajax call
*/
function loadAjaxImages(){
images = getImages(newcontent);
if (images.length) {
let imgCounter = 0;
forEach(images, function(getimg){
let srcimg = getimg.src;
imgLoader = new Image();
imgLoader.onload = function(){
imgCounter++;
if ( imgCounter == images.length ) {
content.classList.remove("vbox-loading");
checkState('animated');
}
};
imgLoader.onerror = function(){
imgCounter++;
if ( imgCounter == images.length ) {
content.classList.remove("vbox-loading");
checkState('animated');
}
};
imgLoader.src = srcimg;
});
} else {
content.classList.remove("vbox-loading");
checkState('animated');
}
}
/**
* Load Ajax
*/
function loadAjax(dest){
content.classList.add("vbox-loading");
let xhr = new XMLHttpRequest();
xhr.open("GET", dest, true);
xhr.onload = function() {
newcontent = '<div class="vbox-inline">'+ xhr.response +'</div>';
loadAjaxImages();
};
xhr.onerror = function() {
newcontent = '<div class="vbox-inline"></div>';
content.classList.remove("vbox-loading");
checkState('animated');
};
xhr.send();
}
/**
* Preload image
*/
function loadImage(dest){
imgLoader.onload = function(){
// image has been loaded
newcontent = '<div class="vbox-child"><img src="' + dest + '"></div>';
content.classList.remove('vbox-loading');
checkState('animated');
};
imgLoader.src = dest;
}
/**
* Start Drag
*/
function dragStart(e) {
if (!navigationDisabled) {
let speed = (current_item.settings.navSpeed * 0.84);
content.style.transition = 'margin '+ speed + 'ms ease-out, opacity '+ speed + 'ms ease-out';
startY = endY = e.pageY;
startX = endX = e.pageX;
startouch = true;
}
}
/**
* End Drag
*/
function dragEnd(e) {
if (startouch) {
startouch = false;
let subject = current_item;
let change = false;
diff = endX - startX;
if (diff < 0 && nextok) {
subject = thenext;
change = true;
}
if (diff > 0 && prevok) {
subject = theprev;
change = true;
}
if (Math.abs(diff) >= threshold && change) {
navigateGall(subject);
} else {
content.style.marginLeft = 0;
content.style.opacity = 1;
}
}
}
/**
* Drag items
*/
function drag(e) {
if (startouch && !navigationDisabled) {
endX = e.pageX;
endY = e.pageY;
diffX = endX - startX;
diffY = endY - startY;
let absdiffX = Math.abs(diffX);
let absdiffY = Math.abs(diffY);
if ((absdiffX > absdiffY) && (absdiffX <= 180)) {
let diffopac = (1 - absdiffX / 180) * 1.5;
e.preventDefault();
content.style.marginLeft = diffX + 'px';
content.style.opacity = diffopac;
}
}
}
function setShareButtons(href){
// Navigator share
if (navigator.canShare) {
const shareData = {
url: href
};
blockshare.insertAdjacentHTML('beforeend', '<div class="vbox-link-btn vbox-share-mobile">'+shareIcon+'</div>');
const mobileShareBtn = blockshare.querySelector('.vbox-share-mobile');
mobileShareBtn.addEventListener('click', function(e){
e.preventDefault();
navigator.share(shareData);
});
}
// Download
blockshare.insertAdjacentHTML('beforeend', '<a target="_blank" href="'+href+'" download>'+downloadIcon+'</a>');
// Copy link
blockshare.insertAdjacentHTML('beforeend', '<div class="vbox-tooltip"><div class="vbox-link-btn vbox-share-copy"><span class="vbox-tooltip-text" id="myTooltip"></span>'+linkIcon+'</div ></div>');
const shareCopyBtn = blockshare.querySelector('.vbox-share-copy');
shareCopyBtn.addEventListener('click', function(e){
e.preventDefault();
let tooltip = document.getElementById("myTooltip");
navigator.clipboard.writeText(href).then(function() {
tooltip.innerHTML = '<div class="vbox-tooltip-inner">Copied</div>';
}, function() {
console.log('copy failed');
});
});
}
/**
* Check navigation
* @param {object} el Current item
*/
function checknav(el){
if (!el) {
return false;
}
thisgall = el.dataset.gall;
numeratio = el.settings.numeration;
infinigall = el.settings.infinigall;
blockshare.innerHTML = '';
let vbtype = el.dataset.vbtype;
if (el.settings.share && vbtype !== 'iframe' && vbtype !== 'inline' && vbtype !== 'ajax' ) {
setShareButtons(el.href);
}
items = document.querySelectorAll('.vbox-item[data-gall="' + thisgall + '"]');
current_index = Array.prototype.indexOf.call(items, el);
if (items.length < 2) {
infinigall = false;
numeratio = false;
}
thenext = items[current_index + 1];
theprev = items[current_index - 1];
if (!thenext && infinigall) {
thenext = items[0];
}
if (!theprev && infinigall) {
theprev = items[items.length - 1];
}
// Update gallery numeration
if (items.length >= 1) {
gallIndex = current_index + 1;
blocknum.innerHTML = gallIndex + ' / ' + items.length;
} else {
gallIndex = 1;
}
if (numeratio) {
blocknum.classList.remove('vbox-hidden');
} else {
blocknum.classList.add('vbox-hidden');
}
// Update title
if (title !== '') {
blocktitle.classList.remove('vbox-hidden');
} else {
blocktitle.classList.add('vbox-hidden');
}
blocktitle.innerHTML = title;
// update navigation arrows
prevok = false;
nextok = false;
if (thenext || infinigall) {
nextok = true;
}
if (current_index > 0 || infinigall) {
prevok = true;
}
// activate swipe
if ((prevok || nextok) && el.settings.navTouch) {
content.classList.add('vbox-grab');
content.addEventListener("touchstart", dragStart, false);
content.addEventListener("touchend", dragEnd, false);
content.addEventListener("touchmove", drag, false);
content.addEventListener("mousedown", dragStart, false);
content.addEventListener("mouseup", dragEnd, false);
content.addEventListener("mouseout", dragEnd, false);
content.addEventListener("mousemove", drag, false);
} else {
content.classList.remove('vbox-grab');
content.removeEventListener("touchstart", dragStart, false);
content.removeEventListener("touchend", dragEnd, false);
content.removeEventListener("touchmove", drag, false);
content.removeEventListener("mousedown", dragStart, false);
content.removeEventListener("mouseup", dragEnd, false);
content.removeEventListener("mouseout", dragEnd, false);
content.removeEventListener("mousemove", drag, false);
}
let vbox_next = overlay.querySelector('.vbox-next');
let vbox_prev = overlay.querySelector('.vbox-prev');
if (prevok) {
vbox_prev.classList.remove('vbox-hidden');
} else {
vbox_prev.classList.add('vbox-hidden');
}
if (nextok) {
vbox_next.classList.remove('vbox-hidden');
} else {
vbox_next.classList.add('vbox-hidden');
}
if (!el.settings.navigation) {
vbox_next.classList.add('vbox-hidden');
vbox_prev.classList.add('vbox-hidden');
}
} // Checknav
/**
* Update overlay and tools style.
*/
function updateOverlay(destination){
if (!destination) {
return false;
}
backdrop.style.backgroundColor = set_overlayColor;
// Custom preloader color.
elPreloaderInner.innerHTML = createspinner(spinners[destination.settings.spinner]);
overlay.style.setProperty('--sk-color', destination.settings.spinColor);
elPreloader.classList.remove('vbox-hidden');
blockshare.classList.remove('vbox-top', 'vbox-bottom');
blocktitle.classList.remove('vbox-top', 'vbox-bottom');
if (destination.settings.titlePosition == 'top') {
blocktitle.classList.add('vbox-top');
blockshare.classList.add('vbox-bottom');
} else {
blocktitle.classList.add('vbox-bottom');
blockshare.classList.add('vbox-top');
}
let titleWidth = destination.settings.titleStyle === 'bar' ? '100%' : 'auto';
let titleRadius = destination.settings.titleStyle === 'pill' ? '5em' : '0';
let shareWidth = destination.settings.shareStyle === 'bar' ? '100%' : 'auto';
let shareRadius = destination.settings.shareStyle === 'pill' ? '5em' : '0';
let titlebg = destination.settings.titleStyle === 'transparent' ? 'transparent' : destination.settings.toolsBackground;
let sharebg = destination.settings.shareStyle === 'transparent' ? 'transparent' : destination.settings.toolsBackground;
overlay.style.setProperty('--vbox-title-width', titleWidth);
overlay.style.setProperty('--vbox-title-radius', titleRadius);
overlay.style.setProperty('--vbox-share-width', shareWidth);
overlay.style.setProperty('--vbox-share-radius', shareRadius);
overlay.style.setProperty('--vbox-tools-color', destination.settings.toolsColor);
overlay.style.setProperty('--vbox-title-background', titlebg);
overlay.style.setProperty('--vbox-share-background', sharebg);
}
/**
* Load content
*/
function loadContent(){
if (!current_item) {
return false;
}
let vbtype = current_item.dataset.vbtype;
switch (vbtype) {
case 'iframe':
loadIframe(set_href, set_ratio);
break;
case 'inline':
loadInline(set_href);
break;
case 'ajax':
loadAjax(set_href);
break;
case 'video':
loadVid(set_href, set_ratio, set_autoplay);
break;
default:
loadImage(set_href);
}
}
/**
* Gallery navigation.
*/
function navigateGall(destination) {
if (!destination || navigationDisabled || !document.body.classList.contains('vbox-open')) {
return false;
}
updateVars(destination);
updateOverlay(destination);
// swipe out item
let speed = (current_item.settings.navSpeed * 0.84);
content.style.transition = 'margin '+ speed + 'ms ease-out, opacity '+ speed + 'ms ease-out';
if (destination === theprev) {
content.classList.add("swipe-right");
}
if (destination === thenext) {
content.classList.add("swipe-left");
}
elPreloader.classList.remove('vbox-hidden');
let startopacity = content.style.opacity;
content.classList.add("vbox-animated", "vbox-loading");
checknav(destination);
animate({
duration: current_item.settings.navSpeed,
timing: timingLinear,
draw: function(progress) {
content.style.opacity = startopacity - progress/startopacity;
if (progress === 1){
content.classList.remove("swipe-left", "swipe-right", "vbox-animated");
content.style.marginLeft = 0;
content.style.transition = '';
checkState('loading');
navigationDisabled = false;
if (current_item.settings.onNavComplete && typeof current_item.settings.onNavComplete === 'function') {
current_item.settings.onNavComplete(current_item, gallIndex, thenext, theprev);
}
}
}
});
loadContent();
}
/**
* Open item.
*/
function open(obj) {
if (document.body.classList.contains('vbox-open') || !obj) {
return false;
}
if (obj.settings.onPreOpen && typeof obj.settings.onPreOpen === 'function') {
obj.settings.onPreOpen(obj);
}
if (!obj.settings.onPreOpen) {
return false;
}
updateVars(obj);
document.body.insertAdjacentHTML('beforeend', core);
document.body.classList.add('vbox-open');
overlay = document.querySelector(".vbox-overlay");
backdrop = overlay.querySelector(".vbox-backdrop");
container = overlay.querySelector(".vbox-container");
content = container.querySelector(".vbox-content");
blocknum = overlay.querySelector(".vbox-num");
blockshare = overlay.querySelector(".vbox-share");
blocktitle = overlay.querySelector(".vbox-title");
elPreloader = overlay.querySelector(".vbox-preloader");
elPreloaderInner = elPreloader.querySelector(".vbox-preloader-inner");
overlay.style.opacity = 0;
updateOverlay(obj);
checknav(obj);
content.classList.add("vbox-animated", "vbox-loading");
// fade in overlay
animate({
duration: 200,
timing: timingLinear,
draw: function(progress) {
overlay.style.opacity = progress;
if (progress === 1){
content.classList.remove('vbox-animated');
navigationDisabled = false;
checkState('loading');
if (current_item.settings.onPostOpen && typeof current_item.settings.onPostOpen === 'function') {
current_item.settings.onPostOpen(current_item, gallIndex, thenext, theprev);
}
}
}
});
loadContent();
// Keyboard actions
if (obj.settings.navKeyboard) {
document.body.addEventListener('keydown', keyboardHandler);
// Reset the throttle timer
document.body.addEventListener('keyup', () => {
if (throttle) {
clearTimeout(throttle);
throttle = null;
}
});
}
// Prev gallery
document.querySelector('.vbox-prev').addEventListener('click', function(){
navigateGall(theprev);
});
// Newxt gallery
document.querySelector('.vbox-next').addEventListener('click', function(){
navigateGall(thenext);
});
// Close modal.
overlay.addEventListener('click', function(e){
let closeBtn = document.querySelector('.vbox-close');
if (closeBtn) {
if (closeBtn.contains(e.target) || closeBtn === e.target || (current_item.settings.overlayClose &&
e.target.classList.contains('vbox-overlay') ||
e.target.classList.contains('vbox-content') ||
e.target.classList.contains('vbox-backdrop') ||
e.target.classList.contains('vbox-close') ||
e.target.classList.contains('vbox-preloader') ||
e.target.classList.contains('vbox-container')
)) {
close();
}
}
});
}
/**
* Initialize Plugin
*/
function init(venobox, settings) {
if (settings.onInit && typeof settings.onInit === 'function') {
settings.onInit(venobox);
}
let selectors = settings.jQuerySelectors || document.querySelectorAll(settings.selector);
let navigation = '<a class="vbox-next"><span>Next</span></a><a class="vbox-prev"><span>Prev</span></a>';
let vbheader = '<div class="vbox-title"></div><div class="vbox-left-corner"><div class="vbox-num">0/0</div></div><div class="vbox-close"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" class="vbox-close-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M13.854 2.146a.5.5 0 0 1 0 .708l-11 11a.5.5 0 0 1-.708-.708l11-11a.5.5 0 0 1 .708 0Z"/><path fill-rule="evenodd" d="M2.146 2.146a.5.5 0 0 0 0 .708l11 11a.5.5 0 0 0 .708-.708l-11-11a.5.5 0 0 0-.708 0Z"/></svg></div>';
let vbfooter = '<div class="vbox-share"></div>';
let preloader = '<div class="vbox-preloader"><div class="vbox-preloader-inner"></div></div>';
core = '<div class="vbox-overlay"><div class="vbox-backdrop"></div>' + preloader + '<div class="vbox-container"><div class="vbox-content"></div></div>' + vbheader + navigation + vbfooter + '</div>';
/**
* Loop items.
*/
forEach(selectors, function(obj){
if (obj.classList.contains("vbox-item")) {
return true;
}
obj.settings = settings;
obj.classList.add("vbox-item");
// Open Link
obj.addEventListener("click", function(e){
e.preventDefault();
// Remove focus from link to avoid multiple calls with enter key
obj.blur();
open(obj);
return false;
}); // Click;
}); // forEach
if (settings.popup) {
let popup = document.querySelector(settings.popup);
popup.settings = settings;
open(popup);
}
} // init
/**
* VenoBox constructor
*/
const VenoBox = function (options) {
const venobox = {};
// Merge user options with defaults
let settings = extend( defaults, options || {} );
venobox.close = close;
venobox.next = next;
venobox.prev = prev;
venobox.open = open;
venobox.settings = settings;
init(venobox, settings);
// Public APIs
return venobox;
};
/* jQuery bridge for $().venobox() */
if (typeof jQuery === 'function') {
(function($){
$.fn.extend({
// plugin name - venobox
venobox: function(options) {
const pluginoptions = options || {};
pluginoptions.jQuerySelectors = this;
// Init venobx
new VenoBox({pluginoptions});
} // venobox
}); // extend
})(jQuery);
}
// See https://www.npmjs.com/package/venobox documentation.
return VenoBox;
})));