Spaces:
Running
Running
File size: 2,584 Bytes
85f2806 | 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 70 71 72 73 74 75 | // Matrix rain effect
function initMatrixRain() {
const canvas = document.createElement('canvas');
const container = document.querySelector('.matrix-rain-overlay');
if (!container) return;
container.appendChild(canvas);
canvas.style.position = 'absolute';
canvas.style.top = '0';
canvas.style.left = '0';
canvas.style.width = '100%';
canvas.style.height = '100%';
canvas.style.opacity = '0.3';
canvas.style.zIndex = '1';
const ctx = canvas.getContext('2d');
canvas.width = container.offsetWidth;
canvas.height = container.offsetHeight;
const katakana = 'アァカサタナハマヤャラワガザダバパイィキシチニヒミリヰギジヂビピウゥクスツヌフムユュルグズブヅプエェケセテネヘメレヱゲゼデベペオォコソトノホモヨョロヲゴゾドボポヴッン';
const latin = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const nums = '0123456789';
const symbols = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
const alphabet = katakana + latin + nums + symbols;
const fontSize = 16;
const columns = canvas.width / fontSize;
const rainDrops = [];
for (let x = 0; x < columns; x++) {
rainDrops[x] = 1;
}
const draw = () => {
ctx.fillStyle = 'rgba(8, 145, 178, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#06b6d4';
ctx.font = fontSize + 'px monospace';
for (let i = 0; i < rainDrops.length; i++) {
const text = alphabet.charAt(Math.floor(Math.random() * alphabet.length));
ctx.fillText(text, i * fontSize, rainDrops[i] * fontSize);
if (rainDrops[i] * fontSize > canvas.height && Math.random() > 0.975) {
rainDrops[i] = 0;
}
rainDrops[i]++;
}
};
setInterval(draw, 30);
window.addEventListener('resize', () => {
canvas.width = container.offsetWidth;
canvas.height = container.offsetHeight;
});
}
document.addEventListener('DOMContentLoaded', () => {
initMatrixRain();
// Animate elements when they come into view
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('animate-fadeIn');
}
});
}, { threshold: 0.1 });
document.querySelectorAll('.feature-card, .hero-section').forEach(el => {
observer.observe(el);
});
}); |