fix: tune orbs/aurora/pulse/rain, redesign rays with settings

Orbs: opacity halved — ambient, not a flood of color.
Aurora: opacity halved, 6 bands, slower movement.
Pulse: fast bass tracker (0.45 factor) for onset detection; ambient
  rings so mode stays alive without audio playing.
Rain: 30 drops (was 65), 1.4px wide, soft gradient, bass mult 2.5x.
Rays: complete redesign — tapered triangle beams from center using
  linear gradients; secondary counter-rotating pink layer; center glow.
  Reads raysConfig (count/speed/brightness/spread) via ref — no restart.
Settings: rays config panel (4 sliders + reset) appears when rays active.
bgStore: RaysConfig interface, setRaysConfig, localStorage persistence.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 21:12:34 +03:00
parent 7f2f6f7e44
commit 87ba7a0ecf
3 changed files with 218 additions and 149 deletions

View File

@@ -4,11 +4,7 @@ import { create } from 'zustand'
export type BgMode = 'orbs' | 'waves' | 'particles' | 'aurora' | 'pulse' | 'stars' | 'rain' | 'rays' | 'none'
export interface BgPreset {
id: BgMode
name: string
desc: string
}
export interface BgPreset { id: BgMode; name: string; desc: string }
export const BG_PRESETS: BgPreset[] = [
{ id: 'orbs', name: 'Орбы', desc: 'Цветовые пятна' },
@@ -22,21 +18,43 @@ export const BG_PRESETS: BgPreset[] = [
{ id: 'none', name: 'Нет', desc: 'Чистый фон' },
]
const KEY = 'pm_bg'
export interface RaysConfig {
count: number // 416
speed: number // 0.23.0 (rotation speed multiplier)
brightness: number // 0.32.5
spread: number // 0.32.0 (ray width multiplier)
}
export const DEFAULT_RAYS: RaysConfig = { count: 9, speed: 1, brightness: 1, spread: 1 }
const KEY_BG = 'pm_bg'
const KEY_RAYS = 'pm_rays'
interface BgStore {
bgMode: BgMode
raysConfig: RaysConfig
setBg: (mode: BgMode) => void
setRaysConfig: (cfg: Partial<RaysConfig>) => void
}
export const useBgStore = create<BgStore>((set) => ({
export const useBgStore = create<BgStore>((set, get) => ({
bgMode: (() => {
if (typeof window === 'undefined') return 'orbs'
const saved = localStorage.getItem(KEY) as BgMode | null
const saved = localStorage.getItem(KEY_BG) as BgMode | null
return saved && BG_PRESETS.some(p => p.id === saved) ? saved : 'orbs'
})(),
raysConfig: (() => {
if (typeof window === 'undefined') return DEFAULT_RAYS
try { return { ...DEFAULT_RAYS, ...JSON.parse(localStorage.getItem(KEY_RAYS) || '{}') } }
catch { return DEFAULT_RAYS }
})(),
setBg: (mode) => {
if (typeof window !== 'undefined') localStorage.setItem(KEY, mode)
if (typeof window !== 'undefined') localStorage.setItem(KEY_BG, mode)
set({ bgMode: mode })
},
setRaysConfig: (cfg) => {
const next = { ...get().raysConfig, ...cfg }
if (typeof window !== 'undefined') localStorage.setItem(KEY_RAYS, JSON.stringify(next))
set({ raysConfig: next })
},
}))