diff options
Diffstat (limited to 'themes/danix-xyz-hacker/assets/js/matrix-rain.js')
| -rw-r--r-- | themes/danix-xyz-hacker/assets/js/matrix-rain.js | 157 |
1 files changed, 0 insertions, 157 deletions
diff --git a/themes/danix-xyz-hacker/assets/js/matrix-rain.js b/themes/danix-xyz-hacker/assets/js/matrix-rain.js deleted file mode 100644 index 53c55d8..0000000 --- a/themes/danix-xyz-hacker/assets/js/matrix-rain.js +++ /dev/null @@ -1,157 +0,0 @@ -// Matrix rain background effect -(function() { - // Bail out if user prefers reduced motion - if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { - return; - } - - // Canvas and context - let canvas = document.getElementById('matrix-rain'); - if (!canvas) return; - const ctx = canvas.getContext('2d'); - - // State - let columns = []; - let frameCount = 0; - let colors = { accent: '#a855f7', accent2: '#00ff88', bg: '#060b10', head: '#ffffff' }; - - // Character set: 30% ASCII, 70% katakana - const ASCII = Array.from({ length: 94 }, (_, i) => String.fromCharCode(33 + i)); - const KATA = Array.from({ length: 96 }, (_, i) => String.fromCodePoint(0x30a0 + i)); - const CHARS = shuffle([...ASCII, ...KATA, ...KATA, ...KATA]); - - // Utility: shuffle array - function shuffle(arr) { - for (let i = arr.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [arr[i], arr[j]] = [arr[j], arr[i]]; - } - return arr; - } - - // Utility: convert hex or rgb color to rgba string - function hexToRgba(color, alpha) { - const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/); - if (rgbMatch) { - return `rgba(${rgbMatch[1]}, ${rgbMatch[2]}, ${rgbMatch[3]}, ${alpha})`; - } - const hex = color.replace('#', ''); - const r = parseInt(hex.substring(0, 2), 16); - const g = parseInt(hex.substring(2, 4), 16); - const b = parseInt(hex.substring(4, 6), 16); - return `rgba(${r}, ${g}, ${b}, ${alpha})`; - } - - // Sample CSS variables based on current theme - function sampleColors() { - const style = getComputedStyle(document.documentElement); - const isDark = document.documentElement.classList.contains('theme-dark'); - colors.accent = style.getPropertyValue('--accent').trim(); - colors.accent2 = style.getPropertyValue('--accent2').trim(); - colors.bg = style.getPropertyValue('--bg').trim(); - // Head char: bright white in dark mode, deep purple-black in light mode - colors.head = isDark ? '#ffffff' : '#1a0533'; - } - - // Resize canvas to window dimensions - function resizeCanvas() { - canvas.width = window.innerWidth; - canvas.height = window.innerHeight; - ctx.font = '14px "JetBrains Mono", monospace'; - ctx.textBaseline = 'top'; - initColumns(); - } - - // Initialize columns for the current canvas width - function initColumns() { - columns = []; - const columnWidth = 14; - const columnCount = Math.floor(canvas.width / columnWidth); - - for (let i = 0; i < columnCount; i++) { - columns.push({ - x: i * columnWidth, - y: -Math.floor(Math.random() * 40), // stagger start above viewport - speed: 2 + Math.floor(Math.random() * 3), // 2-4 frames between drops - color: Math.random() < 0.6 ? 'accent2' : 'accent', // 60% green, 40% purple - charIndex: Math.floor(Math.random() * CHARS.length), - length: 8 + Math.floor(Math.random() * 13), // trail length 8-20 - }); - } - } - - // Set up MutationObserver for theme switching - function setupThemeObserver() { - const observer = new MutationObserver(function(mutations) { - for (const m of mutations) { - if (m.attributeName === 'class') { - sampleColors(); - break; - } - } - }); - observer.observe(document.documentElement, { - attributes: true, - attributeFilter: ['class'], - }); - } - - // Main animation loop - function drawFrame() { - frameCount++; - - // Fade layer: semi-transparent background fill - ctx.fillStyle = hexToRgba(colors.bg, 0.085); - ctx.fillRect(0, 0, canvas.width, canvas.height); - - // Draw each column - for (const col of columns) { - // Skip if not time to drop yet (per-column throttle) - if (frameCount % col.speed !== 0) continue; - - // Draw explicit trail in column color - ctx.fillStyle = colors[col.color]; - for (let i = 1; i <= col.length; i++) { - const trailY = (col.y - i) * 14; - if (trailY < 0) continue; - const trailCharIndex = (col.charIndex - i + CHARS.length) % CHARS.length; - ctx.fillText(CHARS[trailCharIndex], col.x, trailY); - } - - // Draw head character (bright) - ctx.fillStyle = colors.head; - const headCharIndex = col.charIndex % CHARS.length; - ctx.fillText(CHARS[headCharIndex], col.x, col.y * 14); - - // Advance column - col.y++; - col.charIndex = (col.charIndex + 1) % CHARS.length; - - // Reset when scrolled off screen - if (col.y * 14 > canvas.height + col.length * 14) { - col.y = -Math.floor(Math.random() * 20); - col.charIndex = Math.floor(Math.random() * CHARS.length); - col.color = Math.random() < 0.6 ? 'accent2' : 'accent'; - } - } - - requestAnimationFrame(drawFrame); - } - - // Initialize - sampleColors(); - resizeCanvas(); - setupThemeObserver(); - - // Debounced resize handler - let resizeTimer; - window.addEventListener('resize', function() { - clearTimeout(resizeTimer); - resizeTimer = setTimeout(resizeCanvas, 150); - }); - - // Start animation when fonts are ready - document.fonts.ready.then(function() { - requestAnimationFrame(drawFrame); - }); -})(); |
