Files
kupshop/web/templates/x/static/js/wpj.lightbox.js
2025-08-02 16:30:27 +02:00

229 lines
6.5 KiB
JavaScript

import PhotoSwipe from '@static/photoswipe/photoswipe.js';
import PhotoSwipeUI_Default from '@static/photoswipe/photoswipe-ui-default.js'
function initPhotoSwipeFromDOM(gallerySelector) {
document.addEventListener(
'click',
function(e) {
// loop parent nodes from the target to the delegation node
for (var target = e.target; target && target != this; target = target.parentNode) {
if (typeof target === 'object' && typeof target.matches === 'function' && target.matches(gallerySelector)) {
onThumbnailsClick.call(target, e);
break;
}
}
},
false
);
}
function onThumbnailsClick(e) {
// return nearest parent element or itself
function closestParent(el, fn) {
return el && (fn(el) ? el : closestParent(el.parentNode, fn));
}
e = e || window.event;
e.preventDefault ? e.preventDefault() : (e.returnValue = false);
const eTarget = e.target || e.srcElement;
const clickedListItem = closestParent(eTarget, function(el) {
return el.nodeType === 1 ? el.matches('[data-rel="gallery"]') : null;
});
if (!clickedListItem) {
return;
}
let clickedGallery = closestParent(clickedListItem, function(el) {
return el.nodeType === 1 ? el.matches('[data-gallery-wrapper]') : null;
});
if (!clickedGallery) {
clickedGallery = clickedListItem.parentNode;
}
const childNodes = clickedGallery.querySelectorAll('[data-rel="gallery"]');
let nodeIndex = 0,
index;
for (let i = 0; i < childNodes.length; i++) {
/* check it's element node */
if (childNodes[i].nodeType !== 1) {
continue;
}
if (childNodes[i] === clickedListItem) {
index = nodeIndex;
break;
}
nodeIndex++;
}
/* pokud je index cislo, otevre photoswipe na obrazku s poradim `index` */
if (index >= 0) {
openPhotoSwipe(index, clickedGallery);
}
return false;
}
function openPhotoSwipe(index, galleryElement) {
const pswpElement = document.querySelectorAll('.pswp')[0];
const items = parseThumbnailElements(galleryElement);
const options = {
barsSize: { top: 0, bottom: 0 },
fullscreenEl: false,
shareEl: false,
bgOpacity: 1,
showHideOpacity: true,
tapToToggleControls: false,
index: parseInt(index),
clickToCloseNonZoomable: false,
showAnimationDuration: 0,
hideAnimationDuration: 0,
history: false
};
// exit if index not found
if (isNaN(options.index)) {
return;
}
// Pass data to PhotoSwipe and initialize it
const gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
// see: http://photoswipe.com/documentation/responsive-images.html
let realViewportWidth,
useLargeImages = false,
firstResize = true,
imageSrcWillChange;
gallery.listen('beforeResize', function() {
let dpiRatio = window.devicePixelRatio ? window.devicePixelRatio : 1;
dpiRatio = Math.min(dpiRatio, 2.5);
realViewportWidth = gallery.viewportSize.x * dpiRatio;
if (
realViewportWidth >= 1200 ||
(!gallery.likelyTouchDevice && realViewportWidth > 800) ||
screen.width > 1200
) {
if (!useLargeImages) {
useLargeImages = true;
imageSrcWillChange = true;
}
} else {
if (useLargeImages) {
useLargeImages = false;
imageSrcWillChange = true;
}
}
if (imageSrcWillChange && !firstResize) {
gallery.invalidateCurrItems();
}
if (firstResize) {
firstResize = false;
}
imageSrcWillChange = false;
});
gallery.listen('gettingData', function(index, item) {
if (item.w <= 1 || item.h < 1) {
// unknown size
const img = new Image();
img.onload = function() {
// will get size after load
item.w = this.width; // set image width
item.h = this.height; // set image height
item.needsUpdate = true; //only update the newly loaded item
gallery.updateSize(true); // reinit Items
};
if (item.src) {
img.src = item.src; // let's download image
}
}
});
gallery.init();
$('body').addClass('focus-opened');
gallery.listen('close', function() {
// stop video
// create iframe element with same attributes instead of replacing the src of the iframe
// replacing only the src of the iframe pushes states to window.history
$('iframe').each(function(e) {
const $newIframe = $('<iframe></iframe>');
const originalIframeAttributes = $(this).prop("attributes");
$.each(originalIframeAttributes, function() {
$newIframe.attr(this.name, this.value);
});
$(this).replaceWith($newIframe);
});
$('body').removeClass('focus-opened');
});
}
function parseThumbnailElements(originalEl) {
const thumbElements = originalEl.querySelectorAll('[data-rel="gallery"]');
const items = [];
for (let i = 0; i < thumbElements.length; i++) {
const el = thumbElements[i];
// include only element nodes, filter out extra elements created by tns slider
if (el.nodeType !== 1) {
continue;
}
const childElements = el.querySelectorAll('img');
let size = el.getAttribute('data-size');
let item;
if (el.getAttribute('data-type') === 'video') {
item = {
html:
'<div class="video-wrapper"><div class="video"><iframe class="pswp__video" width="960" height="640" src="' +
(el.getAttribute('href') ? el.getAttribute('href') : el.getAttribute('data-href')) +
'" frameborder="0" allowfullscreen></iframe></div></div>'
};
item.o = {
html: item.html
};
} else {
// create slide object
item = {
src: el.getAttribute('href') ? el.getAttribute('href') : el.getAttribute('data-href'),
w: size ? size.split('x')[0] : 0,
h: size ? size.split('x')[1] : 0,
el: el, // save link to element for getThumbBoundsFn
title: childElements.length ? childElements[0].title || childElements[0].alt : 0
};
// original image
item.o = {
src: item.src,
w: item.w,
h: item.h
};
}
items.push(item);
}
return items;
}
initPhotoSwipeFromDOM('[data-rel="gallery"]');