up/docs/javascripts/extra.js

114 lines
3.1 KiB
JavaScript
Raw Normal View History

/**
* Godspark Refined Zensical Light JS
* - Scroll reveal for `.gp-reveal`
* - Cursor glow via `[gp-glow]` attribute
* - Reduced-motion safe
*/
;(function () {
"use strict";
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
).matches;
function initScrollReveal() {
if (prefersReducedMotion) return;
const nodes = document.querySelectorAll(".gp-reveal");
if (!nodes.length) return;
const thresholdRaw = getComputedStyle(document.documentElement)
.getPropertyValue("--gp-reveal-threshold")
.trim();
const threshold = Number.isFinite(parseFloat(thresholdRaw))
? parseFloat(thresholdRaw)
: 0.12;
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("is-visible");
observer.unobserve(entry.target);
}
});
},
{ threshold, rootMargin: "0px 0px -16px 0px" }
);
nodes.forEach((el) => observer.observe(el));
}
function initCursorGlow() {
const el = document.documentElement;
const enabled =
el.hasAttribute("gp-glow") || el.classList.contains("gp-glow-active");
if (!enabled) return;
if (prefersReducedMotion) return;
el.classList.add("gp-glow-active");
let raf = false;
function setGlow(x, y) {
el.style.setProperty("--gp-cursor-x", x + "px");
el.style.setProperty("--gp-cursor-y", y + "px");
}
function onMove(e) {
if (raf) return;
raf = true;
requestAnimationFrame(() => {
const cx = e.touches ? e.touches[0].clientX : e.clientX;
const cy = e.touches ? e.touches[0].clientY : e.clientY;
setGlow(cx, cy);
raf = false;
});
}
function onHide() { el.style.setProperty("--gp-glow-opacity", "0"); }
function onShow() { el.style.setProperty("--gp-glow-opacity", "1"); }
const passive = { passive: true };
document.addEventListener("mousemove", onMove, passive);
document.addEventListener("touchmove", onMove, passive);
document.addEventListener("mouseleave", onHide);
document.addEventListener("mouseenter", onShow);
}
function boot() {
initScrollReveal();
initCursorGlow();
initCusdisReload();
}
/**
* Re-initialize Cusdis comment widget after Zensical instant-navigation
* page transitions (XHR-based SPA navigation). Without this, the widget
* only renders on hard-refresh / initial page load.
*/
function initCusdisReload() {
if (typeof document$ === "undefined") return; // not in Zensical context
document$.subscribe(function () {
var el = document.getElementById("cusdis_thread");
if (!el) return;
// Clear stale Cusdis iframe from previous page render
el.innerHTML = "";
// Re-create Cusdis widget for the new page
if (window.CUSDIS && typeof window.CUSDIS.renderTo === "function") {
window.CUSDIS.renderTo(el);
}
});
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", boot);
} else {
boot();
}
})();