Watch
0
0
Fork
You've already forked hyperhive
0

swarm-ui: test the rain arithmetic and the swarm name loader

The rain's column maths and fade colour move from MatrixRain into
shell/rain.ts, and the request-once swarm name loader from useSwarmName
into shell/swarm-name.ts. Both are plain functions with their input
passed in, so tests cover them; the components keep the DOM and canvas
work.
This commit is contained in:
iris 2026-10-14 16:36:27 +02:00 • committed by mara
commit e32b4172e4
6 changed files with 237 additions and 42 deletions

View file

@ -7,10 +7,16 @@
// `prefers-reduced-motion`. The same effect as the hive dashboard's home
// page, which is plain JS over a fixed canvas.
import { useEffect, useRef } from "preact/hooks";
import {
CELL,
columnsFor,
fadeColorOf,
glyphFor,
startDrops,
stepDrops,
} from "./rain.js";
import "./MatrixRain.css";
const GLYPHS = "アイウエオカキクケコサシスセソタチツテト0123456789:=*+-<>¦";
const CELL = 16; // glyph cell size, in px
const STEP_MS = 55;
// `getComputedStyle` on a custom property returns its declared value
@ -42,15 +48,7 @@ export function MatrixRain() {
let fadeColor = "";
function resolveColors() {
glyphColor = resolveColor("--green", "rgb(166, 227, 161)");
// The fade trail is the background at low alpha. Its channels are
// pulled out numerically so the trail fades whatever spacing
// rgb()/rgba() comes back in, and never fills solid.
const bg = resolveColor("--bg", "rgb(30, 30, 46)").match(
/(\d+)[^\d]+(\d+)[^\d]+(\d+)/,
);
fadeColor = bg
? `rgba(${bg[1]}, ${bg[2]}, ${bg[3]}, 0.09)`
: "rgba(30, 30, 46, 0.09)";
fadeColor = fadeColorOf(resolveColor("--bg", "rgb(30, 30, 46)"));
}
resolveColors();
const themeWatch = new MutationObserver(resolveColors);
@ -65,10 +63,8 @@ export function MatrixRain() {
if (!canvas || !ctx) return;
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
cols = Math.max(1, Math.ceil(canvas.width / CELL));
drops = Array.from({ length: cols }, () =>
Math.floor(Math.random() * -40),
);
cols = columnsFor(canvas.width);
drops = startDrops(cols, Math.random);
ctx.font = `${CELL}px monospace`; // a canvas resize resets the font
}
@ -78,13 +74,9 @@ export function MatrixRain() {
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = glyphColor;
for (let i = 0; i < cols; i++) {
const ch = GLYPHS[Math.floor(Math.random() * GLYPHS.length)] ?? "0";
ctx.fillText(ch, i * CELL, (drops[i] ?? 0) * CELL);
if ((drops[i] ?? 0) * CELL > canvas.height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i] = (drops[i] ?? 0) + 1;
ctx.fillText(glyphFor(Math.random), i * CELL, (drops[i] ?? 0) * CELL);
}
drops = stepDrops(drops, canvas.height, Math.random);
}
let timer: number | null = null;