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);