1/* ============================================================ 2 ACU BANNER MATCOM â Banner Slider JS 3 Swiper init + bar navigation + particles management 4 ============================================================ */ 5 6document.addEventListener('DOMContentLoaded', function () { 7 8 const container = document.querySelector('.acu-hero-slider'); 9 if (!container) return; 10 11 const swiperEl = container.querySelector('.acu-swiper'); 12 if (!swiperEl) return; 13 14 /* ---------- Bar Navigation (Genrod style) ---------- */ 15 const barsNav = container.querySelector('.acu-bars-nav'); 16 const totalSlides = barsNav ? parseInt(barsNav.dataset.total, 10) : 0; 17 let autoplayDuration = 6000; 18 19 function buildBars() { 20 if (!barsNav || totalSlides < 1) return; 21 barsNav.innerHTML = ''; 22 for (var i = 0; i < totalSlides; i++) { 23 var bar = document.createElement('div'); 24 bar.className = 'acu-bar-item'; 25 bar.dataset.index = i; 26 bar.innerHTML = '<div class="acu-bar-fill"></div>'; 27 (function(index) { 28 bar.addEventListener('click', function() { 29 acuSwiper.slideToLoop(index); 30 }); 31 })(i); 32 barsNav.appendChild(bar); 33 } 34 // Set first as active 35 var first = barsNav.querySelector('.acu-bar-item'); 36 if (first) first.classList.add('active'); 37 } 38 39 function updateBars(realIndex) { 40 if (!barsNav) return; 41 var items = barsNav.querySelectorAll('.acu-bar-item'); 42 items.forEach(function(item, i) { 43 var fill = item.querySelector('.acu-bar-fill'); 44 item.classList.remove('active'); 45 fill.style.transition = 'none'; 46 47 if (i < realIndex) { 48 // Past slides: filled 49 fill.style.width = '100%'; 50 } else if (i === realIndex) { 51 // Active: start from 0 52 item.classList.add('active'); 53 fill.style.width = '0%'; 54 } else { 55 // Future: empty 56 fill.style.width = '0%'; 57 } 58 }); 59 } 60 61 function updateBarFill(percentage) { 62 if (!barsNav) return; 63 var activeItem = barsNav.querySelector('.acu-bar-item.active'); 64 if (!activeItem) return; 65 var fill = activeItem.querySelector('.acu-bar-fill'); 66 fill.style.transition = 'none'; 67 fill.style.width = (percentage * 100) + '%'; 68 } 69 70 /* ---------- Swiper Init ---------- */ 71 var acuSwiper = new Swiper(swiperEl, { 72 effect: 'creative', 73 creativeEffect: { 74 prev: { 75 translate: ['-30%', 0, -200], 76 opacity: 0, 77 }, 78 next: { 79 translate: ['100%', 0, 0], 80 opacity: 1, 81 }, 82 }, 83 speed: 900, 84 loop: true, 85 grabCursor: true, 86 autoplay: { 87 delay: autoplayDuration, 88 disableOnInteraction: false, 89 pauseOnMouseEnter: true, 90 }, 91 navigation: { 92 prevEl: '.acu-nav-prev', 93 nextEl: '.acu-nav-next', 94 }, 95 on: { 96 init: function () { 97 buildBars(); 98 updateSlideTheme(this); 99 handleSlideParticles(this); 100 }, 101 slideChangeTransitionStart: function () { 102 updateSlideTheme(this); 103 updateBars(this.realIndex); 104 }, 105 slideChangeTransitionEnd: function () { 106 handleSlideParticles(this); 107 }, 108 autoplayTimeLeft: function (swiper, timeLeft, percentage) { 109 updateBarFill(1 - percentage); 110 }, 111 }, 112 }); 113 114 /* ---------- Theme update on slide change ---------- */ 115 function updateSlideTheme(swiper) { 116 var activeSlide = swiper.slides[swiper.activeIndex]; 117 if (!activeSlide) return; 118 119 // Update nav arrows for light slides 120 var navBtns = container.querySelectorAll('.acu-nav'); 121 var isLight = activeSlide.classList.contains('slide-categorias'); 122 123 navBtns.forEach(function(btn) { 124 if (isLight) { 125 btn.style.background = 'rgba(0,0,0,0.08)'; 126 btn.style.borderColor = 'rgba(0,0,0,0.1)'; 127 btn.style.color = '#333'; 128 } else { 129 btn.style.background = ''; 130 btn.style.borderColor = ''; 131 btn.style.color = ''; 132 } 133 }); 134 } 135 136 /* ---------- Particles management (Swiper loop safe) ---------- */ 137 var _pUid = 0; 138 139 /** 140 * Ensure the element has a unique id (avoids Swiper loop duplicate IDs). 141 */ 142 function ensureUniqueId(el, prefix) { 143 if (!el._acuUid) { 144 el._acuUid = prefix + '-' + (++_pUid) + '-' + Date.now(); 145 } 146 el.id = el._acuUid; 147 return el._acuUid; 148 } 149 150 /** 151 * Init or resume particles/sparks on the given slide element. 152 */ 153 function initOrPlaySlideParticles(slide) { 154 if (!slide) return; 155 156 // ââ Main particles ââ 157 var pDiv = slide.querySelector('.acu-particles-container');
158 if (pDiv && slide.getAttribute('data-bg-type') === 'particles') { 159 if (pDiv._acuInstance) { 160 // Already initialised â just resume 161 if (pDiv._acuInstance.play) pDiv._acuInstance.play(); 162 } else if (typeof window.acuInitParticles === 'function') { 163 var pid = ensureUniqueId(pDiv, 'acu-p'); 164 var color = getComputedStyle(slide).getPropertyValue('--slide-primary').trim() || '#F4812B'; 165 window.acuInitParticles(pid, color, pDiv).then(function (inst) { 166 if (inst) pDiv._acuInstance = inst; 167 }); 168 } 169 } 170 171 // ââ Sparks layer (hero only) ââ 172 var sDiv = slide.querySelector('.acu-sparks-layer'); 173 if (sDiv) { 174 if (sDiv._acuInstance) { 175 if (sDiv._acuInstance.play) sDiv._acuInstance.play(); 176 } else if (typeof window.acuInitSparks === 'function') { 177 var sid = ensureUniqueId(sDiv, 'acu-s'); 178 var sc = getComputedStyle(slide).getPropertyValue('--slide-primary').trim() || '#F4812B'; 179 window.acuInitSparks(sid, sc, sDiv).then(function (inst) { 180 if (inst) sDiv._acuInstance = inst; 181 }); 182 } 183 } 184 } 185 186 /** 187 * Pause particles/sparks on a given slide element. 188 */ 189 function pauseSlideParticles(slide) { 190 if (!slide) return; 191 var pDiv = slide.querySelector('.acu-particles-container'); 192 if (pDiv && pDiv._acuInstance && pDiv._acuInstance.pause) pDiv._acuInstance.pause(); 193 var sDiv = slide.querySelector('.acu-sparks-layer'); 194 if (sDiv && sDiv._acuInstance && sDiv._acuInstance.pause) sDiv._acuInstance.pause(); 195 } 196 197 /** 198 * Master handler â play on active slide, pause on others. 199 */ 200 function handleSlideParticles(swiper) { 201 var activeSlide = swiper.slides[swiper.activeIndex]; 202 203 // Pause all non-active slides 204 for (var i = 0; i < swiper.slides.length; i++) { 205 if (i !== swiper.activeIndex) { 206 pauseSlideParticles(swiper.slides[i]); 207 } 208 } 209 210 // Init / play on active slide 211 initOrPlaySlideParticles(activeSlide); 212 } 213 214 /* ---------- Keyboard nav ---------- */ 215 document.addEventListener('keydown', function (e) { 216 if (e.key === 'ArrowLeft') acuSwiper.slidePrev(); 217 if (e.key === 'ArrowRight') acuSwiper.slideNext(); 218 }); 219 220});
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.