From eed52135e7d6ffbbbd64070cf567bcf08653c7d5 Mon Sep 17 00:00:00 2001
From: HsiangNianian <i@jyunko.cn>
Date: Wed, 14 Jan 2026 18:15:31 +0800
Subject: feat: Enhance UI components and add visual effects

- Updated Sidebar component styles for improved aesthetics and usability.
- Refactored VersionsView component with a new layout and enhanced version filtering.
- Improved DownloadMonitor and GameConsole components for better performance and visual consistency.
- Added new settings for GPU acceleration and visual effects in settings store.
- Introduced ParticleBackground component with customizable effects (Constellation and Saturn).
- Implemented ConstellationEffect and SaturnEffect classes for dynamic background animations.
---
 ui/src/components/ParticleBackground.svelte | 57 +++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 ui/src/components/ParticleBackground.svelte

(limited to 'ui/src/components/ParticleBackground.svelte')

diff --git a/ui/src/components/ParticleBackground.svelte b/ui/src/components/ParticleBackground.svelte
new file mode 100644
index 0000000..080f1f2
--- /dev/null
+++ b/ui/src/components/ParticleBackground.svelte
@@ -0,0 +1,57 @@
+<script lang="ts">
+  import { onMount, onDestroy } from "svelte";
+  import { ConstellationEffect } from "../lib/effects/ConstellationEffect";
+  import { SaturnEffect } from "../lib/effects/SaturnEffect";
+  import { settingsState } from "../stores/settings.svelte";
+
+  let canvas: HTMLCanvasElement;
+  let activeEffect: any;
+
+  function loadEffect() {
+    if (activeEffect) {
+      activeEffect.destroy();
+    }
+    
+    if (!canvas) return;
+
+    if (settingsState.settings.active_effect === "saturn") {
+      activeEffect = new SaturnEffect(canvas);
+    } else {
+      activeEffect = new ConstellationEffect(canvas);
+    }
+    
+    // Ensure correct size immediately
+    activeEffect.resize(window.innerWidth, window.innerHeight);
+  }
+
+  $effect(() => {
+    const _ = settingsState.settings.active_effect;
+    if (canvas) {
+        loadEffect();
+    }
+  });
+
+  onMount(() => {
+    const resizeObserver = new ResizeObserver(() => {
+      if (canvas && activeEffect) {
+         activeEffect.resize(window.innerWidth, window.innerHeight);
+      }
+    });
+    
+    resizeObserver.observe(document.body);
+    
+    return () => {
+      resizeObserver.disconnect();
+      if (activeEffect) activeEffect.destroy();
+    };
+  });
+  
+  onDestroy(() => {
+    if (activeEffect) activeEffect.destroy();
+  });
+</script>
+
+<canvas
+  bind:this={canvas}
+  class="absolute inset-0 z-0 pointer-events-none"
+></canvas>
-- 
cgit v1.2.3-70-g09d2

