@@ -46,6 +46,53 @@ const {
4646 <div class =" bg-gradient" aria-hidden =" true" ></div >
4747 <div class =" bg-overlay" aria-hidden =" true" ></div >
4848
49+ <!-- Matrix rain -->
50+ <canvas id =" matrix-rain" class =" fixed inset-0 pointer-events-none" style =" z-index:1;opacity:0.12" aria-hidden =" true" ></canvas >
51+
4952 <slot />
53+
54+ <script >
55+ const canvas = document.getElementById('matrix-rain') as HTMLCanvasElement;
56+ if (canvas) {
57+ const ctx = canvas.getContext('2d')!;
58+ let w = 0, h = 0;
59+ let columns = 0;
60+ const drops: number[] = [];
61+ const chars = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン0123456789ABCDEF{}[]<>/\\|=+-*&^%$#@!';
62+ const fontSize = 14;
63+ const colors = ['#7c6aef', '#a594ff', '#6050d0', '#4ade80', '#22d3ee'];
64+
65+ function resize() {
66+ w = canvas.width = window.innerWidth;
67+ h = canvas.height = window.innerHeight;
68+ const newCols = Math.floor(w / fontSize);
69+ while (drops.length < newCols) drops.push(Math.random() * -100);
70+ drops.length = newCols;
71+ columns = newCols;
72+ }
73+
74+ function draw() {
75+ ctx.fillStyle = 'rgba(18, 20, 31, 0.15)';
76+ ctx.fillRect(0, 0, w, h);
77+ ctx.font = `${fontSize}px monospace`;
78+
79+ for (let i = 0; i < columns; i++) {
80+ const char = chars[Math.floor(Math.random() * chars.length)];
81+ ctx.fillStyle = colors[Math.floor(Math.random() * colors.length)];
82+ ctx.fillText(char, i * fontSize, drops[i] * fontSize);
83+
84+ if (drops[i] * fontSize > h && Math.random() > 0.975) {
85+ drops[i] = 0;
86+ }
87+ drops[i] += 0.2 + Math.random() * 0.2;
88+ }
89+ requestAnimationFrame(draw);
90+ }
91+
92+ resize();
93+ window.addEventListener('resize', resize);
94+ draw();
95+ }
96+ </script >
5097 </body >
5198</html >
0 commit comments