1const INTERVAL = 2000;
2const STATE_PAUSE = "⏸︎";
3const STATE_PLAY = "⏵︎";
4
5// Start at -1 - the recursive function playSlideshow() increases this to 0
6// on page load
7let currentSlide = -1;
8
9// Elements
10
11let slideshow = document.getElementsByClassName("slideshow")[0];
12let container = document.getElementsByClassName("slides")[0];
13let slides = document.getElementsByClassName("slide");
14let dots = document.getElementsByClassName("dot");
15let stateBtn = document.getElementById("state");
16let expandBtn = document.getElementById("expand");
17
18// Global state
19let maxIndex = slides.length - 1;
20var timeout;
21var paused = false;
22
23// Set up event listeners
24window.addEventListener("resize", setHeights, true);
25slideshow.addEventListener("mouseenter", mouseEnter, true);
26slideshow.addEventListener("mouseleave", mouseLeave, true);
27document.getElementById("prev").addEventListener("click", prevSlide);
28document.getElementById("next").addEventListener("click", nextSlide);
29document.getElementById("state").addEventListener("click", changeState);
30if (dots.length - 1 != maxIndex) {
31 console.log("Number of control dots does not match number of slides");
32}
33expandBtn.addEventListener("click", expand);
34for (i = 0; i <= dots.length - 1; i++) {
35 dots[i].addEventListener("click", goToSlide);
36 dots[i].slide = i;
37}
38
39
40// Start the slideshow
41playSlideshow();
42
43// Recursive function that advances the slide and then calls itself with a
44// delay
45function playSlideshow() {
46 setHeights();
47 nextSlide();
48 timeout = setTimeout(playSlideshow, INTERVAL);
49}
50
51// Change the slide to a given index
52function setSlide(slide) {
53 if (slide < 0 || slide > maxIndex) {
54 console.log("Attempted to change to slide outside range (" + slide.toString() + ")");
55 return;
56 }
57
58 // Remove active class from figure and dot
59 for (i = 0; i <= maxIndex; i++) {
60 slides[i].className = slides[i].className.replace(" active", "");
61 dots[i].className = dots[i].className.replace(" active", "");
62 }
63
64 // Add active class to figure and dot
65 slides[slide].className += " active";
66 dots[slide].className += " active";
67
68 currentSlide = slide;
69}
70
71function setHeights() {
72 var firstSlideHeight = slides[0].offsetHeight;
73 // Set heights (based on height of first slide with 100% width)
74 for (i = 1; i <= maxIndex; i++) {
75 var captionHeight = slides[i].getElementsByTagName("figcaption")[0].offsetHeight;
76 // Set figure height
77 slides[i].style.maxHeight = slides[0].offsetHeight.toString() + "px";
78 // Set image height
79 slides[i].getElementsByTagName("img")[0].style.maxHeight = (firstSlideHeight - captionHeight).toString() + "px";
80 }
81}
82
83function nextSlide() {
84 // Go to the next slide
85 if (currentSlide == maxIndex) {
86 setSlide(0);
87 }
88 else {
89 setSlide(currentSlide + 1);
90 }
91}
92
93function prevSlide() {
94 // Go to the previous slide
95 if (currentSlide == 0) {
96 setSlide(maxIndex);
97 }
98 else {
99 setSlide(currentSlide - 1);
100 }
101}
102
103function goToSlide(evt) {
104 // Go to a slide specified by the event (called when the dots are clicked)
105 setSlide(evt.currentTarget.slide);
106}
107
108function mouseEnter() {
109 // Pause the slideshow
110 clearTimeout(timeout);
111 timeout = null;
112}
113
114function mouseLeave() {
115 // Start the slideshow if not manually paused
116 if (!paused && timeout == null) {
117 timeout = setTimeout(playSlideshow, INTERVAL);
118 }
119}
120
121function changeState() {
122 if (paused) {
123 // Play immediately despite mouseover
124 stateBtn.innerHTML = STATE_PAUSE;
125 timeout = setTimeout(playSlideshow, INTERVAL);
126 stateBtn.title = "Pause";
127 }
128 else {
129 // Pause until user presses play again
130 clearTimeout(timeout); // make sure timer is stopped
131 timeout = null;
132 stateBtn.innerHTML = STATE_PLAY;
133 stateBtn.title = "Play";
134 }
135 paused = !paused;
136}
137
138function expand() {
139 // Open the image in a new tab
140 window.open(slides[currentSlide].getElementsByTagName('img')[0].src, 'blank');
141}