Spaces:
Running on Zero
Running on Zero
File size: 3,427 Bytes
c47f9fb 613e06a c47f9fb | 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 | const slides = [...document.querySelectorAll('.slide')];
const counter = document.getElementById('counter');
const bar = document.getElementById('progress-bar');
const overview = document.getElementById('overview');
const scrim = document.getElementById('scrim');
const menu = document.getElementById('menu');
let current = 0;
function closeOverview() {
overview.classList.remove('open');
scrim.classList.remove('open');
overview.setAttribute('aria-hidden', 'true');
menu.setAttribute('aria-expanded', 'false');
}
function openOverview() {
overview.classList.add('open');
scrim.classList.add('open');
overview.setAttribute('aria-hidden', 'false');
menu.setAttribute('aria-expanded', 'true');
}
function show(index, push = true) {
current = Math.max(0, Math.min(slides.length - 1, index));
slides.forEach((slide, i) => slide.classList.toggle('active', i === current));
counter.textContent = `${current + 1} / ${slides.length}`;
bar.style.width = `${(current + 1) / slides.length * 100}%`;
document.querySelectorAll('[data-slide-target]').forEach(link => {
link.classList.toggle('current', link.dataset.slideTarget === slides[current].id);
});
document.title = `${slides[current].dataset.title || ''} · ${document.querySelector('.deck-nav strong').textContent}`;
if (push) history.replaceState(null, '', `#${slides[current].id}`);
slides[current].scrollTo({ top: 0, behavior: 'instant' });
closeOverview();
}
function showById(id) {
const index = slides.findIndex(slide => slide.id === id);
if (index >= 0) show(index);
}
document.getElementById('prev').addEventListener('click', () => show(current - 1));
document.getElementById('next').addEventListener('click', () => show(current + 1));
document.getElementById('print').addEventListener('click', () => window.print());
menu.addEventListener('click', () => overview.classList.contains('open') ? closeOverview() : openOverview());
document.getElementById('close-overview').addEventListener('click', closeOverview);
scrim.addEventListener('click', closeOverview);
document.querySelectorAll('[data-slide-target]').forEach(link => {
link.addEventListener('click', event => {
event.preventDefault();
showById(link.dataset.slideTarget);
});
});
document.querySelectorAll('.source-chips a').forEach(link => {
link.addEventListener('click', event => {
event.preventDefault();
const target = document.querySelector(link.getAttribute('href'));
showById('references');
if (target) requestAnimationFrame(() => target.scrollIntoView({ block: 'center' }));
});
});
document.addEventListener('keydown', event => {
if (event.key === 'Escape') return closeOverview();
if (['ArrowRight', 'PageDown', ' '].includes(event.key)) show(current + 1);
if (['ArrowLeft', 'PageUp'].includes(event.key)) show(current - 1);
if (event.key === 'Home') show(0);
if (event.key === 'End') show(slides.length - 1);
});
let touchStartX = 0;
document.addEventListener('touchstart', event => { touchStartX = event.changedTouches[0].screenX; }, { passive: true });
document.addEventListener('touchend', event => {
const distance = event.changedTouches[0].screenX - touchStartX;
if (Math.abs(distance) > 70) show(current + (distance < 0 ? 1 : -1));
}, { passive: true });
const hashId = location.hash.slice(1);
const initial = slides.findIndex(slide => slide.id === hashId);
show(initial >= 0 ? initial : 0, false);
|