Character Matrix
Falling strings of random characters, as in The Matrix: each column grows a string, then fades it out from the top and starts a new one. After an asciinema recording.
js
const cols = 80;
const rows = 30;
const renderer = cm.terminal({cols, rows, fontWeight: "bold"});
const root = cm.flow().renderer(renderer);
const randomInt = (a, b) => a + Math.floor(Math.random() * (b - a));
const randomChar = () => String.fromCharCode(randomInt(33, 127));
function createString() {
const lifespan = randomInt(0, rows);
const length = randomInt(0, lifespan);
return {lifespan, length, chars: Array.from({length}, randomChar), y: randomInt(0, 15)};
}
// Grow the string while it's alive, then erase it from the top, then replace it.
function updateString(d, i, data) {
const {chars, lifespan, length} = d;
if (lifespan < 0) data[i] = createString();
else if (lifespan <= chars.length) chars[chars.length - lifespan] = "";
else {
for (let j = length - 1; j < chars.length; j++) chars[j] = randomChar();
chars.push(randomChar());
}
d.lifespan--;
}
const strings = Array.from({length: cols}, createString);
setInterval(() => {
root.append(cm.clear, {fill: "black"});
root
.data(strings)
.process(cm.eachRight, updateString)
.append(cm.group, {x: (_, i) => i, y: (d) => d.y})
.data((d) => d.chars)
.append(cm.point, {
x: 0,
y: (_, i) => i,
stroke: (ch) => (ch ? {ch, fg: "#6EBD41"} : null),
});
root.render();
}, 1000 / 15);
document.body.append(renderer.node());