(function() {
console.log(“BALM Gallery Slider: Infinite Loop Loaded v1.0”);
var container = document.getElementById(‘balm-slider-69770a989b418’);
if (!container) return;
var slides = container.querySelector(‘.sv-slides’);
var originalSlideElements = container.querySelectorAll(‘.sv-slide’);
// Clone first and last slides for infinite loop
var firstSlide = originalSlideElements[0];
var lastSlide = originalSlideElements[originalSlideElements.length – 1];
var cloneFirst = firstSlide.cloneNode(true);
var cloneLast = lastSlide.cloneNode(true);
// Add clones to DOM
slides.appendChild(cloneFirst);
slides.insertBefore(cloneLast, firstSlide);
// Re-query slides to include clones
var allSlides = container.querySelectorAll(‘.sv-slide’);
var slideCount = allSlides.length; // Now N + 2
var prevBtn = container.querySelector(‘.sv-prev’);
var nextBtn = container.querySelector(‘.sv-next’);
// Start at index 1 because index 0 is the clone of the last slide
var currentIndex = 1;
var isTransitioning = false;
// Initialize position
slides.style.transform = ‘translateX(-100%)’;
function updateSlide(index) {
if (isTransitioning) return;
currentIndex = index;
slides.style.transition = ‘transform 0.5s ease’;
slides.style.transform = ‘translateX(-‘ + (currentIndex * 100) + ‘%)’;
isTransitioning = true;
}
// Jump to a specific index without animation (teleport)
function jumpToSlide(index) {
slides.style.transition = ‘none’;
currentIndex = index;
slides.style.transform = ‘translateX(-‘ + (currentIndex * 100) + ‘%)’;
}
slides.addEventListener(‘transitionend’, function() {
isTransitioning = false;
if (currentIndex === 0) {
// We are at the cloned last slide, jump to real last slide
jumpToSlide(slideCount – 2);
}
if (currentIndex === slideCount – 1) {
// We are at the cloned first slide, jump to real first slide
jumpToSlide(1);
}
});
prevBtn.addEventListener(‘click’, function(e) {
e.preventDefault();
if (isTransitioning) return;
updateSlide(currentIndex – 1);
});
nextBtn.addEventListener(‘click’, function(e) {
e.preventDefault();
if (isTransitioning) return;
updateSlide(currentIndex + 1);
});
// Touch Support
var touchstartX = 0;
var touchstartY = 0;
var touchcurrentX = 0;
var touchcurrentY = 0;
var isDragging = false;
container.addEventListener(‘touchstart’, function(e) {
if (isTransitioning) return;
isDragging = true;
touchstartX = e.changedTouches[0].screenX;
touchstartY = e.changedTouches[0].screenY;
touchcurrentX = touchstartX;
slides.style.transition = ‘none’;
}, {passive: true});
container.addEventListener(‘touchmove’, function(e) {
if (!isDragging) return;
touchcurrentX = e.changedTouches[0].screenX;
touchcurrentY = e.changedTouches[0].screenY;
var diffX = touchcurrentX – touchstartX;
var diffY = touchcurrentY – touchstartY;
// Allow vertical scroll
if (Math.abs(diffY) > Math.abs(diffX)) return;
if (e.cancelable) e.preventDefault();
var sliderWidth = container.offsetWidth;
var movePercent = (diffX / sliderWidth) * 100;
// The base is determined by the current index (1-based now)
var currentBase = -(currentIndex * 100);
slides.style.transform = ‘translateX(‘ + (currentBase + movePercent) + ‘%)’;
}, {passive: false});
container.addEventListener(‘touchend’, function(e) {
if (!isDragging) return;
isDragging = false;
var diff = touchcurrentX – touchstartX;
var threshold = 50;
if (Math.abs(diff) > threshold) {
if (diff > 0) updateSlide(currentIndex – 1);
else updateSlide(currentIndex + 1);
} else {
updateSlide(currentIndex);
}
});
})();


