PageSourceSearch

https://zenite.nu/wp-content/plugins/zenite-components/components/carrossel/carrossel.js

js zenite.nu collected 2026-09-24 17:34:07 UTC 7,095 bytes, 233 lines download raw bytes

1document.addEventListener('DOMContentLoaded', function () {
2
3    const breakpoints = {
4        tablet: 768,
5        desktop: 1024
6    };
7
8    const carousels = document.querySelectorAll('.zenite-carousel');
9
10    carousels.forEach(function (carousel) {
11
12        const track = carousel.querySelector('.zc-track');
13        const btnNext = carousel.querySelector('.zc-next');
14        const btnPrev = carousel.querySelector('.zc-prev');
15
16        let originalSlides = Array.from(track.children);
17        if (originalSlides.length <= 1) return;
18
19        const slidesConfig = carousel.dataset.slides.split('|').map(n => parseInt(n, 10));
20
21        let slidesPerView = 1;
22        let index = 0;
23        let autoplay = parseInt(carousel.dataset.autoplay, 10) || 0;
24        let interval = null;
25
26        let slides = [];
27        let isDragging = false;
28        let startX = 0;
29        let isHovered = false;
30        let isVisible = true;
31
32        function getSlidesPerView() {
33            const w = window.innerWidth;
34
35            if (w >= breakpoints.desktop) return slidesConfig[2] || slidesConfig[1] || slidesConfig[0];
36            if (w >= breakpoints.tablet) return slidesConfig[1] || slidesConfig[0];
37            return slidesConfig[0];
38        }
39
40        function setup() {
41            track.innerHTML = '';
42            originalSlides.forEach(el => track.appendChild(el));
43
44            slidesPerView = getSlidesPerView();
45            const totalOriginal = originalSlides.length;
46
47            const clonesBefore = [];
48            const clonesAfter  = [];
49
50            for (let i = 0; i < slidesPerView; i++) {
51                clonesBefore.push(originalSlides[totalOriginal - 1 - i].cloneNode(true));
52                clonesAfter.push(originalSlides[i].cloneNode(true));
53            }
54
55            clonesBefore.reverse().forEach(clone => track.insertBefore(clone, track.firstChild));
56            clonesAfter.forEach(clone => track.appendChild(clone));
57
58            slides = Array.from(track.children);
59            index = slidesPerView;
60
61            updateSlideWidths();
62            jumpTo(index, false);
63
64            // 🔥 preload inicial
65            preloadSlide(index + 1);
66        }
67
68        function updateSlideWidths() {
69            const width = 100 / slidesPerView;
70            slides.forEach(slide => slide.style.width = width + '%');
71        }
72
73        function setTransition(enable = true) {
74            track.style.transition = enable
75                ? 'transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1)'
76                : 'none';
77        }
78
79        function moveTo(i) {
80            index = i;
81            setTransition(true);
82            track.style.transform = `translateX(-${(100 / slidesPerView) * index}%)`;
83        }
84
85        function jumpTo(i, animate = false) {
86            index = i;
87            setTransition(animate);
88            track.style.transform = `translateX(-${(100 / slidesPerView) * index}%)`;
89        }
90
91        function next() {
92            preloadSlide(index + 1);
93            moveTo(index + 1);
94        }
95
96        function prev() {
97            preloadSlide(index - 1);
98            moveTo(index - 1);
99        }
100
101        track.addEventListener('transitionend', function () {
102            const totalOriginal = originalSlides.length;
103
104            if (index >= totalOriginal + slidesPerView) {
105                jumpTo(slidesPerView);
106            }
107
108            if (index < slidesPerView) {
109                jumpTo(totalOriginal + slidesPerView - 1);
110            }
111        });
112
113        // 🔥 PRELOAD
114        function preloadSlide(i) {
115            if (!slides[i]) return;
116
117            const img = slides[i].querySelector('img');
118            if (!img) return;
119
120            const src = img.getAttribute('src');
121            if (!src) return;
122
123            const preloader = new Image();
124            preloader.src = src;
125        }
126
127        function canAutoplay() {
128            return autoplay > 0 && !isHovered && isVisible;
129        }
130
131        function startAutoplay() {
132            stopAutoplay();
133            if (canAutoplay()) {
134                interval = setInterval(next, autoplay);
135            }
136        }
137
138        function stopAutoplay() {
139            if (interval) clearInterval(interval);
140        }
141
142        function restartAutoplayDelayed() {
143            stopAutoplay();
144            if (autoplay > 0) {
145                setTimeout(startAutoplay, 4000);
146            }
147        }
148
149        function getX(e) {
150            return e.type.includes('mouse') ? e.pageX : e.touches[0].clientX;
151        }
152
153        function dragStart(e) {
154            isDragging = true;
155            startX = getX(e);
156            stopAutoplay();
157            setTransition(false);
158        }
159
160        function dragMove(e) {
161            if (!isDragging) return;
162
163            const currentX = getX(e);
164            const diff = currentX - startX;
165
166            track.style.transform = `translateX(calc(-${(100 / slidesPerView) * index}% + ${diff}px))`;
167        }
168
169        function dragEnd(e) {
170            if (!isDragging) return;
171
172            isDragging = false;
173
174            const endX = getX(e);
175            const diff = endX - startX;
176            const threshold = carousel.offsetWidth * 0.1;
177
178            if (diff > threshold) prev();
179            else if (diff < -threshold) next();
180            else moveTo(index);
181
182            restartAutoplayDelayed();
183        }
184
185        // swipe
186        track.addEventListener('mousedown', dragStart);
187        window.addEventListener('mousemove', dragMove);
188        window.addEventListener('mouseup', dragEnd);
189
190        track.addEventListener('touchstart', dragStart, { passive: true });
191        track.addEventListener('touchmove', dragMove, { passive: true });
192        track.addEventListener('touchend', dragEnd);
193
194        // botões
195        if (btnNext) btnNext.addEventListener('click', () => { next(); restartAutoplayDelayed(); });
196        if (btnPrev) btnPrev.addEventListener('click', () => { prev(); restartAutoplayDelayed(); });
197
198        // hover
199        carousel.addEventListener('mouseenter', () => {
200            isHovered = true;
201            stopAutoplay();
202        });
203
204        carousel.addEventListener('mouseleave', () => {
205            isHovered = false;
206            startAutoplay();
207        });
208
209        // viewport
210        const observer = new IntersectionObserver(entries => {
211            entries.forEach(entry => {
212                isVisible = entry.isIntersecting;
213                if (isVisible) startAutoplay();
214                else stopAutoplay();
215            });
216        }, { threshold: 0.3 });
217
218        observer.observe(carousel);
219
220        // resize
221        let resizeTimeout;
222        window.addEventListener('resize', function () {
223            clearTimeout(resizeTimeout);
224            resizeTimeout = setTimeout(setup, 200);
225        });
226
227        // init
228        setup();
229        startAutoplay();
230
231    });
232
233});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.