Files
pivoine.art/assets/js/main.js
T

80 lines
2.8 KiB
JavaScript
Raw Normal View History

2026-04-08 19:49:15 +02:00
// ── Pivoine — main.js ─────────────────────────────────────────────
// ── HTMX progress bar ─────────────────────────────────────────────
(function () {
const bar = document.getElementById("progress-bar");
if (!bar) return;
document.body.addEventListener("htmx:beforeRequest", () => {
bar.style.width = "0";
bar.style.opacity = "1";
requestAnimationFrame(() => {
bar.style.width = "55%";
});
});
document.body.addEventListener("htmx:afterSettle", () => {
bar.style.width = "100%";
setTimeout(() => {
bar.style.opacity = "0";
setTimeout(() => { bar.style.width = "0"; }, 350);
}, 150);
});
})();
// ── Lazy-load videos (data-src attribute) ─────────────────────────
function initLazyVideos(root) {
if (!("IntersectionObserver" in window)) return;
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
const video = entry.target;
if (video.dataset.src) {
video.src = video.dataset.src;
video.load();
}
observer.unobserve(video);
});
},
{ rootMargin: "300px" }
);
(root || document).querySelectorAll("video[data-src]").forEach((v) => observer.observe(v));
}
initLazyVideos();
// ── After HTMX partial swap ────────────────────────────────────────
document.body.addEventListener("htmx:afterSwap", (e) => {
initLazyVideos(e.target);
if (window.Alpine) Alpine.initTree(e.target);
window.scrollTo({ top: 0, behavior: "instant" });
});
// ── After HTMX history restore (back / forward navigation) ────────
document.body.addEventListener("htmx:historyRestore", () => {
// Sync nav active state to the restored URL
if (window.Alpine) Alpine.store("nav").path = window.location.pathname;
// Complete the progress bar (htmx:afterSettle never fires on history restore)
const bar = document.getElementById("progress-bar");
if (bar) {
bar.style.width = "100%";
setTimeout(() => {
bar.style.opacity = "0";
setTimeout(() => { bar.style.width = "0"; }, 350);
}, 150);
}
const main = document.getElementById("main-content");
if (!main) return;
if (window.Alpine) Alpine.initTree(main);
// Reload and replay autoplay videos (autoplay attr is ignored on restore)
main.querySelectorAll("video[autoplay]").forEach((v) => {
v.load();
v.play().catch(() => {});
});
window.scrollTo({ top: 0, behavior: "instant" });
});