diff options
Diffstat (limited to 'public/js/main.js')
| -rw-r--r-- | public/js/main.js | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/public/js/main.js b/public/js/main.js new file mode 100644 index 0000000..c47a5b8 --- /dev/null +++ b/public/js/main.js @@ -0,0 +1,175 @@ +(() => { + // ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/js/theme-toggle.js + (function() { + const STORAGE_KEY = "danix-theme"; + const DARK_CLASS = "theme-dark"; + const LIGHT_CLASS = "theme-light"; + function init() { + const saved = localStorage.getItem(STORAGE_KEY); + const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; + const isDark = saved === null ? prefersDark : saved === "dark"; + applyTheme(isDark ? "dark" : "light"); + } + function applyTheme(theme) { + const html = document.documentElement; + html.classList.remove(DARK_CLASS, LIGHT_CLASS); + if (theme === "dark") { + html.classList.remove(LIGHT_CLASS); + localStorage.setItem(STORAGE_KEY, "dark"); + } else { + html.classList.add(LIGHT_CLASS); + localStorage.setItem(STORAGE_KEY, "light"); + } + } + function getCurrentTheme() { + return document.documentElement.classList.contains(LIGHT_CLASS) ? "light" : "dark"; + } + function toggleTheme() { + const current = getCurrentTheme(); + const next = current === "dark" ? "light" : "dark"; + applyTheme(next); + window.dispatchEvent(new CustomEvent("theme-changed", { detail: { theme: next } })); + } + function setupToggleButton() { + const btn = document.getElementById("theme-toggle-btn"); + if (btn) { + btn.addEventListener("click", toggleTheme); + updateToggleButtonLabel(); + window.addEventListener("theme-changed", updateToggleButtonLabel); + } + } + function updateToggleButtonLabel() { + const btn = document.getElementById("theme-toggle-btn"); + if (btn) { + const current = getCurrentTheme(); + btn.textContent = current === "dark" ? "\u2600\uFE0F light" : "\u{1F319} dark"; + } + } + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", function() { + init(); + setupToggleButton(); + }); + } else { + init(); + setupToggleButton(); + } + window.ThemeToggle = { + toggle: toggleTheme, + set: applyTheme, + get: getCurrentTheme + }; + })(); + + // ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/js/matrix-rain.js + (function() { + const canvas = document.getElementById("matrix-canvas"); + if (!canvas) return; + if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; + const ctx = canvas.getContext("2d"); + const CHARS = "\u30A2\u30A4\u30A6\u30A8\u30AA\u30AB\u30AD\u30AF\u30B1\u30B3\u30B5\u30B7\u30B9\u30BB\u30BD\u30BF\u30C1\u30C4\u30C6\u30C8\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D2\u30D5\u30D8\u30DB\u30DE\u30DF\u30E0\u30E1\u30E2\u30E4\u30E6\u30E8\u30E9\u30EA\u30EB\u30EC\u30ED\u30EF\u30F2\u30F30123456789ABCDEF<>/\\|{}[]$#@!"; + const FS = 14; + let cols, drops, raf; + function init() { + canvas.width = canvas.offsetWidth; + canvas.height = canvas.offsetHeight; + cols = Math.floor(canvas.width / FS) + 1; + drops = Array.from({ length: cols }, () => Math.random() * -(canvas.height / FS)); + } + function tick() { + const light = document.documentElement.classList.contains("theme-light"); + ctx.fillStyle = light ? "rgba(240,244,248,0.07)" : "rgba(6,11,16,0.055)"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.font = `${FS}px "JetBrains Mono", monospace`; + for (let i = 0; i < cols; i++) { + const char = CHARS[Math.floor(Math.random() * CHARS.length)]; + ctx.fillStyle = Math.random() > 0.96 ? light ? "#008f5a" : "#00ff88" : light ? "#7c3aed" : "#a855f7"; + ctx.fillText(char, i * FS, drops[i] * FS); + if (drops[i] * FS > canvas.height && Math.random() > 0.975) { + drops[i] = Math.random() * -20; + } + drops[i] += 0.5; + } + raf = requestAnimationFrame(tick); + } + window.addEventListener("theme-changed", function() { + }, { passive: true }); + init(); + window.addEventListener("resize", () => { + cancelAnimationFrame(raf); + init(); + tick(); + }, { passive: true }); + document.addEventListener("visibilitychange", () => { + if (document.hidden) { + cancelAnimationFrame(raf); + } else { + tick(); + } + }); + tick(); + window.MatrixRain = { init, tick }; + })(); + + // ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/js/progress-bar.js + (function() { + const progressBar = document.querySelector(".reading-progress"); + if (!progressBar) return; + const mainContent = document.querySelector("main"); + if (!mainContent) return; + function updateProgress() { + const windowHeight = window.innerHeight; + const docHeight = document.documentElement.scrollHeight - windowHeight; + const scrolled = window.scrollY; + const percent = docHeight > 0 ? scrolled / docHeight * 100 : 0; + progressBar.style.width = percent + "%"; + } + const contentHeight = mainContent.offsetHeight; + if (contentHeight > window.innerHeight * 1.5) { + document.body.classList.add("scrollable"); + } + let ticking = false; + window.addEventListener("scroll", function() { + if (!ticking) { + requestAnimationFrame(updateProgress); + ticking = true; + setTimeout(() => { + ticking = false; + }, 100); + } + }, { passive: true }); + updateProgress(); + })(); + + // ns-hugo-imp:/home/danix/Programming/GIT/danix2-hugo-theme/assets/js/copy-code.js + (function() { + const codeBlocks = document.querySelectorAll("pre, .highlight"); + codeBlocks.forEach((block) => { + const btn = document.createElement("button"); + btn.className = "code-copy-btn"; + btn.textContent = "copy"; + btn.type = "button"; + btn.setAttribute("aria-label", "Copy code"); + const code = block.querySelector("code"); + const text = code ? code.textContent : block.textContent; + btn.addEventListener("click", async function() { + try { + await navigator.clipboard.writeText(text); + const originalText = btn.textContent; + btn.textContent = "copied!"; + btn.classList.add("copied"); + setTimeout(() => { + btn.textContent = originalText; + btn.classList.remove("copied"); + }, 2e3); + } catch (err) { + console.error("Failed to copy:", err); + btn.textContent = "error"; + } + }); + block.style.position = "relative"; + block.appendChild(btn); + }); + })(); +})(); +//# sourceMappingURL=main.js.map |
