(function () {
// "hydrate" div.gallery with play/pause and nav behaviors var process_gallery = function (g) { var // milliseconds to wait before switch to next slide NEXT_SLIDE_TIMEOUT = 5000; var // will be resized to the height of currently selected image images_container = g.querySelector('.images'), // images in this gallery images = g.querySelectorAll('.images img'), // container for nav buttons gallery_nav = g.querySelector('nav'), // show all images // computed below preview_nav, // clickable buttons, one per image // computed below navs = [], // index of the currently selected image selected_index = 0, // play control consists of a label and a checkbox // defer computing because nav innerHTML gets clobbered play_checkbox, // handle to setInterval play_interval, play_suspended = false;
/*
+--------+--------+--------+ | image1 | image2 | image3 | | |selected| | +--------+--------+--------+ */ var suspended = function () { return play_suspended || document.hidden || document.msHidden || document.webkitHidden; } var adjust_height = function (index) { images_container.style.height = images[index].offsetHeight + 'px'; }
/*
+----------------------------------------+ | +----------+ +----------+ +----------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +----------+ +----------+ +----------+ | | | | +----------+ +----------+ +----------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +----------+ +----------+ +----------+ | | | | +----------+ +----------+ +----------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +----------+ +----------+ +----------+ | | | | +----------+ +----------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +----------+ +----------+ | +----------------------------------------+ */ var show_preview = function () { var thumb_size = (images_container.offsetWidth - 6*10) / 3; for (var i=0; i<images.length; ++i) { var image = images[i]; if (image.offsetHeight > image.offsetWidth) { console.log('showing tall preview', thumb_size, image.offsetWidth, 'x', image.offsetHeight) image.style.width = thumb_size + 'px'; } else { console.log('showing wide preview', thumb_size, image.offsetWidth, 'x', image.offsetHeight) image.style.height = thumb_size + 'px'; } image.classList.add('thumbnail'); } } // show image at index // update nav controls accordingly var select_image = function (index) { if (selected_index === index) return; var slide = function () { images[selected_index].classList.remove('transition'); images[index].classList.remove('transition'); navs[selected_index].classList.remove('selected'); selected_index = index; } if (suspended()) return; images[selected_index].addEventListener('transitionend', slide, {once: true}); navs[index].classList.add('selected'); if (index < selected_index) { setTimeout(function () { images[index].classList.remove('right'); images[index].classList.add('left'); adjust_height(index); setTimeout(function () { images[index].classList.add('transition'); images[selected_index].classList.add('transition'); images[index].classList.remove('left'); images[index].classList.add('center'); images[selected_index].classList.add('right'); images[selected_index].classList.remove('center'); },1) },1) } else { setTimeout(function () { images[index].classList.remove('left'); images[index].classList.add('right'); adjust_height(index); setTimeout(function () { images[index].classList.add('transition'); images[selected_index].classList.add('transition'); images[index].classList.remove('right'); images[index].classList.add('center'); images[selected_index].classList.add('left'); images[selected_index].classList.remove('center'); },1); },1); } } // show next image var next_image = function () { if (suspended()) return; if (selected_index >= images.length-1) { select_image(0); } else { select_image(selected_index+1); } } // handler for nav buttons // selects an image corresponding to the clicked nav button var nav_to_image = function () { select_image(Array.from(navs).indexOf(this)); } // play/pause slideshow var toggle_play = function () { if (play_checkbox.checked===true) { clearInterval(play_interval); } else { play_interval = setInterval(next_image, NEXT_SLIDE_TIMEOUT); } } // build nav bullets var navHtml = ''; for (var i=0; i<images.length; ++i) { var image = images[i] image.addEventListener('click', next_image) navHtml += '<i class="' + (i===0? 'selected' : '') + '" data-target="' + image.id + '"></i>' } gallery_nav.innerHTML += navHtml; // attach nav bullet listeners navs = gallery_nav.querySelectorAll('i'); for (var i=0; i<navs.length; ++i) { var nav = navs[i]; nav.addEventListener('click', nav_to_image) } // play button play_checkbox = g.querySelector('.play input[type=checkbox]'); play_checkbox.addEventListener('change', toggle_play); // g.querySelector('.preview').addEventListener('click', function () { // show_preview(); // }); window.addEventListener('resize', function () { adjust_height(selected_index); }); // resize image container when initial image loads if (images[selected_index].complete) { adjust_height(selected_index); } else { images[selected_index].addEventListener('load', function () { adjust_height(selected_index); }); images[selected_index].addEventListener('error', function() { console.warn('error loading image', arguments, images[selected_index].src, images[selected_index]) }); } } var galleries = document.getElementsByClassName('gallery'); for (var i=0; i<galleries.length; ++i) { var g = galleries[i]; process_gallery(g); }
})();