mirror of
https://github.com/Kugelschieber/schnittfest.git
synced 2026-11-12 09:02:01 +01:00
New design.
This commit is contained in:
+38
-1
@@ -1 +1,38 @@
|
||||
console.log("Hi!");
|
||||
import { initNav } from "./nav.js";
|
||||
import { initReveal } from "./reveal.js";
|
||||
import { initTimecode } from "./timecode.js";
|
||||
|
||||
document.documentElement.classList.add("js");
|
||||
|
||||
const components = {
|
||||
nav: initNav,
|
||||
reveal: initReveal,
|
||||
timecode: initTimecode,
|
||||
};
|
||||
|
||||
function init(root = document) {
|
||||
root.querySelectorAll("[data-component]").forEach((el) => {
|
||||
if (el.dataset.componentReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fn = components[el.dataset.component];
|
||||
|
||||
if (fn) {
|
||||
fn(el);
|
||||
el.dataset.componentReady = "true";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", start);
|
||||
} else {
|
||||
start();
|
||||
}
|
||||
|
||||
function start() {
|
||||
init();
|
||||
// the admin UI swaps element HTML in place after edits
|
||||
new MutationObserver(() => init()).observe(document.body, { childList: true, subtree: true });
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
export function initNav(el) {
|
||||
const toggle = el.querySelector(".nav__toggle");
|
||||
|
||||
if (!toggle) {
|
||||
return;
|
||||
}
|
||||
|
||||
const setOpen = (open) => {
|
||||
el.classList.toggle("nav--open", open);
|
||||
toggle.setAttribute("aria-expanded", String(open));
|
||||
};
|
||||
|
||||
toggle.addEventListener("click", () => setOpen(!el.classList.contains("nav--open")));
|
||||
el.querySelectorAll(".nav__link").forEach((link) => link.addEventListener("click", () => setOpen(false)));
|
||||
el.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape") {
|
||||
setOpen(false);
|
||||
toggle.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
let observer = null;
|
||||
|
||||
function getObserver() {
|
||||
if (!observer) {
|
||||
observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add("is-visible");
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { rootMargin: "0px 0px -8% 0px", threshold: 0.05 });
|
||||
}
|
||||
|
||||
return observer;
|
||||
}
|
||||
|
||||
export function initReveal(el) {
|
||||
if (!("IntersectionObserver" in window)) {
|
||||
el.classList.add("is-visible");
|
||||
return;
|
||||
}
|
||||
|
||||
getObserver().observe(el);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
const FPS = 25;
|
||||
|
||||
function pad(n) {
|
||||
return String(n).padStart(2, "0");
|
||||
}
|
||||
|
||||
export function initTimecode(el) {
|
||||
const start = performance.now();
|
||||
|
||||
const tick = (now) => {
|
||||
if (!el.isConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
const frames = Math.floor(((now - start) / 1000) * FPS);
|
||||
const f = frames % FPS;
|
||||
const s = Math.floor(frames / FPS) % 60;
|
||||
const m = Math.floor(frames / (FPS * 60)) % 60;
|
||||
const h = Math.floor(frames / (FPS * 3600));
|
||||
el.textContent = `${pad(h)}:${pad(m)}:${pad(s)}:${pad(f)}`;
|
||||
requestAnimationFrame(tick);
|
||||
};
|
||||
|
||||
requestAnimationFrame(tick);
|
||||
}
|
||||
Reference in New Issue
Block a user