About this snippet

Green characters fall down the screen in columns and leave fading trails behind them, the cyberpunk data stream look that usually sits behind a hero section. It runs full width on a canvas element and resizes with the window.

The trick is that the canvas is never cleared. Every frame paints a black rectangle at 5 percent alpha over the whole thing, dimming what came before a little at a time. That decay is the trail, and there is no per character fade being calculated anywhere.

One array holds the current row for each column. A random character is drawn at that row, the row then advances, and once a drop passes the bottom it gets a small random chance to reset to the top. That randomness is what keeps the columns from marching in step. Font size sets the column width, so raising it thins the rain out.

Size
3.1 KB
Uses
HTML, CSS, JavaScript
Loads
Nothing external
Views
267
<div class="matrix-wrapper">
  <canvas id="matrix-canvas"></canvas>
  <div class="matrix-content">
    <h2>System Access Granted</h2>
    <button class="cyber-btn">Proceed</button>
  </div>
</div>
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  margin: 0;
  background: #000000;
  overflow: hidden;
}

.matrix-wrapper {
  position: relative;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

#matrix-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}

.matrix-content {
  position: relative;
  z-index: 2;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(8px);
  padding: 40px 60px;
  border: 1px solid #10b981;
  border-radius: 8px;
  text-align: center;
  box-shadow: 0 0 30px rgba(16, 185, 129, 0.2);
}

.matrix-content h2 {
  color: #10b981;
  font-family: "Courier New", Courier, monospace;
  font-size: 2rem;
  margin: 0 0 30px 0;
  letter-spacing: 2px;
  text-transform: uppercase;
  text-shadow: 0 0 10px #10b981;
}

.cyber-btn {
  background: transparent;
  color: #10b981;
  border: 2px solid #10b981;
  padding: 12px 32px;
  font-size: 1.125rem;
  font-family: inherit;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 2px;
  cursor: pointer;
  transition: all 0.2s;
  box-shadow: inset 0 0 10px rgba(16, 185, 129, 0.2);
}

.cyber-btn:hover {
  background: #10b981;
  color: #000000;
  box-shadow: 0 0 20px rgba(16, 185, 129, 0.6);
}
const canvas = document.getElementById("matrix-canvas");
const ctx = canvas.getContext("2d");

let width = window.innerWidth;
let height = window.innerHeight;
canvas.width = width;
canvas.height = height;

const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$+-*/=%";
const fontSize = 16;
const columns = Math.floor(width / fontSize);

/* Create an array of drop positions safely using native object */
const drops = new Array();
for (let i = 0; i < columns; i++) {
  drops.push(1);
}

function drawMatrix() {
  /* Fades out old frames slowly to create the trail effect */
  ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
  ctx.fillRect(0, 0, width, height);
  
  ctx.fillStyle = "#10b981";
  ctx.font = fontSize + "px monospace";
  
  for (let i = 0; i < drops.length; i++) {
    /* Pick a random character securely */
    const randIndex = Math.floor(Math.random() * chars.length);
    const text = chars.charAt(randIndex);
    
    /* Calculate X and Y positions */
    const x = i * fontSize;
    const currentDrop = drops.at(i);
    const y = currentDrop * fontSize;
    
    ctx.fillText(text, x, y);
    
    /* Reset drop to top randomly to create staggered falling */
    if (y > height && Math.random() > 0.975) {
      drops.splice(i, 1, 0);
    }
    
    /* Move drop down by one row */
    const newVal = drops.at(i) + 1;
    drops.splice(i, 1, newVal);
  }
}

/* Run the matrix loop */
setInterval(drawMatrix, 30);

window.addEventListener("resize", function() {
  width = window.innerWidth;
  height = window.innerHeight;
  canvas.width = width;
  canvas.height = height;
});
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save