matrix.js
1.4 kB · javascript · 50 lines
1import { veil } from './frame.js';23const CELL = 20;4const TICK = 33;5const CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';67export function fell(y, h, roll) {8 return y > h && roll > 0.975;9}1011export function matrix(canvas, view) {12 const ctx = canvas.getContext('2d');13 const rand = view.rand;14 const drops = [];15 let cols = 0;16 const wide = () => view.w / view.dpr;17 const tall = () => view.h / view.dpr;18 const face = () => {19 ctx.setTransform(view.dpr, 0, 0, view.dpr, 0, 0);20 ctx.font = `${CELL}px MrlyFont, monospace`;21 ctx.textBaseline = 'alphabetic';22 };23 const wash = () => {24 ctx.fillStyle = view.look().paper;25 ctx.fillRect(0, 0, wide(), tall());26 };27 const size = () => {28 face();29 const next = Math.ceil(wide() / CELL);30 for (let i = cols; i < next; i++) drops[i] = cols ? rand() * (tall() / CELL) : 1;31 cols = next;32 wash();33 };34 const draw = () => {35 const skin = view.look();36 const h = tall();37 ctx.fillStyle = veil(skin.paper, 0.05);38 ctx.fillRect(0, 0, wide(), h);39 ctx.fillStyle = skin.accent;40 for (let i = 0; i < cols; i++) {41 const y = drops[i] * CELL;42 ctx.fillText(CHARS.charAt(Math.floor(rand() * CHARS.length)), i * CELL, y);43 if (fell(y, h, rand())) drops[i] = 0;44 drops[i]++;45 }46 };47 size();48 document.fonts?.ready.then(face);49 return { every: TICK, draw, size, theme: wash };50}