diff --git a/frontend/src/lib/components/ScreensaverOverlay.svelte b/frontend/src/lib/components/ScreensaverOverlay.svelte
index 4718531..9779447 100644
--- a/frontend/src/lib/components/ScreensaverOverlay.svelte
+++ b/frontend/src/lib/components/ScreensaverOverlay.svelte
@@ -4,11 +4,13 @@
import { screensaver, isScreensaverActive, activeScreensaverType } from '$lib/stores/screensaver';
import Snowfall from './screensavers/Snowfall.svelte';
import FractalCrystalline from './screensavers/FractalCrystalline.svelte';
+ import MandelbrotZoom from './screensavers/MandelbrotZoom.svelte';
// Map type to component
const screensaverComponents = {
snowfall: Snowfall,
- fractal_crystalline: FractalCrystalline
+ fractal_crystalline: FractalCrystalline,
+ mandelbrot_zoom: MandelbrotZoom
};
// Dismiss on any interaction
diff --git a/frontend/src/lib/components/screensavers/FractalCrystalline.svelte b/frontend/src/lib/components/screensavers/FractalCrystalline.svelte
index b8dfb8f..f6dde85 100644
--- a/frontend/src/lib/components/screensavers/FractalCrystalline.svelte
+++ b/frontend/src/lib/components/screensavers/FractalCrystalline.svelte
@@ -24,7 +24,7 @@
maxBranches: 800, // Max simultaneous branch tips
branchChance: 0.03, // Chance to spawn new branch per frame
turnAngle: 0.3, // Max random turn per frame (radians)
- hueShiftSpeed: 0.2, // Color cycling speed
+ hueShiftSpeed: 0.5, // Color cycling speed (faster for more color variety)
maxPoints: 15000, // Max crystal points (kept for reference)
shatterDuration: 2500, // Milliseconds for shatter effect
lineWidth: 2
@@ -112,11 +112,14 @@
ctx.fillRect(0, 0, width, height);
}
- // Create seed points at random locations
+ // Create seed points at random locations with spread colors
for (let i = 0; i < CONFIG.seedCount; i++) {
const x = Math.random() * width;
const y = Math.random() * height;
+ // Base hue for this seed - spread evenly across spectrum
+ const seedHue = (i * 360 / CONFIG.seedCount) + Math.random() * 30;
+
// Each seed spawns multiple branches in different directions
const branchCount = 3 + Math.floor(Math.random() * 4);
for (let j = 0; j < branchCount; j++) {
@@ -125,7 +128,7 @@
x,
y,
angle,
- hue: Math.random() * 360,
+ hue: (seedHue + j * 25 + Math.random() * 20) % 360, // Each branch gets varied hue
age: 0,
generation: 0
});
@@ -178,9 +181,11 @@
hue: (branch.hue + branch.age * 0.5) % 360
});
- // Draw the branch segment
- const h = (branch.hue + branch.age * 0.5) % 360;
- ctx.strokeStyle = `hsla(${h}, 80%, 60%, 0.9)`;
+ // Draw the branch segment with varied colors
+ const h = (branch.hue + branch.age * 1.5) % 360; // Faster hue shift
+ const s = 70 + Math.sin(branch.age * 0.1) * 20; // Saturation varies 50-90%
+ const l = 50 + Math.cos(branch.age * 0.05) * 15; // Lightness varies 35-65%
+ ctx.strokeStyle = `hsla(${h}, ${s}%, ${l}%, 0.9)`;
ctx.lineWidth = CONFIG.lineWidth;
ctx.beginPath();
ctx.moveTo(branch.x, branch.y);
@@ -192,14 +197,14 @@
branch.y = newY;
branch.age++;
- // Chance to spawn a new branch (fork)
+ // Chance to spawn a new branch (fork) with distinct color
if (Math.random() < CONFIG.branchChance && branches.length + newBranches.length < CONFIG.maxBranches) {
const forkAngle = branch.angle + (Math.random() > 0.5 ? 1 : -1) * (0.3 + Math.random() * 0.7);
newBranches.push({
x: newX,
y: newY,
angle: forkAngle,
- hue: (branch.hue + 20 + Math.random() * 40) % 360,
+ hue: (branch.hue + 30 + Math.random() * 90) % 360, // More color variation
age: 0,
generation: branch.generation + 1
});
@@ -228,6 +233,7 @@
// Only spawn if we found an unoccupied spot
if (!isOccupied(x, y)) {
+ const seedHue = Math.random() * 360; // Random base hue for new seed
const branchCount = 2 + Math.floor(Math.random() * 3);
for (let j = 0; j < branchCount; j++) {
const angle = Math.random() * Math.PI * 2;
@@ -235,7 +241,7 @@
x,
y,
angle,
- hue: Math.random() * 360,
+ hue: (seedHue + j * 40 + Math.random() * 30) % 360, // Varied colors
age: 0,
generation: 0
});
diff --git a/frontend/src/lib/components/screensavers/MandelbrotZoom.svelte b/frontend/src/lib/components/screensavers/MandelbrotZoom.svelte
new file mode 100644
index 0000000..3b82359
--- /dev/null
+++ b/frontend/src/lib/components/screensavers/MandelbrotZoom.svelte
@@ -0,0 +1,209 @@
+
+
+
+
+
diff --git a/frontend/src/lib/stores/screensaver.js b/frontend/src/lib/stores/screensaver.js
index 95fd232..90ee6d5 100644
--- a/frontend/src/lib/stores/screensaver.js
+++ b/frontend/src/lib/stores/screensaver.js
@@ -93,9 +93,11 @@ function createScreensaverStore() {
// Check if idle time exceeds timeout
if (newIdleTime >= state.timeoutMinutes * 60) {
// Resolve random type at activation time
- const activeType = state.type === 'random'
- ? (Math.random() < 0.5 ? 'snowfall' : 'fractal_crystalline')
- : state.type;
+ let activeType = state.type;
+ if (state.type === 'random') {
+ const types = ['snowfall', 'fractal_crystalline', 'mandelbrot_zoom'];
+ activeType = types[Math.floor(Math.random() * types.length)];
+ }
return { ...newState, active: true, activeType };
}