matrix-effect-react
Version:
Component for using Matrix effect inspired from the Matrix Movies
62 lines (47 loc) • 2.17 kB
JavaScript
/* eslint-disable no-restricted-globals */
import React, { useEffect, useRef } from 'react';
const DEFAULT_TIMEOUT = 20;
const CHARACTERS = ['日', 'ハ', 'ミ', 'ヒ', 'ー', 'ウ', 'シ', 'ナ', 'モ', 'ニ', 'サ', 'ワ', 'ツ', 'オ', 'リ', 'ア', 'ホ', 'テ', 'マ', 'ケ', 'メ', 'エ', 'カ', 'キ', 'ム', 'ユ', 'ラ', 'セ', 'ネ', 'ス', 'タ', 'ヌ', 'ヘ', 'ヲ', 'イ', 'ク', 'コ', 'ソ', 'チ', 'ト', 'ノ', 'フ', 'ヤ', 'ヨ', 'ル', 'レ', 'ロ', 'ン', '0', '1', '2', '3', '4', '5', '7', '8', '9', 'Z', ':', '・', '.', '=', '*', '+', '-', '<', '>', '¦', '|', 'ク']
const STYLES = {
position: 'fixed',
height: '100%',
width: '100v%',
}
function MatrixEffectComponent({ timeout = DEFAULT_TIMEOUT }) {
const canvas = useRef();
useEffect(() => {
const context = canvas.current.getContext('2d');
canvas.current.width = screen.width;
canvas.current.height = screen.height;
context.fillStyle = '#000';
context.fillRect(0, 0, screen.width, screen.height);
const columns = Math.floor(screen.width / 10) + 1;
const yPositions = Array.from({ length: columns }).fill(0);
context.fillStyle = '#000';
context.fillRect(0, 0, screen.width, screen.height);
const interval = setInterval(
() => {
context.fillStyle = '#0001';
context.fillRect(0, 0, screen.width, screen.height);
context.fillStyle = '#0F0';
context.font = '16pt monospace';
yPositions.forEach((y, index) => {
context.fillText(CHARACTERS[Math.floor(Math.random() * CHARACTERS.length)], 20 * index, y);
yPositions[index] = (y > 100 + Math.random() * 10000) ? 0 : (y + 20);
});
}, timeout);
return () => {
clearInterval(interval);
};
}, [canvas, timeout]);
return (
<div
style={STYLES}
>
<canvas
ref={canvas}
/>
</div>
);
}
export default MatrixEffectComponent;