From d42e519cc644be9d5190ef5464b461cfcf910df5 Mon Sep 17 00:00:00 2001 From: alufers Date: Fri, 10 May 2024 01:03:26 +0200 Subject: [PATCH] Add image enlarging --- README.md | 4 ++ assets/js/common.js | 152 ++++++++++++++++++++++++++++++++++++------ content/at/index.html | 109 +++++++++++++++++++++--------- 3 files changed, 211 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 591e8ee..4841a3d 100644 --- a/README.md +++ b/README.md @@ -19,3 +19,7 @@ Alternatively you can just `docker-compose up` and visit `http://localhost:1313` - `layouts/partials/sponsors.html` - Sponsors - `assets/` - CSS, JS, images, etc. - `hugo.yaml` - Site configuration, main menu lives here + +## Tips + +Add the `img-popup-trigger` class to an image to make it open a popup with a larger version of the image when clicked. diff --git a/assets/js/common.js b/assets/js/common.js index 1ff17ee..c913db7 100644 --- a/assets/js/common.js +++ b/assets/js/common.js @@ -1,30 +1,140 @@ -var lastScrollY = window.scrollY; -var documentElement = document.documentElement; +(() => { + // hellpers + const $$ = document.querySelectorAll.bind(document); + const $ = document.querySelector.bind(document); + const on = (elements, event, handler) => { + if (!Array.isArray(elements) && !(elements instanceof NodeList)) { + elements = [elements]; + } + elements.forEach((element) => { + element.addEventListener(event, handler); + }); + }; -function storeScrollData() { - var y = window.scrollY; + // hide scroll bar when scrolling down + let lastScrollY = window.scrollY; + const documentElement = document.documentElement; + function storeScrollData() { + var y = window.scrollY; + documentElement.setAttribute("data-header-transparent", ""); - documentElement.setAttribute("data-header-transparent", ""); + var scrollStatus = ""; + if (y <= 0) { + scrollStatus = "top"; + } else if (window.innerHeight + y >= document.body.offsetHeight) { + scrollStatus = "bottom"; + } else { + var isScrollDown = y - lastScrollY > 0 ? true : false; + scrollStatus = isScrollDown ? "down" : "up"; + } - var scrollStatus = ""; - - if (y <= 0) { - scrollStatus = "top"; - } else if ((window.innerHeight + y) >= document.body.offsetHeight) { - scrollStatus = "bottom"; - } else { - var isScrollDown = (y - lastScrollY > 0) ? true : false; - scrollStatus = isScrollDown ? "down" : "up"; + lastScrollY = y; + documentElement.setAttribute("data-scroll-status", scrollStatus); } + on(window, "scroll", storeScrollData); + storeScrollData(); - lastScrollY = y; - documentElement.setAttribute("data-scroll-status", scrollStatus); -} + // image popup + let popupIdCounter = 0; + $$(".img-popup-trigger").forEach((trigger) => { + if (!trigger.id) { + const srcId = trigger.src + .split("/") + .pop() + .split(".")[0] + .replace(/[^a-zA-Z0-9]/g, ""); + trigger.id = "img-" + srcId + "-" + popupIdCounter++; + } + }); + on($$(".img-popup-trigger"), "click", function (e) { + const backdrop = document.createElement("div"); + const backdropStyle = backdrop.style; + backdropStyle.position = "fixed"; + backdropStyle.top = "0"; + backdropStyle.left = "0"; + backdropStyle.right = "0"; + backdropStyle.bottom = "0"; + backdropStyle.backgroundColor = "rgba(0, 0, 0, 0)"; + backdropStyle.zIndex = "9999"; + backdropStyle.display = "flex"; + backdropStyle.justifyContent = "center"; + backdropStyle.alignItems = "center"; + backdropStyle.transition = "background-color 0.4s, opacity 0.4s"; -window.addEventListener('scroll', function(e) { - storeScrollData(); -}); + const enlargedImage = document.createElement("img"); + const enlargedImageStyle = enlargedImage.style; + enlargedImageStyle.width = "90vw"; + enlargedImageStyle.height = "90vh"; + enlargedImageStyle.objectFit = "contain"; + + enlargedImage.src = e.target.src; + enlargedImage.alt = e.target.alt; + enlargedImageStyle.opacity = "0"; + backdrop.appendChild(enlargedImage); + + const transitionImage = document.createElement("img"); + const transitionImageStyle = transitionImage.style; + transitionImageStyle.position = "fixed"; + const setTransitionImageToRect = function (rect) { + transitionImageStyle.top = rect.top + "px"; + transitionImageStyle.left = rect.left + "px"; + transitionImageStyle.width = rect.width + "px"; + transitionImageStyle.height = rect.height + "px"; + }; + setTransitionImageToRect(e.target.getBoundingClientRect()); + transitionImage.src = e.target.src; + transitionImage.alt = e.target.alt; + transitionImageStyle.transitionDuration = "0.4s"; + transitionImageStyle.transitionProperty = "top, left, width, height"; + transitionImageStyle.transitionTimingFunction = "ease-in-out"; + transitionImageStyle.objectFit = "contain"; + + backdrop.appendChild(transitionImage); + + // hide original image + e.target.style.opacity = "0"; + + // watch the original image for src changes + const observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + if (mutation.attributeName === "src") { + enlargedImage.src = e.target.src; + transitionImage.src = e.target.src; + } + }); + }); + observer.observe(e.target, { attributes: true }); + + let windowEventListener = null; + const hidePopup = function () { + backdropStyle.backgroundColor = "rgba(0, 0, 0, 0)"; + setTransitionImageToRect(e.target.getBoundingClientRect()); + enlargedImageStyle.opacity = "0"; + transitionImageStyle.opacity = "1"; + setTimeout(() => { + backdrop.remove(); + observer.disconnect(); + e.target.style.opacity = "1"; + }, 400); + window.removeEventListener("keydown", windowEventListener); + }; + on(backdrop, "click", hidePopup); + windowEventListener = window.addEventListener("keydown", (e) => { + if (e.key === "Escape") { + hidePopup(); + } + }); + document.body.appendChild(backdrop); -storeScrollData(); + setTimeout(() => { + setTransitionImageToRect(enlargedImage.getBoundingClientRect()); + backdropStyle.backgroundColor = "rgba(0, 0, 0, 0.9)"; + setTimeout(() => { + enlargedImageStyle.opacity = "1"; + transitionImageStyle.opacity = "0"; + }, 400); + }, 1); + }); +})(); diff --git a/content/at/index.html b/content/at/index.html index 4f1459e..5d0f93a 100644 --- a/content/at/index.html +++ b/content/at/index.html @@ -5,41 +5,84 @@ ---
- -
-
-

Hardroom

- Widok na hardroom -
- -
-

Lab elektro

- Widok na lab elektroniczny -
+
+
+

Hardroom

+ Widok na hardroom
- -
-
-

Korytarz

- Widok na korytarz -
- + +
+

Lab elektro

+ Widok na lab elektroniczny
-
-
-

Magazynek

- Widok na magazynek -
-
-

Softroom

- Widok na softroom -
- +
+ +
+
+

Korytarz

+ Widok na korytarz
- -
- - +
+
+

Magazynek

+ Widok na magazynek +
+
+

Softroom

+ Widok na softroom +
- \ No newline at end of file +
+ +
+ + +
+ +