UNPKG

@exabytellc/canvas

Version:
92 lines 2.84 kB
import { randomInt } from "@exabytellc/utils"; import { Canime } from "../../../dist"; import { numExponentialTo } from "../../../../utils/src"; export default function CanimeApplyMatrixRain(canime, { color = "#5cfc30", grid = 25, alpha = 0.9, fade = 0.1, matrixSymbols = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ±µΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё٠١٢٣٤٥٦٧٨٩ابتثجحخدذرزسشصضطظعغفقكلمنهوي∇∑√∞∫≈≠≡≤≥♩♪♫♬♭♮♯あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロワヰヱヲンヴ' } = {}) { var cols; var symbols = []; canime.fpsInfinite = false; canime.fpsLimit = 30; canime.interactive = false; canime.onInitiate = ({ width, height }) => { cols = Math.ceil(width / grid); for (let i = -1; i <= cols; i++) { if (!symbols[i]) symbols[i] = MatrixRainSymbol({ x: i, y: randomInt(0, height) }); } }; canime.onRender = ({ ctx, renderObj, clearCanvas }) => { clearCanvas(); ctx.globalAlpha = alpha; ctx.fillStyle = color; ctx.font = `${grid}px monospace`; ctx.textAlign = "center"; ctx.textBaseline = "bottom"; ctx.textRendering = "optimizeSpeed"; symbols.forEach(renderObj); }; function MatrixRainSymbol({ x, y }) { var tails = []; return Canime.createObj({ onRender: ({ renderObj, height }) => { tails.push(Tail({ x, y, t: getSymbol() })); // Update symbol position if (y * grid > height && Math.random() > 0.98) { y = 0; } else { y += 1; } tails.forEach(renderObj); } }); function getSymbol() { const i = randomInt(0, matrixSymbols.length - 1); return matrixSymbols.charAt(i); } function Tail({ x, y, t }) { var opacity = 1; return Canime.createObj({ onRender: ({ ctx }, self) => { ctx.globalAlpha = opacity; const cx = x * grid; const cy = y * grid; ctx.fillText(t, cx, cy); opacity -= numExponentialTo(fade, 0, 1, 0, 1, 5); if (opacity < 0) { tails.splice(tails.indexOf(self), 1); } } }); } } }