/**
* Product Image Slideshow
*/
(function () {
"use strict";
// Initialize slideshow on DOM ready
function initProductImageSlideshow() {
const slideshowContainers = document.querySelectorAll(
".brandy-product-image-slideshow"
);
slideshowContainers.forEach((container) => {
const mainImage = container.querySelector(
'img[data-testid="product-image"]'
);
const slideImages = container.querySelectorAll(".brandy-slide-image");
const displaySecondaryImage = container.classList.contains(
"brandy-display-secondary-image"
);
// Skip if no gallery images
if (!slideImages || slideImages.length === 0) {
return;
}
const totalSlides = slideImages.length; // +1 for main image
let currentSlideIndex = 0;
let savedSlideIndex = 0; // Save the index before starting auto-slide
let isHovering = false;
// Create navigation arrows
if (!displaySecondaryImage) {
createArrows(container);
}
// Set up event listeners
setupEventListeners(container, slideImages, mainImage);
function createArrows(container) {
// Previous arrow
const prevArrow = document.createElement("button");
prevArrow.className = "brandy--arrow brandy--arrow-prev";
prevArrow.setAttribute("aria-label", "Previous image");
prevArrow.innerHTML =
'';
prevArrow.addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
previousSlide();
if (savedSlideIndex === 0) {
savedSlideIndex = totalSlides;
} else {
savedSlideIndex = savedSlideIndex - 1;
}
});
// Next arrow
const nextArrow = document.createElement("button");
nextArrow.className = "brandy--arrow brandy--arrow-next";
nextArrow.setAttribute("aria-label", "Next image");
nextArrow.innerHTML =
'';
nextArrow.addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
nextSlide();
if (savedSlideIndex === totalSlides) {
savedSlideIndex = 0;
} else {
savedSlideIndex = savedSlideIndex + 1;
}
});
// Find the link element to append arrows to
const link = container.querySelector("a");
if (link) {
link.appendChild(prevArrow);
link.appendChild(nextArrow);
}
}
function setupEventListeners(container, slideImages, mainImage) {
// Mouse enter - save current position and start auto-cycling
container.addEventListener("mouseenter", () => {
isHovering = true;
savedSlideIndex = currentSlideIndex; // Save current position before cycling
nextSlide(); // Immediately show next slide
});
// Mouse leave - stop cycling and return to saved position
container.addEventListener("mouseleave", () => {
isHovering = false;
returnToSavedSlide();
});
// Touch events for mobile
let touchStartX = 0;
let touchEndX = 0;
container.addEventListener(
"touchstart",
(e) => {
touchStartX = e.changedTouches[0].screenX;
},
{ passive: true }
);
container.addEventListener(
"touchend",
(e) => {
touchEndX = e.changedTouches[0].screenX;
handleSwipe();
},
{ passive: true }
);
function handleSwipe() {
const swipeThreshold = 50;
if (touchEndX < touchStartX - swipeThreshold) {
// Swipe left - next slide
nextSlide();
savedSlideIndex = currentSlideIndex; // Update saved index when swiping
} else if (touchEndX > touchStartX + swipeThreshold) {
// Swipe right - previous slide
previousSlide();
savedSlideIndex = currentSlideIndex; // Update saved index when swiping
}
}
}
function goToSlide(index) {
currentSlideIndex = index;
// Update images
if (index === 0) {
// Show main image
mainImage.style.opacity = "1";
slideImages.forEach((img) => {
img.classList.remove("active");
});
container.classList.remove("has-active-slide");
} else {
// Show gallery image
mainImage.style.opacity = "0";
container.classList.add("has-active-slide");
slideImages.forEach((img, i) => {
if (i === index - 1) {
img.classList.add("active");
} else {
img.classList.remove("active");
}
});
}
}
function nextSlide() {
const totalSlides = slideImages.length + 1; // +1 for main image
currentSlideIndex = (currentSlideIndex + 1) % totalSlides;
goToSlide(currentSlideIndex);
}
function previousSlide() {
const totalSlides = slideImages.length + 1; // +1 for main image
currentSlideIndex = (currentSlideIndex - 1 + totalSlides) % totalSlides;
goToSlide(currentSlideIndex);
}
function returnToSavedSlide() {
// Return to the saved slide index after a short delay
if (!isHovering) {
goToSlide(savedSlideIndex);
}
}
// Keyboard navigation
container.addEventListener("keydown", (e) => {
if (e.key === "ArrowLeft") {
e.preventDefault();
previousSlide();
savedSlideIndex = currentSlideIndex; // Update saved index when manually navigating
} else if (e.key === "ArrowRight") {
e.preventDefault();
nextSlide();
savedSlideIndex = currentSlideIndex; // Update saved index when manually navigating
}
});
});
}
// Initialize on DOM ready
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initProductImageSlideshow);
} else {
initProductImageSlideshow();
}
// Re-initialize on dynamic content load (e.g., AJAX product loading)
document.addEventListener(
"wc-blocks_render_blocks_frontend",
initProductImageSlideshow
);
document.addEventListener("updated_wc_div", initProductImageSlideshow);
})();