| |
| |
| |
| |
|
|
| (function () { |
| 'use strict'; |
|
|
| |
| let currentSlide = 1; |
| const totalSlides = 10; |
| let isAnimating = false; |
|
|
| |
| const progressFill = document.getElementById('progressFill'); |
| const currentSlideEl = document.getElementById('currentSlide'); |
| const totalSlidesEl = document.getElementById('totalSlides'); |
| const prevBtn = document.getElementById('prevBtn'); |
| const nextBtn = document.getElementById('nextBtn'); |
| const slides = document.querySelectorAll('.slide'); |
|
|
| |
| function init() { |
| totalSlidesEl.textContent = totalSlides; |
| updateUI(1); |
| bindEvents(); |
| handleHash(); |
| } |
|
|
| |
| function bindEvents() { |
| prevBtn.addEventListener('click', goToPrev); |
| nextBtn.addEventListener('click', goToNext); |
| document.addEventListener('keydown', handleKeyDown); |
|
|
| |
| let touchStartX = 0; |
| document.addEventListener('touchstart', e => { |
| touchStartX = e.changedTouches[0].screenX; |
| }, { passive: true }); |
|
|
| document.addEventListener('touchend', e => { |
| const diff = touchStartX - e.changedTouches[0].screenX; |
| if (Math.abs(diff) > 50) { |
| diff > 0 ? goToNext() : goToPrev(); |
| } |
| }, { passive: true }); |
|
|
| |
| let wheelLock = false; |
| document.addEventListener('wheel', e => { |
| if (wheelLock) return; |
| wheelLock = true; |
| setTimeout(() => { wheelLock = false; }, 800); |
| e.deltaY > 0 ? goToNext() : goToPrev(); |
| }, { passive: true }); |
| } |
|
|
| |
| function handleKeyDown(e) { |
| switch (e.key) { |
| case 'ArrowRight': |
| case ' ': |
| case 'Enter': |
| e.preventDefault(); |
| goToNext(); |
| break; |
| case 'ArrowLeft': |
| case 'Backspace': |
| e.preventDefault(); |
| goToPrev(); |
| break; |
| case 'Home': |
| e.preventDefault(); |
| goToSlide(1); |
| break; |
| case 'End': |
| e.preventDefault(); |
| goToSlide(totalSlides); |
| break; |
| } |
|
|
| |
| const num = parseInt(e.key); |
| if (!isNaN(num) && num >= 1 && num <= Math.min(totalSlides, 9)) { |
| goToSlide(num); |
| } |
| } |
|
|
| |
| function goToNext() { |
| if (currentSlide < totalSlides && !isAnimating) goToSlide(currentSlide + 1); |
| } |
|
|
| function goToPrev() { |
| if (currentSlide > 1 && !isAnimating) goToSlide(currentSlide - 1); |
| } |
|
|
| function goToSlide(n) { |
| if (n === currentSlide || n < 1 || n > totalSlides || isAnimating) return; |
|
|
| isAnimating = true; |
| currentSlide = n; |
|
|
| slides.forEach((slide, i) => { |
| const num = i + 1; |
| slide.classList.remove('active', 'prev'); |
|
|
| if (num === currentSlide) { |
| slide.classList.add('active'); |
| triggerAnimations(slide); |
| } else if (num < currentSlide) { |
| slide.classList.add('prev'); |
| } |
| }); |
|
|
| updateUI(currentSlide); |
| setTimeout(() => { isAnimating = false; }, 500); |
| } |
|
|
| |
| function updateUI(n) { |
| currentSlideEl.textContent = n; |
| progressFill.style.width = `${(n / totalSlides) * 100}%`; |
|
|
| prevBtn.style.opacity = n === 1 ? '0.3' : '1'; |
| prevBtn.style.pointerEvents = n === 1 ? 'none' : 'auto'; |
| nextBtn.style.opacity = n === totalSlides ? '0.3' : '1'; |
| nextBtn.style.pointerEvents = n === totalSlides ? 'none' : 'auto'; |
|
|
| history.replaceState(null, null, `#slide-${n}`); |
| } |
|
|
| |
| function triggerAnimations(slide) { |
| const els = slide.querySelectorAll('.agenda-item, [style*="--delay"]'); |
| els.forEach(el => { |
| el.style.animation = 'none'; |
| void el.offsetHeight; |
| el.style.animation = null; |
| }); |
| } |
|
|
| |
| function handleHash() { |
| const hash = window.location.hash; |
| if (hash && hash.startsWith('#slide-')) { |
| const n = parseInt(hash.replace('#slide-', '')); |
| if (n >= 1 && n <= totalSlides) goToSlide(n); |
| } |
| } |
|
|
| window.addEventListener('hashchange', handleHash); |
|
|
| |
| window.PresentationAPI = { |
| next: goToNext, |
| prev: goToPrev, |
| goTo: goToSlide, |
| getCurrentSlide: () => currentSlide, |
| getTotalSlides: () => totalSlides |
| }; |
|
|
| |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', init); |
| } else { |
| init(); |
| } |
|
|
| })(); |
|
|