Spaces:
Running
Running
File size: 4,978 Bytes
7a6dc7c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | /* Slide Deck 16:9 Controller */
(function () {
const container = document.getElementById('slideContainer');
const slides = Array.from(container.querySelectorAll('.slide'));
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const dotsWrap = document.getElementById('dots');
const progressBar = document.getElementById('progressBar');
const themeToggle = document.getElementById('themeToggle');
const fullscreenBtn = document.getElementById('fullscreenBtn');
const replayBtn = document.getElementById('replayBtn');
const copyBtn = document.getElementById('copyCode');
const codeSample = document.getElementById('codeSample');
const state = {
index: 0,
total: slides.length
};
// Build dots
slides.forEach((_, i) => {
const dot = document.createElement('button');
dot.className = 'dot' + (i === 0 ? ' is-active' : '');
dot.setAttribute('role', 'tab');
dot.setAttribute('aria-label', `Ir para slide ${i + 1}`);
dot.addEventListener('click', () => goTo(i));
dotsWrap.appendChild(dot);
});
const dots = Array.from(dotsWrap.querySelectorAll('.dot'));
function updateUI() {
slides.forEach((s, i) => s.classList.toggle('is-active', i === state.index));
dots.forEach((d, i) => d.classList.toggle('is-active', i === state.index));
prevBtn.disabled = state.index === 0;
nextBtn.disabled = state.index === state.total - 1;
progressBar.style.width = `${((state.index + 1) / state.total) * 100}%`;
// Announce for a11y
const activeSlide = slides[state.index];
activeSlide?.setAttribute('aria-label', `Slide ${state.index + 1} de ${state.total}`);
}
function next() {
if (state.index < state.total - 1) {
state.index++;
updateUI();
}
}
function prev() {
if (state.index > 0) {
state.index--;
updateUI();
}
}
function goTo(i) {
state.index = Math.max(0, Math.min(state.total - 1, i));
updateUI();
}
// Events
nextBtn.addEventListener('click', next);
prevBtn.addEventListener('click', prev);
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowRight' || e.key === 'PageDown') {
e.preventDefault();
next();
} else if (e.key === 'ArrowLeft' || e.key === 'PageUp') {
e.preventDefault();
prev();
} else if (e.key === 'Home') {
e.preventDefault();
goTo(0);
} else if (e.key === 'End') {
e.preventDefault();
goTo(state.total - 1);
}
});
// Touch swipe
let touchStartX = null;
container.addEventListener('touchstart', (e) => {
touchStartX = e.changedTouches[0].clientX;
}, { passive: true });
container.addEventListener('touchend', (e) => {
if (touchStartX === null) return;
const dx = e.changedTouches[0].clientX - touchStartX;
if (Math.abs(dx) > 40) {
dx < 0 ? next() : prev();
}
touchStartX = null;
}, { passive: true });
// Theme toggle (undefined mode -> light by default)
themeToggle.addEventListener('click', () => {
const wrapper = document.querySelector('.theme-wrapper');
wrapper.classList.toggle('dark');
themeToggle.innerHTML = wrapper.classList.contains('dark')
? '<i data-feather="moon"></i>'
: '<i data-feather="sun"></i>';
if (window.feather) feather.replace();
});
// Fullscreen
function toggleFullscreen() {
const elem = document.documentElement;
if (!document.fullscreenElement) {
(elem.requestFullscreen || elem.webkitRequestFullscreen || elem.msRequestFullscreen)?.call(elem);
} else {
(document.exitFullscreen || document.webkitExitFullscreen || document.msExitFullscreen)?.call(document);
}
}
fullscreenBtn.addEventListener('click', toggleFullscreen);
document.addEventListener('fullscreenchange', () => {
fullscreenBtn.innerHTML = document.fullscreenElement
? '<i data-feather="minimize"></i>'
: '<i data-feather="maximize"></i>';
if (window.feather) feather.replace();
});
// Replay / CTA shortcuts
document.getElementById('startSlides')?.addEventListener('click', () => goTo(1));
document.getElementById('viewSamples')?.addEventListener('click', () => goTo(2));
document.getElementById('replayBtn')?.addEventListener('click', () => goTo(0));
document.getElementById('contactBtn')?.addEventListener('click', (e) => {
e.preventDefault();
alert('Obrigado! Vamos conversarei em breve.');
});
// Copy code
copyBtn?.addEventListener('click', async () => {
try {
await navigator.clipboard.writeText(codeSample?.textContent || '');
copyBtn.innerHTML = '<i data-feather="check"></i>';
if (window.feather) feather.replace();
setTimeout(() => {
copyBtn.innerHTML = '<i data-feather="copy"></i>';
if (window.feather) feather.replace();
}, 1200);
} catch (_) {}
});
// Init icons and UI
if (window.feather) feather.replace();
updateUI();
})(); |