From dc921b5f585f722ac8ccaf7b08703f16c9c3c137 Mon Sep 17 00:00:00 2001 From: debuggingfuture Date: Sat, 16 May 2026 02:12:34 +0800 Subject: [PATCH] feat: random Julia set init and scroll-driven morphing on mobile On viewports < 768px, initialize the Julia set with a random coordinate from a curated list of visually interesting constants. As the user scrolls, smoothly interpolate between presets so the fractal background evolves with the page. Desktop behavior unchanged. --- src/components/JuliaBackground.astro | 52 ++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/src/components/JuliaBackground.astro b/src/components/JuliaBackground.astro index 6ee1507..d11b748 100644 --- a/src/components/JuliaBackground.astro +++ b/src/components/JuliaBackground.astro @@ -31,19 +31,57 @@ document.addEventListener("DOMContentLoaded", () => { window.addEventListener("resize", resize); resize(); - // Default constants for the Julia set. - // We'll update these based on the mouse position. - let c_real = -0.7; - let c_imag = 0.27015; + const INTERESTING_COORDS = [ + [-0.7, 0.27015], + [-0.8, 0.156], + [0.285, 0.01], + [-0.4, 0.6], + [0.355, 0.355], + [-0.54, 0.54], + [0.34, -0.05], + [-0.12, -0.77], + ]; + + const isMobile = window.innerWidth < 768; + + let c_real, c_imag; + + if (isMobile) { + const pick = INTERESTING_COORDS[Math.floor(Math.random() * INTERESTING_COORDS.length)]; + c_real = pick[0]; + c_imag = pick[1]; + } else { + c_real = -0.7; + c_imag = 0.27015; + } - // Update the constant c based on the cursor position. window.addEventListener("mousemove", (e) => { - // Map the x-coordinate to a range of [-1, 1] c_real = (e.clientX / width) * 2 - 1; - // Map the y-coordinate to a range of [-1, 1] c_imag = (e.clientY / height) * 2 - 1; }); + if (isMobile) { + const scrollStart = INTERESTING_COORDS.indexOf( + INTERESTING_COORDS.find(c => c[0] === c_real && c[1] === c_imag) + ); + + window.addEventListener("scroll", () => { + const docHeight = document.documentElement.scrollHeight - window.innerHeight; + if (docHeight <= 0) return; + const progress = Math.min(window.scrollY / docHeight, 1); + const totalSegments = INTERESTING_COORDS.length; + const scaled = progress * totalSegments; + const segIndex = Math.min(Math.floor(scaled), totalSegments - 1); + const segProgress = scaled - segIndex; + const fromIdx = (scrollStart + segIndex) % INTERESTING_COORDS.length; + const toIdx = (scrollStart + segIndex + 1) % INTERESTING_COORDS.length; + const from = INTERESTING_COORDS[fromIdx]; + const to = INTERESTING_COORDS[toIdx]; + c_real = from[0] + (to[0] - from[0]) * segProgress; + c_imag = from[1] + (to[1] - from[1]) * segProgress; + }, { passive: true }); + } + let zoom = INITIAL_ZOOM; function render() {