From 71e76624082fe7870a1ec3f3e466f1d442682b3d Mon Sep 17 00:00:00 2001 From: Zakarya Date: Wed, 7 May 2025 21:17:52 -0700 Subject: [PATCH] Add a manual light/dark mode switcher Despite the simplicity of the commit title, this was a pretty big change. The styling used to just go off of the system's color scheme, but that can't be overridden. Instead, I have made a variable that determines whether dark theme is active and made a small panel with some buttons to change the theme. I had to change a lot of code to achieve this and lost a lot of hair (I metaphorically pulled it out) from writing this code. I also changed things from legacy mode to rune mode (Svelte 4 to 5) while I was at it, that wasn't too big. --- src/component/bg.svelte | 46 +++++++--------- src/component/navbar.svelte | 20 +++---- src/component/settings.svelte | 96 +++++++++++++++++++++++++++++++++ src/routes/+layout.svelte | 67 ++++++++++++++++++++++- src/routes/+layout.ts | 1 - src/routes/+page.svelte | 8 +-- src/routes/about/+page.svelte | 8 ++- src/routes/studios/+page.svelte | 8 ++- src/routes/video/+page.svelte | 47 ++++++++-------- src/routes/zakarya/+page.svelte | 14 +++-- src/script/theme.ts | 15 ++++++ src/style/main.scss | 32 +++++------ 12 files changed, 273 insertions(+), 89 deletions(-) create mode 100644 src/component/settings.svelte create mode 100644 src/script/theme.ts diff --git a/src/component/bg.svelte b/src/component/bg.svelte index 428165d..1c1ecfb 100644 --- a/src/component/bg.svelte +++ b/src/component/bg.svelte @@ -5,8 +5,18 @@ let canvas: HTMLCanvasElement; let ctx: CanvasRenderingContext2D; - let dark_theme = false; - let time_scale = 1; + let { darkTheme = $bindable() } = $props(); + let timeScale = 1; // TODO: Make entities a bit faster like they used to + + $effect(() => { + darkTheme; + + for (let i = 0; i < gradients.length; i++) { + let gradient = gradients[i]; + gradient.color = getRandomColor(); + gradient.prepareBuffer(); + } + }); let particleImages: { [key: string]: HTMLImageElement } = {}; @@ -49,24 +59,6 @@ return {}; }); - if ( - window.matchMedia && - window.matchMedia("(prefers-color-scheme: dark)").matches - ) { - dark_theme = true; - } - - window - .matchMedia("(prefers-color-scheme: dark)") - .addEventListener("change", (event) => { - dark_theme = event.matches; - for (let i = 0; i < gradients.length; i++) { - let gradient = gradients[i]; - gradient.color = getRandomColor(); - gradient.prepareBuffer(); - } - }); - resize(); init(); animate(); @@ -99,8 +91,8 @@ } update() { - this.x += this.speedX * time_scale; - this.y += this.speedY * time_scale; + this.x += this.speedX * timeScale; + this.y += this.speedY * timeScale; // Reverse direction if particle hits edge if (this.x <= 0 || this.x >= window.innerWidth) { @@ -183,10 +175,10 @@ update() { super.update(); - this.angle += this.rotationSpeed * time_scale; + this.angle += this.rotationSpeed * timeScale; // Breathing effect: oscillate size - this.size += this.growthSpeed * time_scale; + this.size += this.growthSpeed * timeScale; if ( this.size >= this.originalSize * 1.25 || this.size <= this.originalSize * 0.75 @@ -199,7 +191,7 @@ ctx.save(); // The source images are black, so we are inverting them // different amounts to get different shades of gray - ctx.filter = dark_theme ? "invert(0.15)" : "invert(0.8)"; + ctx.filter = darkTheme ? "invert(0.15)" : "invert(0.8)"; // Draw center of rotation // ctx.beginPath(); @@ -214,7 +206,7 @@ } function getRandomColor() { - if (dark_theme) { + if (darkTheme) { let r = Math.floor(Math.random() * 255 - 100); let b = Math.floor(Math.random() * 255 - 100); let g = Math.floor(Math.random() * 255 - 100); @@ -273,7 +265,7 @@ this.radius, ); gradient.addColorStop(0, this.color); - if (dark_theme) { + if (darkTheme) { gradient.addColorStop(1, `rgba(0, 0, 0, 0)`); } else { gradient.addColorStop(1, `rgba(255, 255, 255, 0)`); diff --git a/src/component/navbar.svelte b/src/component/navbar.svelte index 8bb9585..7b75baa 100644 --- a/src/component/navbar.svelte +++ b/src/component/navbar.svelte @@ -1,4 +1,6 @@