app
Circuit Trace Generators
Public Made by Adomby adom
Two dependency-free, seeded circuit-background generators: a seamless torus tile with ambient or progressive reveal, and the v9 continuous field with obstacles, scroll reveal, and five ambient systems.
← Commit history
README.mdadded+219@@ -0,0 +1,219 @@+# Circuit Trace Generators++Two independent, dependency-free generators that draw the Adom **Nitrogen** hero+background — procedural PCB traces, vias, and routed light — as seeded SVG.++Both recreate the reference artwork's visual grammar rather than copying its path+data, and both were measured off the same original:++| Reference constant | Value |+| --- | --- |+| Routing pitch | `7.895` units (`150 / 19`) |+| Trace stroke | `1.58` units, `#151b25` |+| Via annulus | `3.34` outer / `1.76` inner |+| Board | `#0d1117` |+| Routed-light palette | `#00e6dc` 60% · `#64abff` 25% · `#c5b3ff` 15% |++They diverge on the thing that matters most: **how the board is filled.** One+routes a torus and tiles forever; the other routes one continuous field at the+mount's real size. Pick by whether you want a repeatable texture or a bespoke+backdrop.++| | Tiling router | Field router |+| --- | --- | --- |+| Fill strategy | seamless `900×450` tile, repeats in both axes | one continuous field, no repeat |+| Router | A\* nets between placed terminal formations | flow-field + vortex trace packing |+| Wrap | torus occupancy grid (seamless, crossing-free) | reserved grid nodes (crossing-free) |+| Headless output | `generate-tile.mjs` → SVG tile | `generateCircuitField()` → geometry |+| Motion | cursor-fed signal fountain | conductor **or** handshake system |+| Entry file | `circuit-background.js` | `circuit-background-v5.js` |+| Live demo | [traces-fuyou1ziuokn.adom.cloud](https://traces-fuyou1ziuokn.adom.cloud) | [circuit-y2uq81e4dp1d.adom.cloud](https://circuit-y2uq81e4dp1d.adom.cloud) |++Both ship `createCircuitBackground(mount, options)` returning+`{ regenerate, exportSvg, destroy }`, both are seeded (same seed + dimensions →+identical geometry), and both honour `prefers-reduced-motion`.++---++## 1. Tiling router — `circuit-background.js`++++An occupancy-grid router run **on a torus**, so the `900×450` tile it emits+repeats seamlessly in both axes and no two traces ever cross. That makes its+output usable directly as a CSS `background-image` with `background-repeat: repeat`.++### How a tile is built++1. **`placeFormations`** — scatters terminal groups (via ladders and rows) across+ the grid; these are the pads everything else routes between.+2. **`routeNets`** — A\* between pins, weighted by a *turn penalty* (higher =+ longer, calmer runs) and a *weave* preference for 2-lane neighbour spacing,+ with a matching *cramp* aversion to 1-lane spacing outside bundles.+3. **`replicateWalk`** — translated-copy bundle followers, so neighbouring traces+ bend together the way a real bus does, re-routed in bundle mode when blocked.+4. **`tapCombs`** / **`routeStubs`** — comb and stub motifs as punctuation.+5. **`sealEnd`** — enforces the **via mandate**: every trace starts *and* ends on a+ via, trimming blocked ends via per-step claim tracking. A wrap-aware checker+ passes with zero bare ends.++### Tuning++Twelve generation knobs, all exposed as sliders in the demo and as kebab-case+flags on the CLI:++`density` · `formations` · `busWidth` · `turnPenalty` · `weave` · `cramp` ·+`horizontalBias` · `netReach` · `jogBias` · `stubChance` · `inlineViaChance` · `combs`++### Motion: the signal fountain++Every signal is mortal. A passive spawn timer (`signalInterval`, 240 ms) is the+fountain: each tick, if the census is under `maxSignals` (12), one new signal+appears near the cursor — `pickStart` scores the actual launch pad by pointer+distance plus `spawnRadius` jitter, falling back to a whole-board spread when the+pointer idles past 4 s. A signal runs to a trace-end via, then rolls its chain's+survival: survivors hop to a nearby via (`hopRadius` 440) inheriting speed,+colour, and survival rate; the rest die and the timer refills next tick.+Equilibrium census ≈ spawn rate × life.++Passive and clicked chains decay at **separate rates** — `hopSurvival` 0.4 vs+`burstSurvival` 0.72 — so a clicked burst keeps its own longer life for the whole+chain. `colorDrift` (0.18/hop) crossfades a leg; `maxBurstSignals` (25) is a hard+ceiling.++Animation presets: **None** (the page default — a static board), **Fireflies**,+**Swarm**, **Cursor sparks**, **Slow streams**.++### Headless CLI++```bash+node generate-tile.mjs --seed traces --out tile.svg+node generate-tile.mjs --seed foo --turn-penalty 0.8 --bus-width 1.4 --combs 0 --transparent > tile.svg+```++Seed `traces` yields 334 traces / 482 vias per tile. Run with `--help` for the+full flag list.++### API++```js+import {+ generateCircuitTile, tileSvg, pathData, createCircuitBackground,+} from "./circuit-background.js";++const tile = generateCircuitTile({ seed: "traces", turnPenalty: 0.8 });+const svg = tileSvg(tile, { background: "#0d1117" });+```++---++## 2. Field router — `circuit-background-v5.js`++++No tile. A deterministic planar trace-packing pass fills one continuous field at+the mount's real dimensions with hundreds of independent routes. A rotatable+vector field plus seeded, low-frequency vortices organise long carriers, diagonal+runs, and gentle swirls; *channel attraction* collects nearby routes into natural+local buses. Every occupied grid node is reserved, so separate traces never cross.++`v5` is the animation shell over `v4`'s geometry (`v2` and `v3` are earlier+iterations, kept for reference).++### Tuning++`fill` · `routeLength` · `horizontalFlow` · `flowAngle` · `diagonalFlow` ·+`longFlow` · `swirl` · `swirlScale` · `jogLength` · `channelAttraction` ·+`edgeDensity` · `featureScale`++`featureScale` proportionally scales routing pitch, trace width, via rings, and+routed-light geometry together, so the motif stays coherent at any size.++Geometry presets: **Original match** (the default, tuned to the reference's path+count, route-length distribution, stroke, via count, and orientation mix),+**Dense**, **Diagonal sweep**, **Broad swirl**, **Sparse**. Geometry presets never+touch motion settings — the two preset rows are independent.++### Two animation systems++- **Original conductor** (`circuit-animation-conductor.js`) — the full system:+ ambient currents, breathing endpoint nodes, core and halo packets, convoys,+ timed spatial waves, pointer wake, endpoint flashes.+- **Adom handshake** (`circuit-animation-handshake.js`) — the restrained+ alternative. Each transaction charges a source via, traverses one complete trace+ once, settles into its destination via, and sends a dim acknowledgement back. It+ uses exact polyline intervals instead of wrapping dashes, never flood-lights the+ field, and avoids the protected hero-copy reading zone. Only `maxHandshakes` (3)+ transactions coexist, so per-frame work does **not** grow with geometry density —+ the reason to reach for it on a dense board.+- **None** mounts only the static SVG and creates no animation layer at all.++### API++```js+import { createCircuitBackground } from "./circuit-background-v5.js";++const circuit = createCircuitBackground(document.querySelector("#hero-circuit"), {+ seed: "product-launch",+ fill: 0.668,+ swirl: 0.28,+ channelAttraction: 0.78,+ animationSystem: "handshake",+ motion: true,+});++circuit.regenerate({ seed: "another-layout" });+circuit.triggerAnimation({ x: 240, y: 180 }); // in SVG coordinates+const svg = circuit.exportSvg(); // static, no motion layers+circuit.destroy();+```++`generateCircuitField(options)` returns deterministic geometry with no DOM+involvement — each trace carries `points`, `length`, `viaStart`, `viaEnd`, and+`pathData(points)` turns one into SVG path data. That is how the two images on+this page were rendered.++The mount needs a real width and height; the helper observes resizes, clips+overflow, and leaves pointer interaction to the surrounding page.++---++## Running both demos++The two projects share one working directory, `~/project/circuit-generator`, and+run on separate ports.++```bash+cd ~/project/circuit-generator++# Tiling router → http://localhost:8930+node serve-classic.mjs # serves index-classic.html + circuit-background.js++# Field router → http://localhost:8124+./serve.sh # serves index.html via server.js+```++Public mappings on container `beziswazskpw`:++| Demo | Port | URL |+| --- | --- | --- |+| Tiling router | 8930 | <https://traces-fuyou1ziuokn.adom.cloud> |+| Field router | 8124 | <https://circuit-y2uq81e4dp1d.adom.cloud> |++If either URL 502s, the process died — re-run its command above.++## File map++Both projects live side by side in one directory, which is the single most+confusing thing about the source. This is the split:++| File | Belongs to |+| --- | --- |+| `circuit-background.js` | tiling router (engine) |+| `index-classic.html`, `serve-classic.mjs` | tiling router (demo, port 8930) |+| `generate-tile.mjs` | tiling router (CLI) |+| `circuit-background-v5.js` | field router (entry: animation shell) |+| `circuit-background-v4.js` | field router (geometry) |+| `circuit-animation-conductor.js`, `circuit-animation-handshake.js` | field router (motion) |+| `circuit-background-v2.js`, `circuit-background-v3.js` | field router (earlier iterations) |+| `index.html`, `server.js`, `serve.sh` | field router (demo, port 8124) |
page.jsonadded+50@@ -0,0 +1,50 @@+{+ "slug": "circuit-trace-generators",+ "title": "Circuit Trace Generators",+ "type": "app",+ "version": "0.1.0",+ "description": "Two dependency-free, seeded SVG generators for the Adom Nitrogen hero background: a tiling router that emits a seamless 900x450 PCB-trace tile from a torus occupancy grid, and a field router that packs one continuous non-repeating trace field using a flow field and seeded vortices.",+ "tags": [+ "svg",+ "generative",+ "background",+ "pcb",+ "brand"+ ],+ "dependencies": {},+ "discovery_triggers": [+ "generate a circuit background",+ "make a PCB trace background",+ "nitrogen hero background",+ "seamless circuit tile",+ "procedural trace pattern"+ ],+ "discovery_pitch": "Reach for this when a page needs the Adom circuit-trace backdrop — either a seamless tile you can repeat as a CSS background-image, or one continuous generated field sized to the mount.",+ "sample_prompts": [+ {+ "label": "Seamless tile",+ "prompt": "generate a seamless circuit-trace tile I can use as a repeating CSS background"+ },+ {+ "label": "Hero backdrop",+ "prompt": "put the Nitrogen circuit background behind this hero section"+ }+ ],+ "scripts": {+ "install": "./install.sh",+ "uninstall": "./uninstall.sh"+ },+ "hero": {+ "type": "billboard",+ "headline": "Circuit Trace Generators",+ "subhead": "Two seeded SVG routers for the Nitrogen hero background — one tiles a torus, one packs a continuous field.",+ "screenshot": "docs/hero.png",+ "accent": "#00e6dc"+ },+ "visibility": "private",+ "org": "adom",+ "author": {+ "name": "AdityaAngajala",+ "email": "[email protected]"+ }+}