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