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}