<!DOCTYPE html>
Three.js Matrix Code Scene body { margin: 0; overflow: hidden; background-color: #111827; } canvas { display: block; width: 100vw; height: 100vh; }// Global variables for parent interactivity
var controls;
var grid;
// Main initialization
(function() {
// 1. Scene Setup
const scene = new THREE.Scene();
scene.background = new THREE.Color('#111827');
// Add some fog for depth
scene.fog = new THREE.FogExp2('#111827', 0.02);
// 2. Camera Setup
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 10, 40);
// 3. Renderer Setup
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
// 4. OrbitControls
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.autoRotate = true;
controls.autoRotateSpeed = 0.5;
// 5. Lights
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const dirLight = new THREE.DirectionalLight(0x00ff00, 0.8);
dirLight.position.set(10, 20, 10);
scene.add(dirLight);
// 6. Grid Helper
grid = new THREE.GridHelper(50, 50, 0x00ff00, 0x1f2937); // Matrix Green lines, dark gray sublines
scene.add(grid);
// 7. Matrix Code Effect (Digital Rain)
// Helper to generate a texture for a character
function createCharTexture(char) {
const size = 64;
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
const ctx = canvas.getContext('2d');
// Transparent background
ctx.fillStyle = "rgba(0,0,0,0)";
ctx.fillRect(0, 0, size, size);
// Glow effect
ctx.shadowBlur = 6;
ctx.shadowColor = "#00ff00";
// Text properties
ctx.font = "bold 40px 'Courier New', monospace";
ctx.fillStyle = "#00ff00"; // Bright Green
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(char, size/2, size/2);
const texture = new THREE.CanvasTexture(canvas);
return texture;
}
// Characters to use
const chars = ['0', '1', 'ク', 'ラ', 'イ', 'ム'];
const particleSystems = [];
// Create a particle system for each character type to vary the look
chars.forEach(char => {
const count = 600; // Particles per character type
const geometry = new THREE.BufferGeometry();
const positions = [];
const velocities = [];
for (let i = 0; i < count; i++) {
// Random positions x, y, z
// Spread wide (x, z) and tall (y)
const x = (Math.random() - 0.5) * 60;
const y = (Math.random() - 0.5) * 60;
const z = (Math.random() - 0.5) * 60;
positions.push(x, y, z);
// Fall speed: random between 0.1 and 0.4
velocities.push(0.1 + Math.random() * 0.3);
}
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
// Custom property to store velocities
geometry.userData = { velocities: velocities };
const material = new THREE.PointsMaterial({
size: 1.5,
map: createCharTexture(char),
transparent: true,
opacity: 0.9,
alphaTest: 0.1,
blending: THREE.AdditiveBlending,
depthWrite: false
});
const points = new THREE.Points(geometry, material);
scene.add(points);
particleSystems.push(points);
});
// 8. Animation Loop
function animate() {
requestAnimationFrame(animate);
// Update Controls (Auto-rotation)
if (controls) controls.update();
// Animate Rain
particleSystems.forEach(system => {
const positions = system.geometry.attributes.position.array;
const velocities = system.geometry.userData.velocities;
for (let i = 0; i < velocities.length; i++) {
// y index is i * 3 + 1
const yIdx = i * 3 + 1;
// Move down
positions[yIdx] -= velocities[i];
// Reset to top if below floor (visual floor is -25 since height is ~50 spread)
if (positions[yIdx] < -25) {
positions[yIdx] = 25;
}
}
// Notify Three.js that positions have changed
system.geometry.attributes.position.needsUpdate = true;
});
renderer.render(scene, camera);
}
animate();
// 9. Resize Handler
window.addEventListener('resize', function() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
})();
// 10. Exposed Global Functions
window.resetCamera = function() {
if (controls) {
controls.reset();
}
};
window.toggleGrid = function() {
if (grid) {
grid.visible = !grid.visible;
}
};
Top comments (0)