The Matrix movie trilogy has left a lasting impression on pop culture, particularly with its iconic “digital rain” effect. This effect, representing the flowing green code of the Matrix’s virtual reality, has been replicated countless times. Today, we’ll delve into a JavaScript code snippet that recreates this captivating visual.
The Complete Code
function loadMatrixFont() { const link = document.createElement('link'); link.href = "https://fonts.cdnfonts.com/css/matrix-code-nfi"; link.rel = "stylesheet"; document.head.appendChild(link); } function isFontLoaded(fontName) { const testString = "abcdefghijklmnopqrstuvwxyz0123456789"; const testSize = "72px"; const testElement = document.createElement("span"); testElement.style.fontSize = testSize; testElement.style.position = "absolute"; testElement.style.left = "-9999px"; testElement.style.visibility = "hidden"; testElement.style.fontFamily = "sans-serif"; testElement.innerText = testString; document.body.appendChild(testElement); const defaultWidth = testElement.offsetWidth; const defaultHeight = testElement.offsetHeight; testElement.style.fontFamily = fontName + ", sans-serif"; const newWidth = testElement.offsetWidth; const newHeight = testElement.offsetHeight; document.body.removeChild(testElement); return defaultWidth !== newWidth || defaultHeight !== newHeight; } function waitForFontLoad(fontName, callback) { const interval = setInterval(() => { if (isFontLoaded(fontName)) { clearInterval(interval); callback(); } }, 100); } function startMatrixEffect() { loadMatrixFont(); // Load the Matrix font dynamically waitForFontLoad("Matrix Code NFI", () => { const slideLayer = document.querySelector('.slide-layer.base-layer.shown'); if (!slideLayer) { console.error("Element with class 'slide-layer base-layer shown' not found."); return; } const textStrip = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm']; const stripCount = 100; // Increased density const stripElements = []; const stripY = new Array(stripCount).fill(-100); const dY = Array.from({ length: stripCount }, () => Math.floor(Math.random() * 5) + 2); const theColors = ['#cefbe4', '#81ec72', '#5cd646', '#54d13c', '#4ccc32', '#43c728']; for (let i = 0; i < stripCount; i++) { const strip = document.createElement('div'); strip.style.position = 'absolute'; strip.style.left = `${Math.floor(Math.random() * (slideLayer.clientWidth - 20))}px`; // Adjust font size range here strip.style.fontSize = `${Math.floor(Math.random() * 20) + 16}px`; strip.style.zIndex = 9999; // Ensure it's above everything else strip.style.fontFamily = "'Matrix Code NFI', sans-serif"; // Use the Matrix font strip.style.color = theColors[0]; strip.innerText = textStrip[Math.floor(Math.random() * textStrip.length)]; slideLayer.appendChild(strip); stripElements.push(strip); } function draw() { for (let j = 0; j < stripCount; j++) { if (stripY[j] > slideLayer.clientHeight) { stripElements[j].style.left = `${Math.floor(Math.random() * (slideLayer.clientWidth - 20))}px`; stripY[j] = -100; dY[j] = Math.floor(Math.random() * 5) + 2; } stripY[j] += dY[j]; stripElements[j].style.top = `${stripY[j]}px`; if (Math.random() > 0.9) { stripElements[j].innerText = textStrip[Math.floor(Math.random() * textStrip.length)]; stripElements[j].style.color = theColors[Math.floor(Math.random() * theColors.length)]; } } requestAnimationFrame(draw); } draw(); }); } startMatrixEffect();
Understanding the Code
Let’s break down the JavaScript code step-by-step to understand how it conjures up this Matrix-inspired spectacle.
1. Loading the Matrix Font
The code kicks off by loading the distinctive Matrix font loadMatrixFont(). It dynamically adds a stylesheet link to the document’s <head>
, ensuring the browser can render the text in that signature Matrix style.
2. Checking if the Font is Loaded
This function isFontLoaded(); verifies whether the specified font has been successfully loaded by the browser. It does this by comparing the dimensions of a test string rendered with a generic font against the same string rendered with the target font. If the dimensions differ, it indicates the target font is active.
3. Waiting for the Font to Load
This function waitForFontLoad(); patiently waits for the font to load before proceeding. It sets up an interval that repeatedly checks if the font is loaded using isFontLoaded
. Once the font is ready, it clears the interval and executes a provided callback function.
4. Starting the Matrix Effect
This is where the magic happens. The code:
- Loads the Matrix font.
- Waits for the font to load.
- Finds the target element where the effect will be displayed.
- Creates multiple “strips” of characters that will cascade down the screen.
- Animates these strips, giving them random positions, speeds, and characters to mimic the flowing code.
- Uses
requestAnimationFrame
for smooth animation.
Key Points and Enhancements
- The code dynamically loads the Matrix font, ensuring it’s available even if the user doesn’t have it installed locally.
- It waits for the font to load before starting the effect, preventing visual glitches.
- You can customize the effect by adjusting variables like
stripCount
(density of the rain), font size range, colors, and the characters used in the strips. - The code uses
requestAnimationFrame
for optimal performance and battery life.
Conclusion
This JavaScript snippet provides a fascinating glimpse into how to create visually engaging effects using web technologies. It showcases the power of dynamic font loading, animation techniques, and the importance of performance optimization.
Feel free to experiment with the code, tweak its parameters, and create your own unique variations of the Matrix rain effect. Happy coding!