@exabytellc/canvas
Version:
EB react canvas!
92 lines • 2.84 kB
JavaScript
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);
}
}
});
}
}
}