Files
the-nexus/modules/matrix-rain.js

84 lines
2.8 KiB
JavaScript
Raw Normal View History

// === MATRIX RAIN === + === ASSET LOADER ===
import * as THREE from 'three';
import { S } from './state.js';
// === ASSET LOADER ===
export const loadedAssets = new Map();
// Forward ref: animate() is set by app.js after all modules load
let _animateFn = null;
export function setAnimateFn(fn) { _animateFn = fn; }
export const loadingManager = new THREE.LoadingManager(() => {
document.getElementById('loading-bar').style.width = '100%';
document.getElementById('loading').style.display = 'none';
if (_animateFn) _animateFn();
});
loadingManager.onProgress = (url, itemsLoaded, itemsTotal) => {
const progress = (itemsLoaded / itemsTotal) * 100;
document.getElementById('loading-bar').style.width = `${progress}%`;
};
// === MATRIX RAIN ===
const matrixCanvas = document.createElement('canvas');
matrixCanvas.id = 'matrix-rain';
matrixCanvas.width = window.innerWidth;
matrixCanvas.height = window.innerHeight;
document.body.appendChild(matrixCanvas);
const matrixCtx = matrixCanvas.getContext('2d');
const MATRIX_CHARS = 'アイウエオカキクケコサシスセソタチツテトナニヌネハヒフヘホマミムメモヤユヨラリルレロワヲン0123456789ABCDEF';
const MATRIX_FONT_SIZE = 14;
const MATRIX_COL_COUNT = Math.floor(window.innerWidth / MATRIX_FONT_SIZE);
const matrixDrops = new Array(MATRIX_COL_COUNT).fill(1);
// totalActivity is provided by warp module — imported lazily via a setter
let _totalActivityFn = () => 0;
export function setTotalActivityFn(fn) { _totalActivityFn = fn; }
function drawMatrixRain() {
matrixCtx.fillStyle = 'rgba(0, 0, 8, 0.05)';
matrixCtx.fillRect(0, 0, matrixCanvas.width, matrixCanvas.height);
matrixCtx.font = `${MATRIX_FONT_SIZE}px monospace`;
const activity = _totalActivityFn();
const density = 0.1 + activity * 0.9;
const activeColCount = Math.max(1, Math.floor(matrixDrops.length * density));
for (let i = 0; i < matrixDrops.length; i++) {
if (i >= activeColCount) {
if (matrixDrops[i] * MATRIX_FONT_SIZE > matrixCanvas.height) continue;
}
let char;
if (S._matrixCommitHashes.length > 0 && Math.random() < 0.02) {
const hash = S._matrixCommitHashes[Math.floor(Math.random() * S._matrixCommitHashes.length)];
char = hash[Math.floor(Math.random() * hash.length)];
} else {
char = MATRIX_CHARS[Math.floor(Math.random() * MATRIX_CHARS.length)];
}
const x = i * MATRIX_FONT_SIZE;
const y = matrixDrops[i] * MATRIX_FONT_SIZE;
matrixCtx.fillStyle = '#aaffaa';
matrixCtx.fillText(char, x, y);
const resetThreshold = 0.975 - activity * 0.015;
if (y > matrixCanvas.height && Math.random() > resetThreshold) {
matrixDrops[i] = 0;
}
matrixDrops[i]++;
}
}
setInterval(drawMatrixRain, 50);
window.addEventListener('resize', () => {
matrixCanvas.width = window.innerWidth;
matrixCanvas.height = window.innerHeight;
});