File size: 2,318 Bytes
5a81b95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { useEffect, useRef } from 'react';

const MatrixRain = () => {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    const characters = 'をむウエγ‚ͺγ‚«γ‚­γ‚―γ‚±γ‚³γ‚΅γ‚·γ‚Ήγ‚»γ‚½γ‚Ώγƒγƒ„γƒ†γƒˆγƒŠγƒ‹γƒŒγƒγƒŽγƒγƒ’γƒ•γƒ˜γƒ›γƒžγƒŸγƒ γƒ‘γƒ’γƒ€γƒ¦γƒ¨γƒ©γƒͺルレロワヲン0123456789ABCDEF<>{}[]|/\\';
    const columnWidth = 20;
    const numColumns = Math.ceil(window.innerWidth / columnWidth);
    
    const columns: HTMLDivElement[] = [];

    for (let i = 0; i < numColumns; i++) {
      const column = document.createElement('div');
      column.className = 'absolute top-0 font-mono text-xs leading-tight select-none pointer-events-none';
      column.style.left = `${i * columnWidth}px`;
      column.style.animationDelay = `${Math.random() * 5}s`;
      column.style.animationDuration = `${5 + Math.random() * 10}s`;
      
      const numChars = Math.floor(Math.random() * 20) + 10;
      let html = '';
      
      for (let j = 0; j < numChars; j++) {
        const char = characters[Math.floor(Math.random() * characters.length)];
        const opacity = 1 - (j / numChars);
        const isHead = j === 0;
        html += `<div style="opacity: ${opacity * 0.6}; color: ${isHead ? 'hsl(166, 100%, 70%)' : 'hsl(166, 100%, 50%)'}">${char}</div>`;
      }
      
      column.innerHTML = html;
      column.style.animation = `matrix-fall ${8 + Math.random() * 8}s linear infinite`;
      column.style.animationDelay = `${-Math.random() * 15}s`;
      
      columns.push(column);
      container.appendChild(column);
    }

    // Update characters periodically
    const interval = setInterval(() => {
      columns.forEach(column => {
        const divs = column.querySelectorAll('div');
        divs.forEach(div => {
          if (Math.random() > 0.95) {
            div.textContent = characters[Math.floor(Math.random() * characters.length)];
          }
        });
      });
    }, 100);

    return () => {
      clearInterval(interval);
      columns.forEach(col => col.remove());
    };
  }, []);

  return (
    <div 
      ref={containerRef}
      className="fixed inset-0 overflow-hidden pointer-events-none z-0"
      style={{ opacity: 0.15 }}
    />
  );
};

export default MatrixRain;