Skip to content

Instantly share code, notes, and snippets.

@Earu
Last active October 10, 2024 13:10
Show Gist options
  • Save Earu/a8777f590a2cf7516ba2e6b7c14b4391 to your computer and use it in GitHub Desktop.
Save Earu/a8777f590a2cf7516ba2e6b7c14b4391 to your computer and use it in GitHub Desktop.
A simple matrix effect adapted into a React component.
import { HTMLAttributes, useEffect, useRef } from "react";
export default function Matrix(props: HTMLAttributes<HTMLCanvasElement> & { stripCount?: number }): JSX.Element {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const context = canvas.getContext('2d');
if (!context) return;
context.globalCompositeOperation = 'lighter';
const textStrip = ['诶', '比', '西', '迪', '伊', '吉', '艾', '杰', '开', '哦', '屁', '提', '维'];
const stripCount = props.stripCount ?? 5, stripX = new Array(), stripY = new Array(), dY = new Array(), stripFontSize = new Array();
for (let i = 0; i < stripCount; i++) {
stripX[i] = Math.floor(Math.random() * canvas.width);
stripY[i] = -100;
dY[i] = Math.floor(Math.random() * 4) + 2;
stripFontSize[i] = Math.floor(Math.random() * 4) + 2;
}
const theColors = ['#cefbe4', '#81ec72', '#5cd646', '#54d13c', '#4ccc32', '#43c728'];
function drawStrip(x: number, y: number) {
if (!context) return;
for (var k = 0; k <= 20; k++) {
var randChar = textStrip[Math.floor(Math.random() * textStrip.length)];
if (context.fillText) {
switch (k) {
case 0:
context.fillStyle = theColors[0]; break;
case 1:
context.fillStyle = theColors[1]; break;
case 3:
context.fillStyle = theColors[2]; break;
case 7:
context.fillStyle = theColors[3]; break;
case 13:
context.fillStyle = theColors[4]; break;
case 17:
context.fillStyle = theColors[5]; break;
}
context.fillText(randChar, x, y);
}
y -= stripFontSize[k];
}
}
function draw() {
if (!context || !canvas) return;
// clear the canvas and set the properties
context.clearRect(0, 0, canvas.width, canvas.height);
context.shadowOffsetX = context.shadowOffsetY = 0;
context.shadowBlur = 8;
context.shadowColor = '#94f475';
for (let j = 0; j < stripCount; j++) {
context.font = stripFontSize[j] + 'px MatrixCode';
context.textBaseline = 'top';
context.textAlign = 'center';
if (stripY[j] > canvas.height + 100) {
stripX[j] = Math.floor(Math.random() * canvas.width);
stripY[j] = -100;
dY[j] = Math.floor(Math.random() * 7) + 3;
stripFontSize[j] = Math.floor(Math.random() * 16) + 8;
drawStrip(stripX[j], stripY[j]);
} else drawStrip(stripX[j], stripY[j]);
stripY[j] += dY[j];
}
setTimeout(draw, 70);
}
draw();
});
return <canvas ref={canvasRef} {...props}/>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment