Code Rain

v1.0.1
FreeBackgroundsWebGL

An interactive WebGL matrix digital rain canvas that reacts to mouse clicks and keypress typing bursts.

Code Rain

Framer Remix Link

https://framer.link/lORtp2a

Installation

Step 1. Initialize ProjectOne-time setup

Run once in your project root to configure paths and dependencies:

npx vectorvesper init
Step 2. Add ComponentInstalls source & assets

Downloads and registers the component in your project:

npx vectorvesper add code-rain
Step 3. Required DependenciesAuto-installed with CLI

If installing manually or managing your package lock:

npm install three @react-three/fiber
Packages:three@react-three/fiber

Usage

Import

import CodeRain from "@/components/vv/code-rain/CodeRain";

Usage

<CodeRain />

WebGL — render it on the client only

On Next.js, load it with ssr: false from a Client Component, as below. Vite apps need nothing extra.

"use client";

import dynamic from "next/dynamic";

const CodeRain = dynamic(
  () => import("@/components/vv/code-rain/CodeRain"),
  { ssr: false }
);

Props

A grid of falling characters, terminal-green by default, that scatters where you click. Fills its container and sits behind whatever you put on top of it.

<CodeRainVisualizer />

The full effect. Fills its parent, so give that parent a height.

PropTypeDefaultDescription
backgroundColorstring"#000000"Colour behind the characters.
color1string"#001a0a"Colour of a character at rest — the dim base of the grid.
color2string"#00ff66"Colour of a character at full intensity, right after it is struck.
gridResolutionnumber80.0How many characters fit across the surface. Higher packs them tighter and finer.
trailSpeednumber0.12How fast the rain falls.
intensityDecaynumber0.96How much brightness a character keeps each frame, so how long the trail behind it lingers. Just under 1 gives a long tail; lower numbers cut it short.
glowIntensitynumber0.4Bloom around the brightest characters. 0 leaves them flat.
scanlineIntensitynumber0.05Strength of the horizontal scanlines over the grid. Subtle by default; 0 removes them.
explosionRadiusnumber30.0How far a click's burst reaches across the grid.
burstPattern"digital" | "circular""digital"Shape of that burst. `digital` scatters along the grid's rows and columns; `circular` rings outward from the click.
classNamestringApplied to the wrapper around the canvas.
styleReact.CSSPropertiesMerged onto the wrapper. Width and height are already 100%, so use this for position or z-index rather than size.

Examples

As a background
import CodeRainVisualizer from "@/components/vv/code-rain/CodeRain";

<section className="relative h-screen">
  <div className="absolute inset-0">
    <CodeRainVisualizer />
  </div>
  <h1 className="relative z-10">Click anywhere</h1>
</section>
Slower, denser, in your own palette
<CodeRainVisualizer
  color1="#0a0018"
  color2="#b388ff"
  gridResolution={120}
  trailSpeed={0.06}
  intensityDecay={0.985}
  burstPattern="circular"
  explosionRadius={45}
/>
The rain runs continuously and does not stop for reduced motion. If that matters for your page, render a still background instead when the preference is set.
The whole grid is drawn on the GPU in one pass, so raising gridResolution costs far less than it looks. Pixel ratio is capped at 2.
Client component. It opens a 3D drawing context on mount — import it dynamically with ssr: false if your route renders on the server.

Source

"use client";

/**
 * Code Rain — Vector Vesper
 * https://vectorvesper.dev/components
 *
 * Copyright (c) 2026 Vector Vesper
 * Released under the MIT License. This notice must be retained in copies and
 * substantial portions of the file. https://vectorvesper.dev/license
 */
import React, { useRef, useMemo, useEffect } from "react";
import { Canvas, useFrame, useThree } from "@react-three/fiber";
import * as THREE from "three";

export interface CodeRainProps {
  backgroundColor?: string;
  color1?: string;
  color2?: string;
  gridResolution?: number;
  intensityDecay?: number;
  explosionRadius?: number;
  glowIntensity?: number;
  scanlineIntensity?: number;
  trailSpeed?: number;
  burstPattern?: "digital" | "circular";
  className?: string;
  style?: React.CSSProperties;
}

const CodeRainScene: React.FC<CodeRainProps> = ({
  backgroundColor = "#000000",
  color1 = "#001a0a",
  color2 = "#00ff66",
  gridResolution = 80.0,
  intensityDecay = 0.96,
  explosionRadius = 30.0,
  glowIntensity = 0.4,
  scanlineIntensity = 0.05,
  trailSpeed = 0.12,
  burstPattern = "digital",
}) => {
  const meshRef = useRef<THREE.Mesh<THREE.BufferGeometry, THREE.ShaderMaterial>>(null);
  const { viewport } = useThree();
  const setupRef = useRef<{
    canvas: HTMLCanvasElement;
    ctx: CanvasRenderingContext2D | null;
    heatTexture: THREE.CanvasTexture;
  } | null>(null);

  const propsRef = useRef({ explosionRadius, intensityDecay, trailSpeed, burstPattern });
View on GitHubReport an issue