Skip to content

Instantly share code, notes, and snippets.

@dpw1
Created August 26, 2026 18:18
Show Gist options
  • Select an option

  • Save dpw1/a1343e51c06f33bf15678dad09925f75 to your computer and use it in GitHub Desktop.

Select an option

Save dpw1/a1343e51c06f33bf15678dad09925f75 to your computer and use it in GitHub Desktop.
EZFY Debut theme product image zoom snippet plus Theme settings schema.
,{
"name": "EZFY Product Image Zoom",
"settings": [
{
"type": "paragraph",
"content": "Please save and view the website outside of the Customize page to see the changes."
},
{
"type": "checkbox",
"id": "ezfy_zoom_enable",
"label": "Enable lightbox zoom",
"default": true
},
{
"type": "select",
"id": "ezfy_zoom_type",
"label": "On desktop, activate the lightbox via:",
"info": "Choose whether the zoom is activated by clicking on the image or by clicking on the magnifying glass button.",
"options": [
{
"value": "button",
"label": "Button"
},
{
"value": "click",
"label": "Image click"
}
],
"default": "click"
},
{
"type": "select",
"id": "ezfy_zoom_type_mobile",
"label": "On mobile, activate the lightbox via:",
"info": "Choose whether the zoom is activated by clicking on the image or by clicking on the magnifying glass button.",
"options": [
{
"value": "button",
"label": "Button"
},
{
"value": "click",
"label": "Image click"
}
],
"default": "click"
}
]
}
{% if settings.ezfy_zoom_enable and template contains 'product' %}
<div style="height:0;width:0;display:none"
data_ezfy_zoom_type_mobile="{{ settings.ezfy_zoom_type_mobile }}"
data_ezfy_zoom_type="{{ settings.ezfy_zoom_type }}"
data_ezfy_zoom_block_slider="false"
></div>
<style>
.pswp{display:none;position:absolute;width:100%;height:100%;left:0;top:0;overflow:hidden;-ms-touch-action:none;touch-action:none;z-index:1500;-webkit-text-size-adjust:100%;-webkit-backface-visibility:hidden;outline:0}.pswp *{-webkit-box-sizing:border-box;box-sizing:border-box}.pswp img{max-width:none}.pswp--animate_opacity{opacity:.001;will-change:opacity;-webkit-transition:opacity 333ms cubic-bezier(.4,0,.22,1);transition:opacity 333ms cubic-bezier(.4,0,.22,1)}.pswp--open{display:block}.pswp--zoom-allowed .pswp__img{cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.pswp--zoomed-in .pswp__img{cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.pswp--dragging .pswp__img{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.pswp__bg{position:absolute;left:0;top:0;width:100%;height:100%;background:#000;opacity:0;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility:hidden;will-change:opacity}.pswp__scroll-wrap{position:absolute;left:0;top:0;width:100%;height:100%;overflow:hidden}.pswp__container,.pswp__zoom-wrap{-ms-touch-action:none;touch-action:none;position:absolute;left:0;right:0;top:0;bottom:0}.pswp__container,.pswp__img{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.pswp__zoom-wrap{position:absolute;width:100%;-webkit-transform-origin:left top;-ms-transform-origin:left top;transform-origin:left top;-webkit-transition:-webkit-transform 333ms cubic-bezier(.4,0,.22,1);transition:transform 333ms cubic-bezier(.4,0,.22,1)}.pswp__bg{will-change:opacity;-webkit-transition:opacity 333ms cubic-bezier(.4,0,.22,1);transition:opacity 333ms cubic-bezier(.4,0,.22,1)}.pswp--animated-in .pswp__bg,.pswp--animated-in .pswp__zoom-wrap{-webkit-transition:none;transition:none}.pswp__container,.pswp__zoom-wrap{-webkit-backface-visibility:hidden}.pswp__item{position:absolute;left:0;right:0;top:0;bottom:0;overflow:hidden}.pswp__img{position:absolute;width:auto;height:auto;top:0;left:0}.pswp__img--placeholder{-webkit-backface-visibility:hidden}.pswp__img--placeholder--blank{background:#222}.pswp--ie .pswp__img{width:100%!important;height:auto!important;left:0;top:0}.pswp__error-msg{position:absolute;left:0;top:50%;width:100%;text-align:center;font-size:14px;line-height:16px;margin-top:-8px;color:#ccc}.pswp__error-msg a{color:#ccc;text-decoration:underline}
.pswp__button{width:44px;height:44px;position:relative;background:0 0;cursor:pointer;overflow:visible;-webkit-appearance:none;display:block;border:0;padding:0;margin:0;float:right;opacity:.75;-webkit-transition:opacity .2s;transition:opacity .2s;-webkit-box-shadow:none;box-shadow:none}.pswp__button:focus,.pswp__button:hover{opacity:1}.pswp__button:active{outline:0;opacity:.9}.pswp__button::-moz-focus-inner{padding:0;border:0}.pswp__ui--over-close .pswp__button--close{opacity:1}.pswp__button,.pswp__button--arrow--left:before,.pswp__button--arrow--right:before{background:url(default-skin.png) 0 0 no-repeat;background-size:264px 88px;width:44px;height:44px}@media (-webkit-min-device-pixel-ratio:1.1),(-webkit-min-device-pixel-ratio:1.09375),(min-resolution:105dpi),(min-resolution:1.1dppx){.pswp--svg .pswp__button,.pswp--svg .pswp__button--arrow--left:before,.pswp--svg .pswp__button--arrow--right:before{background-image:url(default-skin.svg)}.pswp--svg .pswp__button--arrow--left,.pswp--svg .pswp__button--arrow--right{background:0 0}}.pswp__button--close{background-position:0 -44px}.pswp__button--share{background-position:-44px -44px}.pswp__button--fs{display:none}.pswp--supports-fs .pswp__button--fs{display:block}.pswp--fs .pswp__button--fs{background-position:-44px 0}.pswp__button--zoom{display:none;background-position:-88px 0}.pswp--zoom-allowed .pswp__button--zoom{display:block}.pswp--zoomed-in .pswp__button--zoom{background-position:-132px 0}.pswp--touch .pswp__button--arrow--left,.pswp--touch .pswp__button--arrow--right{visibility:hidden}.pswp__button--arrow--left,.pswp__button--arrow--right{background:0 0;top:50%;margin-top:-50px;width:70px;height:100px;position:absolute}.pswp__button--arrow--left{left:0}.pswp__button--arrow--right{right:0}.pswp__button--arrow--left:before,.pswp__button--arrow--right:before{content:'';top:35px;background-color:rgba(0,0,0,.3);height:30px;width:32px;position:absolute}.pswp__button--arrow--left:before{left:6px;background-position:-138px -44px}.pswp__button--arrow--right:before{right:6px;background-position:-94px -44px}.pswp__counter,.pswp__share-modal{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pswp__share-modal{display:block;background:rgba(0,0,0,.5);width:100%;height:100%;top:0;left:0;padding:10px;position:absolute;z-index:1600;opacity:0;-webkit-transition:opacity .25s ease-out;transition:opacity .25s ease-out;-webkit-backface-visibility:hidden;will-change:opacity}.pswp__share-modal--hidden{display:none}.pswp__share-tooltip{z-index:1620;position:absolute;background:#fff;top:56px;border-radius:2px;display:block;width:auto;right:44px;-webkit-box-shadow:0 2px 5px rgba(0,0,0,.25);box-shadow:0 2px 5px rgba(0,0,0,.25);-webkit-transform:translateY(6px);-ms-transform:translateY(6px);transform:translateY(6px);-webkit-transition:-webkit-transform .25s;transition:transform .25s;-webkit-backface-visibility:hidden;will-change:transform}.pswp__share-tooltip a{display:block;padding:8px 12px;color:#000;text-decoration:none;font-size:14px;line-height:18px}.pswp__share-tooltip a:hover{text-decoration:none;color:#000}.pswp__share-tooltip a:first-child{border-radius:2px 2px 0 0}.pswp__share-tooltip a:last-child{border-radius:0 0 2px 2px}.pswp__share-modal--fade-in{opacity:1}.pswp__share-modal--fade-in .pswp__share-tooltip{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.pswp--touch .pswp__share-tooltip a{padding:16px 12px}a.pswp__share--facebook:before{content:'';display:block;width:0;height:0;position:absolute;top:-12px;right:15px;border:6px solid transparent;border-bottom-color:#fff;-webkit-pointer-events:none;-moz-pointer-events:none;pointer-events:none}a.pswp__share--facebook:hover{background:#3e5c9a;color:#fff}a.pswp__share--facebook:hover:before{border-bottom-color:#3e5c9a}a.pswp__share--twitter:hover{background:#55acee;color:#fff}a.pswp__share--pinterest:hover{background:#ccc;color:#ce272d}a.pswp__share--download:hover{background:#ddd}.pswp__counter{position:absolute;left:0;top:0;height:44px;font-size:13px;line-height:44px;color:#fff;opacity:.75;padding:0 10px}.pswp__caption{position:absolute;left:0;bottom:0;width:100%;min-height:44px}.pswp__caption small{font-size:11px;color:#bbb}.pswp__caption__center{text-align:left;max-width:420px;margin:0 auto;font-size:13px;padding:10px;line-height:20px;color:#ccc}.pswp__caption--empty{display:none}.pswp__caption--fake{visibility:hidden}.pswp__preloader{width:44px;height:44px;position:absolute;top:0;left:50%;margin-left:-22px;opacity:0;-webkit-transition:opacity .25s ease-out;transition:opacity .25s ease-out;will-change:opacity;direction:ltr}.pswp__preloader__icn{width:20px;height:20px;margin:12px}.pswp__preloader--active{opacity:1}.pswp__preloader--active .pswp__preloader__icn{background:url(preloader.gif) 0 0 no-repeat}.pswp--css_animation .pswp__preloader--active{opacity:1}.pswp--css_animation .pswp__preloader--active .pswp__preloader__icn{-webkit-animation:clockwise .5s linear infinite;animation:clockwise .5s linear infinite}.pswp--css_animation .pswp__preloader--active .pswp__preloader__donut{-webkit-animation:donut-rotate 1s cubic-bezier(.4,0,.22,1) infinite;animation:donut-rotate 1s cubic-bezier(.4,0,.22,1) infinite}.pswp--css_animation .pswp__preloader__icn{background:0 0;opacity:.75;width:14px;height:14px;position:absolute;left:15px;top:15px;margin:0}.pswp--css_animation .pswp__preloader__cut{position:relative;width:7px;height:14px;overflow:hidden}.pswp--css_animation .pswp__preloader__donut{-webkit-box-sizing:border-box;box-sizing:border-box;width:14px;height:14px;border:2px solid #fff;border-radius:50%;border-left-color:transparent;border-bottom-color:transparent;position:absolute;top:0;left:0;background:0 0;margin:0}@media screen and (max-width:1024px){.pswp__preloader{position:relative;left:auto;top:auto;margin:0;float:right}}@-webkit-keyframes clockwise{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes clockwise{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes donut-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}50%{-webkit-transform:rotate(-140deg);transform:rotate(-140deg)}100%{-webkit-transform:rotate(0);transform:rotate(0)}}@keyframes donut-rotate{0%{-webkit-transform:rotate(0);transform:rotate(0)}50%{-webkit-transform:rotate(-140deg);transform:rotate(-140deg)}100%{-webkit-transform:rotate(0);transform:rotate(0)}}.pswp__ui{-webkit-font-smoothing:auto;visibility:visible;opacity:1;z-index:1550}.pswp__top-bar{position:absolute;left:0;top:0;height:44px;width:100%}.pswp--has_mouse .pswp__button--arrow--left,.pswp--has_mouse .pswp__button--arrow--right,.pswp__caption,.pswp__top-bar{-webkit-backface-visibility:hidden;will-change:opacity;-webkit-transition:opacity 333ms cubic-bezier(.4,0,.22,1);transition:opacity 333ms cubic-bezier(.4,0,.22,1)}.pswp--has_mouse .pswp__button--arrow--left,.pswp--has_mouse .pswp__button--arrow--right{visibility:visible}.pswp__caption,.pswp__top-bar{background-color:rgba(0,0,0,.5)}.pswp__ui--fit .pswp__caption,.pswp__ui--fit .pswp__top-bar{background-color:rgba(0,0,0,.3)}.pswp__ui--idle .pswp__top-bar{opacity:0}.pswp__ui--idle .pswp__button--arrow--left,.pswp__ui--idle .pswp__button--arrow--right{opacity:0}.pswp__ui--hidden .pswp__button--arrow--left,.pswp__ui--hidden .pswp__button--arrow--right,.pswp__ui--hidden .pswp__caption,.pswp__ui--hidden .pswp__top-bar{opacity:.001}.pswp__ui--one-slide .pswp__button--arrow--left,.pswp__ui--one-slide .pswp__button--arrow--right,.pswp__ui--one-slide .pswp__counter{display:none}.pswp__element--disabled{display:none!important}.pswp--minimal--dark .pswp__top-bar{background:0 0}
</style>
<style>
/* Images */
.product-single__photos,
.product-single__media-wrapper{
{% if settings.ezfy_zoom_type == 'click' %}
cursor: -moz-zoom-in;
cursor: -webkit-zoom-in;
cursor: zoom-in;
{% endif %}
}
.FeaturedImage--block-lightbox *{
pointer-events: none;
}
.product-single__media-group [id*='FeaturedMedia'][tabindex]{
position: relative;
}
/* Zoom button */
.EzfyZoom-button *{
pointer-events: none;
}
.EzfyZoom-button{
border-radius: 50%;
width: 34px;
height: 34px;
padding: 0 !important;
position: absolute;
right: 12px;
bottom: 12px;
background: white;
box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
cursor: -moz-zoom-in;
cursor: -webkit-zoom-in;
cursor: zoom-in;
opacity: 0;
transition: opacity 1s ease-in-out;
}
.EzfyZoom-button:hover{
background: white !important;
}
.EzfyZoom-button svg{
fill: black !important;
width: 13.75px;
height: 13.75px;
position: relative;
top: 2px;
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
[id*='FeaturedMedia'] .EzfyZoom-button,
.product-single__photo .EzfyZoom-button{
-webkit-animation: fade-in .5s cubic-bezier(0.39, 0.575, 0.565, 1) both;
animation: fade-in .5s cubic-bezier(0.39, 0.575, 0.565, 1) both;
}
.EzfyZoom-button:active,
.EzfyZoom-button:visited,
.EzfyZoom-button:focus{
background: unset !important;
}
/* PhotoSwipe general styles
================================ */
#ezfyLightbox .pswp__custom-controls{
position: absolute;
display: flex !important;
bottom: 30px;
left: 0;
right: 0;
transform: translateY(0);
transition: transform .32s;
justify-content: center;
align-items: center;
}
#ezfyLightbox .pswp__button[class*='arrow']{
margin-top: unset;
}
#ezfyLightbox .pswp__custom-controls .pswp__button{
background: white;
border-radius: 50%;
width: 49px;
height: 49px;
opacity: 1;
position: relative;
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
transition: unset !important;
transform: unset !important;
visibility: visible;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
#ezfyLightbox .pswp__custom-controls .pswp__button svg{
width: 13px !important;
height: 13px !important;
margin: 8px;
pointer-events: none;
}
#ezfyLightbox svg{
pointer-events: none;
}
#ezfyLightbox .pswp__button:before {
display: none;
}
.pswp__ui--hidden .pswp__custom-controls{
transform: translateY(100px) !important;
}
#ezfyLightbox .pswp__custom-controls .pswp__button--close{
width: 60px;
height: 60px;
margin-left: 25px;
margin-right: 25px;
}
#ezfyLightbox .pswp__custom-controls .pswp__button--close svg{
position: relative;
top: 2px;
}
#ezfyLightbox .pswp__top-bar{
display: none;
}
.EzfyZoom-button{
z-index: 10;
}
/* Custom styles
================================ */
#ezfyLightbox .pswp__bg{
background: white !important;
}
</style>
<div id="ezfyLightbox" class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<!-- Background of PhotoSwipe.
It's a separate element as animating opacity is faster than rgba(). -->
<div class="pswp__bg"></div>
<!-- Slides wrapper with overflow:hidden. -->
<div class="pswp__scroll-wrap">
<!-- Container that holds slides.
PhotoSwipe keeps only 3 of them in the DOM to save memory.
Don't modify these 3 pswp__item elements, data is added later on. -->
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<!-- Controls are self-explanatory. Order can be changed. -->
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--share" title="Share"></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR -->
<!-- element will get class pswp__preloader--active when preloader is running -->
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<div class="pswp__custom-controls">
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
<svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-arrow-left" viewBox="0 0 284.49 498.98"><path d="M249.49 0a35 35 0 0 1 24.75 59.75L84.49 249.49l189.75 189.74a35.002 35.002 0 1 1-49.5 49.5L10.25 274.24a35 35 0 0 1 0-49.5L224.74 10.25A34.89 34.89 0 0 1 249.49 0z"></path></svg>
</button>
<button class="pswp__button pswp__button--close" title="Close (Esc)">
<svg xmlns="http://www.w3.org/2000/svg" id="Capa_1" enable-background="new 0 0 413.348 413.348" height="512" viewBox="0 0 413.348 413.348" width="512"><path d="m413.348 24.354-24.354-24.354-182.32 182.32-182.32-182.32-24.354 24.354 182.32 182.32-182.32 182.32 24.354 24.354 182.32-182.32 182.32 182.32 24.354-24.354-182.32-182.32z"/></svg>
</button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
<svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-arrow-right" viewBox="0 0 284.49 498.98"><path d="M35 498.98a35 35 0 0 1-24.75-59.75l189.74-189.74L10.25 59.75a35.002 35.002 0 0 1 49.5-49.5l214.49 214.49a35 35 0 0 1 0 49.5L59.75 488.73A34.89 34.89 0 0 1 35 498.98z"></path></svg>
</button>
</div>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div>
<script>
/*ezfybeautify*/
/*
[EZFYLICENSE]
1.7.1:
- Improved compatibility with all debut versions
1.7.0:
- Slider images not showing in some older Debut versions
1.6.0:
- Multiple fixes and compatibility to older debuts
1.5.0:
- Removed unnecessary options
1.4.0
- Lightbox zoom "click to zoom" for mobile fix
1.3.0
- Lightbox zoom button only on mobile
1.2.0
- Added option to block lightbox zoom.
- Refactor JS code.
1.1.0
- Loads only at the product page
1.0.9
- Position relative for images to keep button inside
1.0.8
- Added zoom options for desktop/mobile
1.0.7
- Added zoom button
- Added 'settings_schema' options
1.0.6
- Updated zoom to work with multiple videos under the Non-slider debut
1.0.5
- Zoom working correctly with latest Debut Slider version (accepts multiple videos)
1.0.4
- Added short delay after loading photswipe to avoid bugs
1.0.3
- moved parent/child selectors to init of function
- renamed function
1.0.2
- Fix blurry images when opening lightbox
1.0.1
- Hide top bar
1.0.0
- Stylized back, close & next buttons
[EZFYLICENSE]
*/
window.ezfyLightboxZoomDebut = window.ezfyLightboxZoomDebut || {};
ezfyLightboxZoomDebut = (function() {
let IS_DEBUT_SLIDER = false;
const DELAY_AFTER_LOADING_PHOTO_SWIPE = 250;
const CSS_PRODUCT_IMAGE_TAG = `img.feature-row__image`
const CSS_PRODUCT_IMAGE_PARENT = `.product-single__media-wrapper > .product-single__media, .product-single__photo`
const CSS_PARENT = `.product-single__media-group, .product-single__photos`;
/* This is used to detect which thumbnail must be clicked after the
zoomed image changes.
Make sure to replace the "replace_index' with the correct number */
const CSS_THUMBNAIL_CLICKABLE = `.product-single__thumbnails > *:nth-child(REPLACE_INDEX) a, [class*='product-single__thumbnails'] > li:nth-child(REPLACE_INDEX) a`
const CSS_INDIVIDUAL_SLIDE = `.product-single__photo, .product-single__media`
const CLASS_INDIVIDUAL_SLIDE = [`product-single__photo`, ]
const ZOOM_TYPE = (() => {
function _isMobile() {
return window.matchMedia("(max-width: 767px)").matches
}
if (_isMobile()) {
let $el = document.querySelector(`[data_ezfy_zoom_type_mobile]`);
return $el.getAttribute(`data_ezfy_zoom_type_mobile`);
}
let $el = document.querySelector(`[data_ezfy_zoom_type]`);
return $el.getAttribute(`data_ezfy_zoom_type`);
})();
const options = {
blockSlider: _getAttributeOption(`data_ezfy_zoom_block_slider`)
}
function _getAttributeOption(dataAttribute) {
const element = document.querySelector(`[${dataAttribute}]`);
if (!element) {
return null;
}
const attr = element.getAttribute(dataAttribute);
if (attr === 'true') {
return true;
} else if (attr === 'false') {
return false
} else {
return attr;
}
}
const _detectParentSelector = () => {
// using debut slider
if (document.querySelector(`#featuredImageSlider`)) {
IS_DEBUT_SLIDER = true;
return "#featuredImageSlider .flickity-slider";
}
// using default debut
return CSS_PARENT;
}
const CSS_PARENT_SELECTOR = _detectParentSelector();
function _loadScript(src) {
return new Promise(function(resolve, reject) {
var s;
s = document.createElement("script");
s.src = src;
s.onload = resolve;
s.onerror = reject;
document.head.appendChild(s);
});
}
function _isProductPage() {
return /product/.test(window.location.href);
}
async function _getCurrentProductImages() {
return new Promise(async (resolve, reject) => {
const url = `${window.location.origin}/${window.location.pathname}.json`;
let response = await fetch(url);
let data = await response.json();
console.log(data);
resolve(data.product.images);
});
}
function _sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function loadPhotoswipe() {
return new Promise(async (resolve, reject) => {
await _loadScript(`https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe.min.js`);
await _loadScript(`https://cdnjs.cloudflare.com/ajax/libs/photoswipe/4.1.3/photoswipe-ui-default.min.js`);
resolve();
});
}
/* Adds essential data attributes for the images to be clickable. */
async function addImageSizeDataAttribute() {
const $images = document.querySelectorAll(CSS_PRODUCT_IMAGE_TAG);
if (!$images) {
return;
}
const images = await _getCurrentProductImages();
for (const [i, each] of $images.entries()) {
const $parent = each.closest(CSS_PRODUCT_IMAGE_PARENT);
const height = images[i].height;
const width = images[i].width;
const src = images[i].src;
$parent.setAttribute("data-size-zoom", `${width}x${height}`);
$parent.setAttribute("data-image-large", src);
$parent.setAttribute("data-ezfy-zoom-type", ZOOM_TYPE);
if (!$parent.hasAttribute(`data-product-media-type-video`)) {
$parent.setAttribute(`data-image-position`, images[i].position)
}
}
if (!IS_DEBUT_SLIDER) {
const $medias = document.querySelectorAll(CSS_PRODUCT_IMAGE_PARENT);
for (const [i, each] of $medias.entries()) {
each.setAttribute("data-slide-index", i);
}
}
}
function initPhotoSwipeZoom() {
var initPhotoSwipeFromDOM = function(gallerySelector) {
/* Gets all images
======================= */
var parseThumbnailElements = function(el) {
var $elements = document.querySelectorAll(CSS_PRODUCT_IMAGE_PARENT),
items = [],
linkEl,
size,
item;
for (var i = 0; i < $elements.length; i++) {
const $el = $elements[i]; //child element
// include only element nodes
if ($el.nodeType !== 1) {
continue;
}
if (!$el.getAttribute("data-size-zoom")) {
continue;
}
size = $el.getAttribute('data-size-zoom').split('x');
// create slide object
item = {
src: $el.getAttribute('data-image-large'),
w: parseInt(size[0], 10),
h: parseInt(size[1], 10)
};
const $image = $el.querySelector('img');
item.msrc = $el.getAttribute('data-image-large')
item.imagePosition = $el.getAttribute(`data-image-position`);
item.el = $el; // save link to element for getThumbBoundsFn
items.push(item);
}
return items;
};
// find nearest parent element
var _closest = function _closest(el, fn) {
return el && (fn(el) ? el : _closest(el.parentNode, fn));
};
/* Image or button clicked */
var onImageClick = function(e) {
e = e || window.event;
e.preventDefault ? e.preventDefault() : e.returnValue = false;
var eTarget = e.target || e.srcElement;
const $parent = eTarget.closest(CSS_PRODUCT_IMAGE_PARENT);
if ($parent){
const isVideo = $parent.querySelector("video");
if (isVideo) {
return;
}
}
/* If allowed button only, do not open lightbox */
if (ZOOM_TYPE === 'button' && !eTarget.classList.contains('EzfyZoom-button')) {
return;
}
// find root element of slide
var clickedListItem = _closest(eTarget, function(el) {
console.log(el);
if (!el || !el.classList){
return false;
}
return (el.matches(CSS_INDIVIDUAL_SLIDE));
});
if (!clickedListItem) {
return;
}
// find index of clicked item by looping through all child nodes
// alternatively, you may define index via data- attribute
const $clickedParent = clickedListItem.parentNode;
var clickedGallery = $clickedParent;
var $children = $clickedParent.querySelectorAll(CSS_INDIVIDUAL_SLIDE);
var totalChildren = $children.length;
var nodeIndex = 0;
var index;
for (var i = 0; i < totalChildren; i++) {
if ($children[i].nodeType !== 1) {
continue;
}
if ($children[i] === clickedListItem) {
index = nodeIndex;
break;
}
nodeIndex++;
}
index = parseInt(clickedListItem.getAttribute(`data-image-position`) ? clickedListItem.getAttribute(`data-image-position`) : clickedListItem.querySelector(`[data-image-position]`).getAttribute(`data-image-position`)) - 1;
if (index >= 0) {
// open PhotoSwipe if valid index found
openPhotoSwipe(index, clickedGallery);
}
return false;
};
var openPhotoSwipe = function(index, galleryElement, disableAnimation, fromURL) {
var pswpElement = document.querySelectorAll('.pswp')[0],
gallery,
options,
items;
items = parseThumbnailElements(galleryElement);
options = {
barsSize: {
top: 0,
bottom: 'auto'
},
allowPanToNext: false,
captionEl: false,
closeOnScroll: false,
pinchToClose: false,
tapToToggleControls: false,
history: false,
galleryUID: galleryElement.getAttribute('data-pswp-uid'),
getThumbBoundsFn: function(index) {
// See Options -> getThumbBoundsFn section of documentation for more info
var thumbnail = items[index].el.getElementsByTagName('img')[0], // find thumbnail
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return {
x: rect.left,
y: rect.top + pageYScroll,
w: rect.width
};
}
};
// PhotoSwipe opened from URL
if (fromURL) {
if (options.galleryPIDs) {
// parse real index when custom PIDs are used
// http://photoswipe.com/documentation/faq.html#custom-pid-in-url
for (var j = 0; j < items.length; j++) {
if (items[j].pid == index) {
options.index = j;
break;
}
}
} else {
// in URL indexes start from 1
options.index = parseInt(index, 10) - 1;
}
} else {
options.index = parseInt(index, 10);
}
// exit if index not found
if (isNaN(options.index)) {
return;
}
if (disableAnimation) {
options.showAnimationDuration = 0;
}
// Pass data to PhotoSwipe and initialize it
gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
gallery.init();
gallery.ui.hideControls();
gallery.listen('beforeChange', function() {
updateMainSliderImageAsPhotoSwipeChanges(gallery);
});
};
// loop through all gallery elements and bind events
var galleryElements = document.querySelectorAll(gallerySelector);
for (var i = 0, l = galleryElements.length; i < l; i++) {
galleryElements[i].setAttribute('data-pswp-uid', i + 1);
galleryElements[i].onclick = onImageClick;
}
};
// execute above function
initPhotoSwipeFromDOM(CSS_PARENT_SELECTOR);
}
function injectButton() {
if (ZOOM_TYPE !== 'button') {
return;
}
const $button = `<button type="button" class="EzfyZoom-button btn btn--body btn--circle js-photoswipe__zoom product__photo-zoom">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g>
<g>
<path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/>
</g>
</g>
<g>
<g>
<path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/>
</g>
</g>
</svg>
</button>`;
const $images = document.querySelectorAll(CSS_PRODUCT_IMAGE_PARENT);
if (!$images) {
return;
}
for (let each of $images) {
if (each.hasAttribute(`data-product-media-type-video`)) {
continue;
}
each.insertAdjacentHTML('beforeend', $button);
}
}
function updateMainSliderImageAsPhotoSwipeChanges(gallery) {
let index = gallery.getCurrentIndex();
index = gallery.currItem.imagePosition
const _newIndex = document.querySelector(`[data-image-position='${index}']`);
const getNewIndex = () => {
if (_newIndex.hasAttribute(`data-slide-index`)) {
return parseInt(_newIndex.getAttribute(`data-slide-index`));
}
}
const newIndex = getNewIndex();
const i = parseInt(newIndex) + 1;
if (IS_DEBUT_SLIDER && window.ezfyDebutSliderFeatured) {
window.ezfyDebutSliderFeatured.select(newIndex, null, true);
} else {
const selector = CSS_THUMBNAIL_CLICKABLE.replaceAll(`REPLACE_INDEX`, i);
const $thumbnail = document.querySelector(selector);
window.photoSwipeIndex = index;
if ($thumbnail) {
$thumbnail.click();
}
}
}
function blockLightboxOnSliderDrag() {
if (!IS_DEBUT_SLIDER || !window.ezfyVentureSliderFeatured || !options.blockSlider || _isMobile()) {
return;
}
const _class = 'FeaturedImage--block-lightbox';
const $image = document.querySelector(`#featuredImageSlider`);
window.ezfyVentureSliderFeatured.on('dragMove', function(event, pointer, moveVector) {
if ($image.classList.contains(_class)) {
return;
}
$image.classList.add(_class);
});
window.ezfyVentureSliderFeatured.on('dragEnd', function(event, pointer, moveVector) {
$image.classList.remove(_class);
});
}
return {
init: function() {
document.addEventListener("DOMContentLoaded", async function() {
if (_isProductPage()) {
await loadPhotoswipe();
await addImageSizeDataAttribute();
await _sleep(DELAY_AFTER_LOADING_PHOTO_SWIPE);
initPhotoSwipeZoom();
blockLightboxOnSliderDrag();
injectButton();
}
});
window.addEventListener("resize", function() {});
window.addEventListener("load", function() {});
window.addEventListener("scroll", function() {});
},
};
})();
ezfyLightboxZoomDebut.init();
</script>
{% endif %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment