window.Webflow = window.Webflow || []; window.Webflow.push(function () { if (window.__productsScrollV2) return; window.__productsScrollV2 = true; gsap.registerPlugin(ScrollTrigger); var section = document.querySelector(".products_scroll"); var carousel = document.querySelector(".tricks-slider"); var barActive = document.querySelector(".bar_active"); var mainSlides = ".tricks-slider_slide"; var imageSelector = ".image_graph_visual"; if (!section || !carousel) return; var verticalAmount = 60; var rotationAmount = 6; var maxScale = 1.18; var scrollDistanceFactor = 1.15; var flkty = null; var trigger = null; var uiRaf = null; var resizeTimer = null; function clamp(value, min, max) { return Math.min(Math.max(value, min), max); } function debounce(fn, ms) { return function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(fn, ms); }; } function cancelUiRaf() { if (uiRaf != null) { cancelAnimationFrame(uiRaf); uiRaf = null; } } function setBarProgress(progress) { if (!barActive) return; barActive.style.transform = "scaleX(" + progress + ")"; } function setImagePositions() { var carouselRect = carousel.getBoundingClientRect(); var carouselWidth = carouselRect.width; if (!carouselWidth) return; var carouselCenterX = carouselRect.left + carouselWidth / 2; var slides = carousel.querySelectorAll(mainSlides); var i; var batch = []; for (i = 0; i < slides.length; i++) { var slide = slides[i]; var sr = slide.getBoundingClientRect(); var slideCenter = sr.left + sr.width / 2; var elementOffsetCenter = slideCenter - carouselCenterX; var parentWidth = carouselWidth + sr.width; var progressCenter = elementOffsetCenter / parentWidth; var centerStrength = clamp(1 - Math.abs(progressCenter) * 2, 0, 1); var imageScale = 1 + centerStrength * (maxScale - 1); batch.push({ slide: slide, imageScale: imageScale, progressCenter: progressCenter }); } for (i = 0; i < batch.length; i++) { var item = batch[i]; var img = item.slide.querySelector(imageSelector); var wrap = item.slide.querySelector(".tricks-slider_wrap"); if (img) img.style.transform = "scale(" + item.imageScale + ")"; if (wrap) { wrap.style.transform = "translateY(" + verticalAmount * item.progressCenter + "%) rotate(" + rotationAmount * item.progressCenter + "deg)"; } } } function syncSliderUi() { if (uiRaf != null) return; uiRaf = requestAnimationFrame(function () { uiRaf = null; setImagePositions(); }); } function getBounds() { if (!flkty || !flkty.cells.length) { return { minX: 0, maxX: 0 }; } var firstCell = flkty.cells[0]; var lastCell = flkty.getLastCell(); if (!firstCell || !lastCell) { return { minX: flkty.x || 0, maxX: flkty.x || 0 }; } return { minX: -lastCell.target, maxX: -firstCell.target }; } function getTravel() { var bounds = getBounds(); return Math.max(0, bounds.maxX - bounds.minX); } function setCarouselProgress(progress) { if (!flkty) return; var bounds = getBounds(); var total = bounds.maxX - bounds.minX; var nextX = bounds.maxX - progress * total; flkty.isFreeScrolling = true; flkty.x = clamp(nextX, bounds.minX, bounds.maxX); flkty.velocity = 0; flkty.positionSlider(); syncSliderUi(); } function killScrollTrigger() { if (trigger) { trigger.kill(); trigger = null; } } function destroyDesktopMode() { cancelUiRaf(); killScrollTrigger(); if (flkty) { flkty.destroy(); flkty = null; } gsap.set(section, { clearProps: "all" }); section.classList.remove("is-carousel-ready"); setBarProgress(0); } function createScrollTrigger() { if (!flkty) return; killScrollTrigger(); flkty.resize(); syncSliderUi(); setBarProgress(0); var travel = getTravel(); if (!travel) return; trigger = ScrollTrigger.create({ trigger: section, start: "top top", end: function () { return "+=" + getTravel() * scrollDistanceFactor; }, pin: true, scrub: true, anticipatePin: 1, invalidateOnRefresh: true, onUpdate: function (self) { setCarouselProgress(self.progress); setBarProgress(self.progress); } }); } function layoutThenCreateTrigger() { if (!flkty) return; flkty.resize(); requestAnimationFrame(function () { requestAnimationFrame(function () { createScrollTrigger(); ScrollTrigger.refresh(); section.classList.add("is-carousel-ready"); }); }); } function refreshDesktopLayout() { if (!flkty) return; flkty.resize(); killScrollTrigger(); createScrollTrigger(); ScrollTrigger.refresh(); section.classList.add("is-carousel-ready"); } var debouncedResize = debounce(function () { refreshDesktopLayout(); }, 200); function onWindowLoad() { refreshDesktopLayout(); } function initDesktopMode() { if (flkty) { layoutThenCreateTrigger(); return; } flkty = new Flickity(carousel, { freeScroll: true, contain: true, percentPosition: true, pageDots: false, cellSelector: mainSlides, cellAlign: "center", wrapAround: false, resize: true, imagesLoaded: true, prevNextButtons: false, selectedAttraction: 0.01, freeScrollFriction: 0.05, draggable: false }); flkty.on("scroll", syncSliderUi); flkty.on("settle", syncSliderUi); layoutThenCreateTrigger(); if (document.readyState === "complete") { requestAnimationFrame(onWindowLoad); } else { window.addEventListener("load", onWindowLoad, { once: true }); } window.addEventListener("resize", debouncedResize); } ScrollTrigger.matchMedia({ "(min-width: 992px)": function () { initDesktopMode(); return function () { window.removeEventListener("resize", debouncedResize); window.removeEventListener("load", onWindowLoad); destroyDesktopMode(); }; } }); });