feat: add README file with project overview and setup instructions

This commit is contained in:
sha
2026-02-21 22:44:16 +02:00
parent 3fb3c0739a
commit 70be0ce4a4
2 changed files with 112 additions and 69 deletions
+77 -63
View File
@@ -1,7 +1,8 @@
# devpage — Agent Context File # devpage — Agent Context File
This file is a compact reference for AI agents working on this project. This file is a compact reference for AI agents working on this project.
Read it before making changes. It covers purpose, architecture, patterns, and current state. Read it before making changes; it documents architecture, patterns, current
state, and deployment notes.
--- ---
@@ -9,13 +10,20 @@ Read it before making changes. It covers purpose, architecture, patterns, and cu
A personal developer page — a single-page app with an animated gradient background A personal developer page — a single-page app with an animated gradient background
and a floating icon "evolution" system. Icons spawn at random intervals, drift and a floating icon "evolution" system. Icons spawn at random intervals, drift
around the screen with chaotic physics, and bounce off viewport edges. with chaotic physics, and bounce off viewport edges. A settings modal lets the
A settings modal lets the user tune the gradient colour, animation speed, icon user tune colours, speeds, the bump/threshold behaviour of the logo word, and
movement speed, and gradient rotation. other simulation parameters.
**It is intentionally a growing project.** The base page and evolution system are Recent enhancements include:
done; future work will extend icon variety, add icon interactions, and build out - Full localStorage persistence of all settings including slider values,
the main content area. toggle states, bump counts, and threshold range.
- Realtime current-value display for every slider.
- Debug/visualisation toggles for per-letter hit counts and detach thresholds.
- Configurable random bump threshold range with immediate update of existing
letters and regenerated thresholds on evolution restart.
- Smooth colour interpolation for letters as they approach their threshold.
- Reset semantics that restore **all** settings to constants while leaving
evolution state untouched.
--- ---
@@ -23,10 +31,8 @@ the main content area.
- Vanilla JS — no framework, no bundler, no build step. - Vanilla JS — no framework, no bundler, no build step.
- Pure ES modules (`type="module"` in HTML). All imports use relative paths. - Pure ES modules (`type="module"` in HTML). All imports use relative paths.
- Requires a local HTTP server `fetch()` calls fail on `file://`. - Static site; requires HTTP server for `fetch()` (e.g. GitHub Pages, `npx serve`).
Run with `npx serve .` or `python3 -m http.server` then open `localhost`. - Target: modern evergreen browsers (CSS `@property`, `backdrop-filter`, etc.).
- Browser target: modern evergreen (CSS `@property`, `backdrop-filter`, `scale`
as standalone property, private class fields all required).
--- ---
@@ -36,25 +42,28 @@ the main content area.
index.html ← HTML shell + all CSS links + module entry point index.html ← HTML shell + all CSS links + module entry point
src/ src/
js/ js/
main.js ← Entry point. Instantiates all controllers, boots them. main.js ← Entry point. Instantiates controllers, wires them.
constants.js ← Single source of truth for all numeric/flag defaults. constants.js ← Single source of truth for all numeric/flag defaults.
gradient.js ← GradientController. Drives CSS vars on <html>. gradient.js ← GradientController.
modal.js ← ModalController. Open/close, focus trap, Escape dismiss. modal.js ← ModalController (settings popup).
settings.js ← SettingsController. UI controller bridge (no own state). settings.js ← SettingsController (UI controllers, storage).
evolution.js ← EvolutionController. Spawn scheduler + rAF physics loop. evolution.js ← EvolutionController (physics/loop/spawner).
entity.js ← Entity class. One floating icon: physics + DOM lifecycle. entity.js ← Entity class (one floating icon).
iconLoader.js ← fetch() + Map cache for SVGs. normalizeSvg() strips attrs. logoController.js ← LogoController (floating word logic).
logoLetter.js ← LogoLetter class (perletter behaviour).
iconLoader.js ← SVG fetching and caching.
utils/ utils/
colorUtils.js ← hexToHSL, hslToHex, deriveGradientPair. colorUtils.js ← colour math utilities.
styles/ styles/
main.css ← Base reset, typography (DM Mono), settings button. main.css
gradient.css ← @property --gradient-angle, keyframes, body animation. gradient.css
modal.css ← Glass morphism overlay, controls, toggle switch. modal.css
icons.css ← .evolution-container, .icon-entity, appear transition. icons.css
logo.css
data/ data/
icons.json ← Icon registry: groups, per-icon metadata, type colours, spawn config. icons.json ← Configuration for icons, types, spawn rules.
icons/ icons/
*.svg ← 34 SVG icons (Solar icon set, 24×24 viewBox, currentColor). *.svg ← Raw SVG files (34 total).
``` ```
--- ---
@@ -63,38 +72,31 @@ src/
### Controller pattern ### Controller pattern
Each domain has one class. No shared mutable globals.
``` ```
main.js main.js
├── GradientController gradient.js state: color, speed, rotating ├── GradientController
├── ModalController modal.js state: open/closed, trigger ref ├── ModalController
├── SettingsController settings.js no state — reads DOM, forwards to others ├── SettingsController
└── EvolutionController evolution.js state: entities[], moveSpeed, timers └── EvolutionController
── Entity[] entity.js state: x, y, vx, vy, alive, DOM refs ── LogoController
│ └── LogoLetter[]
└── Entity[]
``` ```
### Data flow ### Data flow
``` ```
User interaction (slider/picker/toggle) UI change → settings.js → controller method → CSS/physics update → save
→ settings.js listener
→ gradient.setColor() / gradient.setSpeed() / evolution.setMoveSpeed()
→ CSS custom property on <html> OR evolution speed multiplier updated live
``` ```
### CSS custom properties (set on `<html>` by GradientController) SettingsController is the only module that writes to localStorage; it serialises
all mutable configuration (including logos hit counts) and restores them on
``` boot, preserving the exact state across reloads. The reset button clears this
--color-1 first gradient colour (derived from user's base colour) storage and reverts UI controls to `constants.js` defaults.
--color-2 second gradient colour (hue-shifted companion)
--anim-duration animation duration in seconds (maps speed 1-10 → ~32s-3.5s)
--gradient-angle registered @property <angle>, animated by gradientRotate keyframe
```
--- ---
## Key patterns and why ## Key patterns
### Two-div entity structure ### Two-div entity structure
Each entity uses an outer div for JS position (`transform: translate()`) and an Each entity uses an outer div for JS position (`transform: translate()`) and an
@@ -200,31 +202,43 @@ Create a new group in `icons.groups` if needed.
## Current spawn behaviour ## Current spawn behaviour
Only `dna-bold-duotone` spawns. The icon is set in `icons.json → spawn.initial`. Only `dna-bold-duotone` spawns by default; the spawn logic is the next target for extension.
`EvolutionController.#spawnEntity()` always uses `spawn.initial` — it does not yet
pick from the full icon registry. This is intentional: the spawn logic is the next
thing to extend.
--- ---
## Settings modal controls ## Settings modal controls
| Element ID | Type | Default | Wired to | In addition to the original colour/speed toggles, the modal now offers:
|--------------------|---------|---------|-------------------------------------|
| `colorPicker` | color | #4d22b3 | `gradient.setColor(hex)` | - realtime readout column for every slider value (gradient speed, movement
| `speedSlider` | range 1-10 | 2 | `gradient.setSpeed(n)` | speed, spawn rate, virus kill %, bug rarity %, bug count, and bump range).
| `moveSpeedSlider` | range 1-10 | 5 | `evolution.setMoveSpeed(n)` | - toggles for showing perletter **hit counts** and **detach thresholds** on the
| `rotationToggle` | checkbox| false | `gradient.toggleRotation(bool)` | floating logo word.
- sliders to adjust the **min/max bump threshold** used when picking random
detach numbers.
All settings persist to localStorage, including zeros and hits, and reload
exact values on page refresh. The reset button restores every setting to the
hardcoded constant defaults.
--- ---
## Known gaps / next steps ## Known gaps / next steps
1. **Spawn variety** `#spawnEntity` always spawns `spawn.initial`. Extend to pick 1. **Spawn variety** pick from full icon registry.
randomly from `icons.icons` (or weighted by type) to get diverse entities. 2. **icons.json completeness** register remaining 25 icons.
2. **icons.json completeness** — 25 icons on disk are unregistered. Add them to 3. **Entity interactions** currently only entityletter collisions are handled.
unlock their use in spawning. 4. **Main content area** still an empty `<main>` for future content.
3. **Icon interactions** — no collision detection between entities yet. 5. **Entity cap/persistence improvements** add limits or export/import features.
4. **Main content area**`<main class="page-main">` is empty. Reserved for content.
5. **Entity cap** — no maximum entity count; they accumulate indefinitely. ---
6. **Persistence** — settings reset on page reload. No localStorage yet.
## Deployment notes
The app is fully static; GitHub Pages (or any static file host) works fine.
No serverside code is required. Make sure to serve via HTTP so `fetch` can
load `icons.json` and SVG files.
*Updated 20260221 to reflect the current state after adding settings persistence,
hitcount/debug toggles, threshold controls, colour interpolation, and continued
work on logo/evolution mechanics.*
+29
View File
@@ -0,0 +1,29 @@
# devpage
A tiny personal developer page with an animated gradient background and floating icons.
## Features
- Vanilla JavaScript ES modules
- Randomly spawning SVG icons with physics
- Logo word that responds to hits and detaches letters
- Settings modal with persistent controls (gradient, speed, spawn, logo options)
- Fully static; serves via any HTTP server (e.g. `python3 -m http.server`).
## Development
1. Clone the repo.
2. Run a simple HTTP server in the project root:
```sh
cd devpage
python3 -m http.server 8080
```
3. Open `http://localhost:8080` in a modern browser.
## Deployment
The site is static and can be hosted on GitHub Pages or any static file host.
## License
MIT