site.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /* Public site behavior: hiding navigation + gallery lightbox. Vanilla JS. */
  2. (function () {
  3. 'use strict';
  4. /* ---- Navigation: hide on scroll-down, show on scroll-up ------------- */
  5. var nav = document.getElementById('nav');
  6. if (nav) {
  7. var lastY = window.scrollY;
  8. var onScroll = function () {
  9. var y = window.scrollY;
  10. if (y > lastY && y > 80) {
  11. nav.classList.add('nav-hidden');
  12. } else if (y < lastY - 2 || y <= 80) {
  13. nav.classList.remove('nav-hidden');
  14. }
  15. lastY = y;
  16. };
  17. window.addEventListener('scroll', onScroll, { passive: true });
  18. }
  19. /* ---- Lightbox for gallery pages -------------------------------------
  20. Markup contract: .grid contains <a href="<full-res URL>"><img></a>. */
  21. var grid = document.querySelector('.grid');
  22. if (!grid) return;
  23. var links = Array.prototype.slice.call(grid.querySelectorAll('a'));
  24. if (!links.length) return;
  25. var box = document.createElement('div');
  26. box.className = 'lightbox';
  27. box.innerHTML =
  28. '<button class="lb-close" aria-label="Close">&times;</button>' +
  29. '<button class="lb-prev" aria-label="Previous">&#8249;</button>' +
  30. '<img alt="">' +
  31. '<button class="lb-next" aria-label="Next">&#8250;</button>' +
  32. '<span class="lb-count"></span>';
  33. document.body.appendChild(box);
  34. var img = box.querySelector('img');
  35. var count = box.querySelector('.lb-count');
  36. var current = -1;
  37. function show(i) {
  38. current = (i + links.length) % links.length;
  39. img.src = links[current].href;
  40. count.textContent = (current + 1) + ' / ' + links.length;
  41. box.classList.add('open');
  42. document.body.style.overflow = 'hidden';
  43. }
  44. function close() {
  45. box.classList.remove('open');
  46. img.src = '';
  47. document.body.style.overflow = '';
  48. current = -1;
  49. }
  50. links.forEach(function (a, i) {
  51. a.addEventListener('click', function (e) {
  52. e.preventDefault();
  53. show(i);
  54. });
  55. });
  56. box.querySelector('.lb-close').addEventListener('click', close);
  57. box.querySelector('.lb-prev').addEventListener('click', function () { show(current - 1); });
  58. box.querySelector('.lb-next').addEventListener('click', function () { show(current + 1); });
  59. box.addEventListener('click', function (e) { if (e.target === box) close(); });
  60. document.addEventListener('keydown', function (e) {
  61. if (current < 0) return;
  62. if (e.key === 'Escape') close();
  63. if (e.key === 'ArrowLeft') show(current - 1);
  64. if (e.key === 'ArrowRight') show(current + 1);
  65. });
  66. /* Basic swipe support */
  67. var touchX = null;
  68. box.addEventListener('touchstart', function (e) { touchX = e.touches[0].clientX; }, { passive: true });
  69. box.addEventListener('touchend', function (e) {
  70. if (touchX === null || current < 0) return;
  71. var dx = e.changedTouches[0].clientX - touchX;
  72. if (dx > 50) show(current - 1);
  73. else if (dx < -50) show(current + 1);
  74. touchX = null;
  75. }, { passive: true });
  76. })();