experimetn galerie

by Petr Haluza

HTML

<div id="bar_before">
  <ul>
    <!--prostor JS-->
  </ul>
</div>
<main onscroll="refreshBars();">
  <ul>
    <li> <img id="img_0" src="https://source.unsplash.com/ezSFnAFi9hY/500x500" alt="" />xx.</li>
    <li> <img id="img_1" src="https://source.unsplash.com/TIGDsyy0TK4/500x500" alt="" />xx.</li>
    <li> <img id="img_2" src="https://source.unsplash.com/TdDtTu2rv4s/500x500" alt="" />xx.</li>
    <li> <img id="img_3" src="https://source.unsplash.com/eudGUrDdBB0/500x500" alt="" />xx.</li>
    <li> <img id="img_4" src="https://source.unsplash.com/eJH4f1rlG7g/500x500" alt="" />xx.</li>
  </ul>
</main>
<div id="bar_after">
  <ul>
    <!--prostor JS-->
  </ul>
</div>

CSS

body { margin: 0; padding: 0;}

main { margin: 0; padding-top: 20vmin; padding-bottom: 20vmin; background: black; color: white; text-align: center; height: calc(100vh - 40vmin); width: 100vw; position: fixed; overflow-y: auto; scroll-behavior: smooth;}
main ul { list-style-type: none; }
main img {  display: block;  height: 60vmin;  margin: auto;   margin-bottom: 10vmin;  margin-top: 10vmin;}
::-webkit-scrollbar {  width: 5vmin;}
::-webkit-scrollbar-track {  background: transparent;}
::-webkit-scrollbar-thumb {  background: radial-gradient(#ccc, white);  border-radius: 2.5vmin;}
::-webkit-scrollbar-thumb:hover {  background: radial-gradient(#888, #ccc);}

main {  scroll-snap-type: y mandatory;  scroll-padding: 10vmin;}
main li {  scroll-snap-align: start;}

#bar_before {  top: 0;}
#bar_after {  bottom: 0;}
#bar_before,
#bar_after {  z-index: 1;  position: fixed;  left: 0;  background: #111111;  width: calc(100vw - 4vmin);  height: 6vmin;  padding: 2vmin;  text-align: center;}
#bar_before ul,
#bar_after ul {  height: 100%;  overflow: hidden;  margin: 0;  padding: 0;  list-style-type: none;  text-align: center;  display: flex; justify-content: center;   width: calc(6vmin * 16 + 1vmin * 15);  margin: auto;}

#bar_before ul li,
#bar_after ul li {  opacity: 1;  margin: 0;  padding: 0;  overflow: hidden;  transition: all 0.5s;}
#bar_before ul li img,
#bar_after ul li img {  height: 100%;  width: 100%;  margin: 0;  padding: 0;  display: block;  transition: all 0.5s;}
#bar_before ul li.hidden,
#bar_after ul li.hidden {  opacity: 0;  pointer-events: none;  transition: all 0.5s;}
#bar_before ul li.hidden img,
#bar_after ul li.hidden img {  margin: 50%;  height: 0;  width: 0;  transition: all 0.5s;}

JavaScript

function whereIs(element) {
  /* Is element visible in viewport? Return "b" if before, "v" if visible and "a" if after */
  const rect = element.getBoundingClientRect();
  if (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <=
      (window.innerHeight || document.documentElement.clientHeight) &&
    rect.right <= (window.innerWidth || document.documentElement.clientWidth)
  )
    return "v"; // Visible
  if (rect.top < 0 || rect.left < 0) return "b"; // Before
  return "a"; // After
}

function loadBars() {
  let imgs = document.querySelectorAll("main img"); // All main images
  let bar_before = document.querySelector("#bar_before ul");
  let bar_after = document.querySelector("#bar_after ul");
  for (let i = 0; i < imgs.length; i++) {
    let img = imgs[i];
    let where_is = whereIs(img);
    /* Append HTML of image to bars */
    bar_before.insertAdjacentHTML(
      "beforeend",
      `<li ${where_is == "b" ? "" : "class='hidden'"} id="bb_${img.id}"> <a href="#${img.id}"><img src="${img.src}" alt="${img.alt}" /></a></li>`
    ); // Add class as hidden if is not before
    bar_after.insertAdjacentHTML(
      "beforeend",
      `<li ${where_is == "a" ? "" : "class='hidden'"} id="ba_${img.id}"> <a href="#${img.id}"><img src="${img.src}" alt="${img.alt}" /></a></li>`
    );
  }
}

window.onload = loadBars; // Load bars on page load

function refreshBars() {
  let imgs = document.querySelectorAll("main img"); // All main images

  /* For each img */
  for (let i = 0; i < imgs.length; i++) {
    let img = imgs[i];
    let where_is = whereIs(img);

    /* Change class of images if needed */
    document.querySelector(`#bb_${img.id}`).className =  where_is == "b" ? "" : "hidden"; // Visible if before current - show on *before* bar
    document.querySelector(`#ba_${img.id}`).className =  where_is == "a" ? "" : "hidden"; // Visible if before current - show on *after* bar
  }
}