diff options
| author | Bobby <[email protected]> | 2026-04-22 09:18:18 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-04-22 09:18:18 +0530 |
| commit | 7f80e8a1a0c4e71fde9a1530cc49fd03da01c099 (patch) | |
| tree | 895cdebcc531f22e569acbad2f2944047593e99d /lib/components/LeafScene.svelte | |
| parent | bbb8a51490f98dfc02ab9a0fd79248806c80e705 (diff) | |
| download | hollowdark-7f80e8a1a0c4e71fde9a1530cc49fd03da01c099.tar.xz hollowdark-7f80e8a1a0c4e71fde9a1530cc49fd03da01c099.zip | |
Remove the leaf scene and its supporting systems from the Begin screen
Diffstat (limited to 'lib/components/LeafScene.svelte')
| -rw-r--r-- | lib/components/LeafScene.svelte | 197 |
1 files changed, 0 insertions, 197 deletions
diff --git a/lib/components/LeafScene.svelte b/lib/components/LeafScene.svelte deleted file mode 100644 index 53dce6b..0000000 --- a/lib/components/LeafScene.svelte +++ /dev/null @@ -1,197 +0,0 @@ -<script lang="ts"> - import { onDestroy, onMount } from 'svelte' - import { createRNG } from '@hollowdark/rng/seeded' - import { reduceMotion } from '@hollowdark/lib/display/state' - import { LEAF_VARIANTS } from '@hollowdark/lib/leaves/variants' - import { spawnLeaf } from '@hollowdark/lib/leaves/spawn' - import { isLeafOffscreen, stepLeaf } from '@hollowdark/lib/leaves/physics' - import { - initialWindSystem, - particleOpacity, - stepWind, - type IdSource - } from '@hollowdark/lib/leaves/wind' - import type { Leaf, SceneDimensions, WindSystem } from '@hollowdark/lib/leaves/types' - - const TARGET_LEAF_COUNT = 14 - const GROUND_Y_RATIO = 0.86 - - const rng = createRNG(Math.floor(performance.now() * 1000) | 0) - - let container: HTMLDivElement | null = $state(null) - let scene: SceneDimensions = $state({ width: 0, height: 0, groundY: 0 }) - let leaves: Leaf[] = $state([]) - let wind: WindSystem = $state(initialWindSystem(rng)) - - let rafId: number | null = null - let lastTimeMs = 0 - let nextLeafId = 0 - let nextGustId = 0 - let nextParticleId = 0 - let resizeObserver: ResizeObserver | null = null - - const ids: IdSource = { - nextGustId: () => nextGustId++, - nextParticleId: () => nextParticleId++ - } - - function measure(): void { - if (!container) return - const rect = container.getBoundingClientRect() - scene = { - width: rect.width, - height: rect.height, - groundY: rect.height * GROUND_Y_RATIO - } - } - - onMount(() => { - measure() - - for (let i = 0; i < TARGET_LEAF_COUNT; i++) { - leaves = [...leaves, spawnLeaf(nextLeafId++, scene, rng)] - } - - if (container && typeof ResizeObserver !== 'undefined') { - resizeObserver = new ResizeObserver(measure) - resizeObserver.observe(container) - } - - const tick = (nowMs: number): void => { - const dtMs = Math.min(50, nowMs - lastTimeMs) - lastTimeMs = nowMs - const dt = dtMs / 1000 - const timeS = nowMs / 1000 - - wind = stepWind(wind, dtMs, scene, rng, ids) - - const next: Leaf[] = [] - for (const leaf of leaves) { - const advanced = stepLeaf(leaf, dt, timeS, wind, scene) - if (!isLeafOffscreen(advanced, scene)) { - next.push(advanced) - } - } - - while (next.length < TARGET_LEAF_COUNT) { - next.push(spawnLeaf(nextLeafId++, scene, rng)) - } - - leaves = next - rafId = requestAnimationFrame(tick) - } - - rafId = requestAnimationFrame((nowMs) => { - lastTimeMs = nowMs - rafId = requestAnimationFrame(tick) - }) - }) - - onDestroy(() => { - if (rafId !== null) cancelAnimationFrame(rafId) - resizeObserver?.disconnect() - }) -</script> - -{#if !$reduceMotion} -<div class="leaf-scene" bind:this={container} aria-hidden="true"> - <svg class="defs" width="0" height="0" focusable="false"> - <defs> - {#each LEAF_VARIANTS as variant (variant.id)} - <symbol id="leaf-{variant.id}" viewBox={variant.viewBox}> - <path - d={variant.pathData} - fill="currentColor" - stroke="currentColor" - stroke-width="0.6" - stroke-linejoin="round" - /> - </symbol> - {/each} - </defs> - </svg> - - <div class="ground" style:top="{scene.groundY}px"></div> - - {#if wind.activeGust} - {#each wind.activeGust.particles as particle (particle.id)} - <div - class="wind-particle" - style:left="{particle.x}px" - style:top="{particle.y}px" - style:width="{particle.size}px" - style:height="{particle.size}px" - style:opacity={particleOpacity(particle)} - ></div> - {/each} - {/if} - - {#each leaves as leaf (leaf.id)} - <svg - class="leaf" - viewBox="0 0 40 48" - style:left="{leaf.x}px" - style:top="{leaf.y}px" - style:width="{leaf.size}px" - style:color={leaf.color} - style:transform="translate(-50%, -50%) rotate({leaf.rotation}deg)" - focusable="false" - > - <use href="#leaf-{leaf.variantId}" /> - </svg> - {/each} -</div> -{/if} - -<style> - .leaf-scene { - position: absolute; - inset: 0; - overflow: hidden; - pointer-events: none; - z-index: 0; - } - - .defs { - position: absolute; - width: 0; - height: 0; - } - - .ground { - position: absolute; - left: 0; - right: 0; - height: 1px; - background: linear-gradient( - to right, - rgba(232, 226, 213, 0) 0%, - rgba(232, 226, 213, 0.04) 30%, - rgba(232, 226, 213, 0.04) 70%, - rgba(232, 226, 213, 0) 100% - ); - opacity: 0.6; - } - - .leaf { - position: absolute; - display: block; - will-change: transform, top, left; - filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.25)); - } - - .wind-particle { - position: absolute; - border-radius: 50%; - background: rgba(232, 226, 213, 0.45); - transform: translate(-50%, -50%); - pointer-events: none; - box-shadow: 0 0 4px rgba(232, 226, 213, 0.2); - } - - @media (prefers-reduced-motion: reduce) { - .leaf-scene { - display: none; - } - } -</style> |
