/** * ECOSISTEMA - CARRUSEL * Auto-play con fade, control por tabs, pausa al interactuar, * reanudación al salir completamente del viewport. */ (function () { 'use strict'; const INTERVAL_MS = 5000; const FADE_MS = 600; // debe coincidir con --eco-fade-duration const section = document.querySelector('.ecosystem-section'); if (!section) return; const tabs = Array.from(section.querySelectorAll('.eco-tab')); const slides = Array.from(section.querySelectorAll('.eco-slide')); let currentIndex = 0; let timer = null; let userInteracted = false; // true después de un clic manual // ---------- Utilidades ---------- function goTo(index) { if (index < 0) index = slides.length - 1; if (index >= slides.length) index = 0; // Actualizar slides slides.forEach((slide, i) => { if (i === index) { slide.classList.add('is-active'); slide.removeAttribute('hidden'); } else { slide.classList.remove('is-active'); // Esperamos la transición para ocultar (accesibilidad + rendimiento) setTimeout(() => { if (!slide.classList.contains('is-active')) { slide.setAttribute('hidden', ''); } }, FADE_MS); } }); // Actualizar tabs tabs.forEach((tab, i) => { if (i === index) { tab.classList.add('is-active'); tab.setAttribute('aria-selected', 'true'); // Color activo específico de la capacidad tab.style.backgroundColor = tab.dataset.color; tab.style.borderColor = tab.dataset.color; } else { tab.classList.remove('is-active'); tab.setAttribute('aria-selected', 'false'); // Reset a color inactivo estándar tab.style.backgroundColor = ''; tab.style.borderColor = ''; } }); currentIndex = index; } function next() { goTo(currentIndex + 1); } function startAutoPlay() { stopAutoPlay(); timer = setInterval(next, INTERVAL_MS); } function stopAutoPlay() { if (timer) { clearInterval(timer); timer = null; } } // ---------- Eventos de tabs ---------- tabs.forEach((tab, i) => { tab.addEventListener('click', () => { userInteracted = true; stopAutoPlay(); goTo(i); }); }); // ---------- IntersectionObserver: reanudar al salir del viewport ---------- // "Salir completamente" = cuando la sección ya no intersecta en absoluto. const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (!entry.isIntersecting) { // Salió completamente del viewport userInteracted = false; startAutoPlay(); } else { // Entró al viewport: si el usuario interactuó, mantenemos pausa; // si no, arrancamos el auto-play. if (!userInteracted) { startAutoPlay(); } } }); }, { threshold: 0 } // se dispara cuando la visibilidad cambia de 0 a >0 o viceversa ); observer.observe(section); // ---------- Init ---------- goTo(0); startAutoPlay(); })();