Der Matrix Regen Effekt ist eine beliebte visuelle Darstellung, die durch den Science-Fiction-Film „Matrix“ berühmt wurde. Er zeigt fallende grüne Zeichen (Symbole) auf einem schwarzen Hintergrund und erzeugt so den Eindruck eines digitalen Regens. Dieser Effekt ist ein ikonisches Beispiel für die Darstellung von Computercode oder einer virtuellen Welt in der Popkultur.
Matrix Regen im Film
Der Matrix Regen Effekt wurde erstmals im Jahr 1999 im Film „Matrix“ von den Wachowski-Geschwistern verwendet. In dieser Filmszene wird der Protagonist Neo in eine virtuelle Welt gebracht, die als „Matrix“ bekannt ist. Dort sieht er fallende grüne Zeichen, die den Code der simulierten Realität darstellen. Dieser Effekt hat sich in der Popkultur fest etabliert und wird häufig verwendet, um eine futuristische, technologische oder virtuelle Atmosphäre zu vermitteln.
Folgendes Video zeigt den Anfang des „Matrix“ films und nach 30 Sekunden auch die Matrix Regen Effekt mit Schriftzeichen.
Matrix Regen als Canvas Animation
Der Matrix Regen Effekt wird in der Regel auf einem Computerbildschirm oder einem Leinwandprojektor angezeigt. Die fallenden grünen Zeichen werden durch eine zufällige Auswahl aus einem begrenzten Satz von Unicode-Zeichen erzeugt. Die Zeichen fallen vertikal von oben nach unten und erscheinen in unregelmäßigen Abständen und Geschwindigkeiten, um den Eindruck eines Regens oder Schneesturms zu erzeugen.
JavaScript Code für den Matrix Regen
Der folgende JavaScript-Code implementiert den Matrix Regen Effekt in einem HTML5 Canvas. Der Code nutzt Konzepte der objektorientierten Programmierung (OOP) und ES6 (ECMAScript 2015), um den Effekt zu erstellen und zu steuern. Er verwendet Klassen, um die verschiedenen Komponenten des Effekts zu organisieren, und ES6-Features wie private Methoden (#initialize
, #resizeCanvas
, #animate
) und die class
-Syntax.
class Symbol { constructor(x, y, fontSize, canvasHeight){ this.characters = '0123456789'; this.x = x; this.y = y; this.fontSize = fontSize; this.text = ''; this.canvasHeight = canvasHeight; } draw(ctx){ this.text = this.characters.charAt( Math.floor( Math.random() * this.characters.length ) ); ctx.fillText(this.text, this.x * this.fontSize, this.y * this.fontSize); if( this.y * this.fontSize > this.canvasHeight && Math.random() > 0.95 ){ this.y = 0; } else { this.y += 1; } } } class MatrixRain { constructor(canvasWidth, canvasHeight){ this.canvasWidth = canvasWidth; this.canvasHeight = canvasHeight; this.fontSize = 24; this.columns = this.canvasWidth / this.fontSize; this.symbols = []; this.#initialize(); } #initialize(){ for(let i = 0; i < this.columns; i++){ this.symbols[i] = new Symbol(i, this.canvasHeight / this.fontSize + this.fontSize , this.fontSize, this.canvasHeight ); } } resize(canvasWidth, canvasHeight){ this.canvasWidth = canvasWidth; this.canvasHeight = canvasHeight; this.columns = this.canvasWidth / this.fontSize this.symbols = []; this.#initialize(); } } class Timer { constructor(fps) { this.fps = fps; this.lastTime = 0; // last Update this.deltaTime = 0; // difference between last and current this.interval = 1000 / this.fps; // next Frame } update(currentTime) { this.deltaTime = currentTime - this.lastTime; } shouldUpdate() { return this.deltaTime > this.interval; // true if difference between last and current > interval } reset(currentTime) { this.lastTime = currentTime; } } class Render { constructor() { this.canvas = document.getElementById('canvas'); this.ctx = this.canvas.getContext("2d"); this.canvas.width = window.innerWidth; this.canvas.height = window.innerHeight; this.matrixrain = new MatrixRain(this.canvas.width, this.canvas.height); this.fps = 20; this.timer = new Timer(this.fps); window.addEventListener('resize', () => this.#resizeCanvas()); } #resizeCanvas() { this.canvas.width = window.innerWidth; this.canvas.height = window.innerHeight; this.matrixrain.resize(this.canvas.width, this.canvas.height); } startAnimation() { this.#animate(0); } #animate(currentTime) { this.timer.update(currentTime); if (this.timer.shouldUpdate()) { this.ctx.fillStyle = 'rgba(0, 0, 0, 0.05)'; // overlay each frame with transparent black to fade out this.ctx.textAlign = 'center'; this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); this.ctx.fillStyle = '#0aff0a'; this.ctx.font = this.matrixrain.fontSize + 'px monospace'; this.matrixrain.symbols.forEach(symbol => symbol.draw(this.ctx)); this.timer.reset(currentTime); } requestAnimationFrame((timeStamp) => this.#animate(timeStamp)); } } window.onload = () => { const render = new Render(); render.startAnimation(); };
- Symbol-Klasse: Diese Klasse repräsentiert ein einzelnes fallendes Zeichen (Symbol) im Effekt. Sie enthält die Eigenschaften
x
undy
für die Position,fontSize
für die Schriftgröße,text
für den aktuell angezeigten Zeichencode undcanvasHeight
für die Höhe des Canvas. Die Methodedraw(ctx)
wird verwendet, um das Symbol in den übergebenenc
tx (Canvas-Kontext) zu zeichnen. - MatrixRain-Klasse: Diese Klasse ist für die Verwaltung aller fallenden Symbole verantwortlich. Sie wird mit der Breite und Höhe des Canvas initialisiert und erstellt eine Reihe von
Symbol
-Instanzen, die in einem Arraysymbols
gespeichert werden. Die private Methode#initialize
wird verwendet, um die Symbole zu erstellen und zu platzieren. Dieresize
-Methode passt die Größe des Effekts an die Größe des Canvas an. - Timer-Klasse: Diese Klasse steuert die Framerate (FPS) der Animation. Sie verfolgt die Zeit zwischen Frames und aktualisiert den Effekt nur, wenn eine bestimmte Zeitspanne (entsprechend der FPS) vergangen ist.
- Render-Klasse: Diese Klasse ist die zentrale Klasse, die das Canvas verwaltet, den Matrix Regen Effekt erstellt und die Animation startet. Sie initialisiert das Canvas, die
MatrixRain
– undTimer
-Instanzen. Die privaten Methoden#resizeCanvas
und#animate
werden verwendet, um das Canvas bei einer Größenänderung anzupassen und die Animation zu steuern. Die öffentliche MethodestartAnimation
wird verwendet, um die Animation zu starten.
Der gesamte Code verwendet moderne JavaScript-Features wie Klassen, private Methoden und ES6-Syntax, um den Matrix Regen Effekt auf dem Canvas zu erzeugen und zu animieren. Es zeigt, wie mächtig und sauber der Code sein kann, wenn er in einem objektorientierten Stil geschrieben ist und ES6-Funktionen verwendet werden. Durch die Verwendung von Klassen wird der Code auch leichter zu warten und zu erweitern.