Skip to content

Instantly share code, notes, and snippets.

@laurent-dinh
Created February 10, 2024 19:15
Show Gist options
  • Select an option

  • Save laurent-dinh/7e787c231494bf7046074e046c156ac3 to your computer and use it in GitHub Desktop.

Select an option

Save laurent-dinh/7e787c231494bf7046074e046c156ac3 to your computer and use it in GitHub Desktop.
Gallery
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<!-- load fontawesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/fontawesome.min.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/solid.min.css">
<style type="text/css">
body {
margin: 0px;
padding: 0px;
}
#container {
margin: 0px;
padding: 0px;
height: 100vh;
width: 100vw;
overflow: auto;
scroll-snap-type: y mandatory;
background-color: black;
position:absolute;
overflow-x: hidden;
}
.hidden {
display: none;
}
#icons {
width: 100px;
height: 50px;
font-size: 30px;
padding: 5px;
text-align: center;
color: white;
position: fixed;
z-index: 10;
}
#icons a {
color: white;
}
#icons a {
opacity: .75;
cursor: pointer;
}
#icons a:hover {
opacity: 1;
}
section {
margin: 0px;
padding: 0px;
border: 0px solid white;
height: 100vh;
width: 100vw;
scroll-snap-align: start;
position: absolute;
background-image: url("imgs/loading.svg");
background-repeat: no-repeat;
background-position: center;
background-size: 25%;
}
img {
height: 100vh;
width: 100vw;
position: absolute;
top: 0px;
left: 0px;
}
img.foreground {
object-fit: contain;
z-index: 10;
}
img.background {
object-fit: cover;
z-index: 7;
opacity: 0.75;
}
</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
</head>
<body>
<div id="icons"><a onclick="toggleShuffle()"><i class="fas fa-random"></i></a> <a id="gallery-link"><i class="fas fa-compress-arrows-alt"></i></a></div>
<div id="container">
<section id="phantom"></section>
<div id="sentinel"></div>
</div>
</body>
<script type="text/javascript">
var vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);
window.onresize = (event) => {vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0);}
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
}
function shuffle(array) {
array.sort(() => (Math.random() - 0.5));
}
function shuffled(array) {
return array.toSorted(() => (Math.random() - 0.5));
}
const n_div = 23;
const container = document.getElementById("container");
for (let i = 0; i < n_div; i++) {
var section = document.createElement("section");
section.style.top = Number.parseFloat(i * 100).toFixed(0) + "vh";
section.id = "section-" + i;
var img = document.createElement("img");
img.setAttribute("class", "foreground");
section.appendChild(img);
var img = document.createElement("img");
img.setAttribute("class", "background");
section.appendChild(img);
container.appendChild(section);
}
create list
const images_orig = [];
const n_images = images_orig.length;
const sentinel = document.getElementById("sentinel");
sentinel.style.width = "100vw";
sentinel.style.height = "1px";
sentinel.style.position = "absolute";
sentinel.style.top = Number.parseFloat((n_images) * 100).toFixed(0) + "vh";
var shuffling;
try {
shuffling = (/true/i).test(localStorage.getItem("shuffle"));
}
catch(e) {
shuffling = false;
}
localStorage.setItem("shuffle", shuffling);
var images = images_orig;
function setIcon() {
var icon = document.getElementById("icons").children[0].children[0];
if (shuffling) {
icon.setAttribute("class", "fas fa-sort");
images = shuffled(images_orig);
} else {
icon.setAttribute("class", "fas fa-random");
images = images_orig;
}
localStorage.setItem("shuffle", shuffling);
}
setIcon();
function toggleShuffle() {
shuffling = !shuffling;
setIcon();
setPagePos();
updatePageIndex();
}
const phantom = document.getElementById("phantom");
phantom.style.top = Number.parseFloat(page_pos * 100).toFixed(0) + "vh";
phantom.style["z-index"] = 0;
var page_pos;
function setPagePos() {
if (images.findIndex((filename_) => filename_ == decodeURI(getQueryVariable("filename"))) >= 0) {
// check filename
page_pos = images.findIndex((filename_) => filename_ == decodeURI(getQueryVariable("filename")));
} else if (getQueryVariable("page") >= 0) {
// check position
page_pos = getQueryVariable("page");
} else {
page_pos = 0;
}
updatePages(page_pos);
container.scrollTo(0, page_pos * vh);
}
setPagePos();
updatePageIndex();
const sections = [].slice.call(document.getElementsByTagName("section")).toSorted(function(a, b){return a.id > b.id});;
function getCurrentPage() {
return Math.floor($("#container").scrollTop() / vh + .5);
}
function updatePageIndex() {
window.history.replaceState(null, null, `?${$.param({
filename: images[getCurrentPage()]
})}`);
}
function getImageIndex(page_value, id_value, post_bound) {
return Math.floor((page_value + post_bound - id_value) / n_div) * n_div + id_value
}
function updatePages(page_value) {
var pre_bound = Math.floor((n_div - 1) / 2);
var post_bound = Math.ceil((n_div - 1) / 2);
var clipped_page_value = Math.max(pre_bound, Math.min(page_value, n_images - post_bound - 1));
for (let i = 0; i < n_div; i++) {
var section = document.getElementById("section-" + i);
if (page_value % n_div == i) {
section.style["z-index"] = 3;
}
else {
section.style["z-index"] = 2;
}
section.style.top = Number.parseFloat(getImageIndex(clipped_page_value, i, post_bound) * 100).toFixed(0) + "vh";
section.children[0].setAttribute("src", "imgs/" + images[getImageIndex(clipped_page_value, i, post_bound)]);
section.children[1].setAttribute("src", "imgs/" + images[getImageIndex(clipped_page_value, i, post_bound)]);
}
var galleryLink = document.getElementById("gallery-link");
galleryLink.setAttribute("href", "gallery.html?filename=" + images[page_value]);
}
var timeout = Date.now();
function scrollFunction() {
currentTime = Date.now();
if (Math.abs(($("#container").scrollTop() / vh )% 1) < .1) {
updatePageIndex();
}
if ((currentTime - timeout) > 1000) {
updatePages(getCurrentPage());
timeout = currentTime;
}
}
function hideImgs(event) {
if (event.key == "m") {
for (let i = 0; i < n_div; i++) {
var section = document.getElementById("section-" + i);
if (section.children[0].getAttribute("style") == "display: none;") {
section.children[0].removeAttribute("style");
section.children[1].removeAttribute("style");
} else {
section.children[0].setAttribute("style", "display: none;");
section.children[1].setAttribute("style", "display: none;");
}
}
} else {
scrollFunction();
}
}
container.setAttribute("onscroll", "scrollFunction();");
window.onkeydown = hideImgs;
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment