diff --git a/assets/css/style.css b/assets/css/style.css index d0924e7..e67236a 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -1,10 +1,20 @@ +:root { + --primary-pink: #F5A9B8; + --primary-blue: #5BCFFA; + --white: #FFFFFF; + --dark-bg: #161618; + --gray-blue: #A8C5DB; + --dark-blue: #12354B; + --dark-teal: #12404B; + +} + display-imagebody,html{ -ms-scroll-chaining:none; overscroll-behavior:none; margin:0; padding:0; - background-image: url(../images/background.webp); - background-color: black; + background-color: var(--dark-bg); background-size: cover; background-attachment: fixed; font-family: "Noto Sans", serif; @@ -29,6 +39,16 @@ display-imagebody,html{ to{background-position:100px 0} } +.background-canvas { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; + pointer-events: none; +} + .min-h-full{ min-height:100vh } diff --git a/assets/js/background.js b/assets/js/background.js new file mode 100644 index 0000000..34f08ab --- /dev/null +++ b/assets/js/background.js @@ -0,0 +1,119 @@ +(() => { + document.addEventListener("DOMContentLoaded", () => { + const canvas = document.getElementById("backgroundCanvas"); + if (!canvas) return; + + if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; + + const ctx = canvas.getContext("2d", { alpha: true, desynchronized: true }); + + const isMobile = window.matchMedia("(max-width: 768px)").matches; + const DPR_CAP = Math.min(1.5, isMobile ? 1.0 : 1.25); + + const getOrbCount = () => { + const baseCount = Math.floor((window.innerWidth * window.innerHeight) / 40000); + return Math.min(Math.max(baseCount, isMobile ? 15 : 25), isMobile ? 30 : 50); + }; + + const R_MIN = isMobile ? 3 : 4; + const R_MAX = isMobile ? 8 : 12; + const SPEED = isMobile ? 0.08 : 0.12; + + const PINK = [245, 169, 184]; + const BLUE = [91, 207, 250]; + + let w = 0, h = 0, dpr = 1; + let orbs = []; + let raf = 0; + let last = 0; + + function resize() { + w = window.innerWidth; + h = window.innerHeight; + + dpr = Math.min(DPR_CAP, window.devicePixelRatio || 1); + canvas.width = Math.floor(w * dpr); + canvas.height = Math.floor(h * dpr); + canvas.style.width = w + "px"; + canvas.style.height = h + "px"; + + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + createOrbs(); + last = 0; + } + + function createOrbs() { + const count = getOrbCount(); + orbs = new Array(count); + + for (let i = 0; i < count; i++) { + const r = Math.random() * (R_MAX - R_MIN) + R_MIN; + const color = Math.random() > 0.5 ? PINK : BLUE; + orbs[i] = { + x: Math.random() * w, + y: Math.random() * h, + r, + a: Math.random() * 0.15 + 0.4, + vx: (Math.random() - 0.5) * SPEED, + vy: (Math.random() - 0.5) * SPEED, + color: color + }; + } + } + + function step() { + ctx.clearRect(0, 0, w, h); + + for (let i = 0; i < orbs.length; i++) { + const o = orbs[i]; + o.x += o.vx; + o.y += o.vy; + + const margin = o.r * 3; + if (o.x < -margin) o.x = w + margin; + else if (o.x > w + margin) o.x = -margin; + if (o.y < -margin) o.y = h + margin; + else if (o.y > h + margin) o.y = -margin; + + ctx.beginPath(); + ctx.arc(o.x, o.y, o.r, 0, Math.PI * 2); + ctx.fillStyle = `rgba(${o.color[0]}, ${o.color[1]}, ${o.color[2]}, ${o.a})`; + ctx.fill(); + } + } + + function tick(now) { + if (document.hidden) { + raf = 0; + return; + } + + if (!last) last = now; + if (now - last >= 16) { + last = now; + step(); + } + + raf = requestAnimationFrame(tick); + } + + let resizeTimer; + window.addEventListener("resize", () => { + clearTimeout(resizeTimer); + resizeTimer = setTimeout(resize, 150); + }, { passive: true }); + + document.addEventListener("visibilitychange", () => { + if (document.hidden) { + cancelAnimationFrame(raf); + raf = 0; + } else if (!raf) { + last = 0; + raf = requestAnimationFrame(tick); + } + }); + + resize(); + raf = requestAnimationFrame(tick); + }); +})(); \ No newline at end of file diff --git a/index.html b/index.html index b8910b4..96a601b 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + @@ -13,7 +13,7 @@ JaxOff Links - + @@ -32,13 +32,14 @@ - + + End of Snowfall Background Animation --> +
@@ -202,7 +203,7 @@