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
}
}