Code Rain

v1.0.0
FreeWebGLBackgroundInteractive

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

Code Rain

Installation

npx vectorvesper add code-rain

Run npx vectorvesper init once first to set up your project.

Dependencies

npm install three @react-three/fiber
  • three
  • @react-three/fiber

Usage

Import

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

Usage

<CodeRain />

Client-only component — disable SSR

This component uses WebGL and must be rendered client-side only.

import dynamic from "next/dynamic";

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

Props

An interactive canvas matrix code rain shader built on WebGL. Pressing keys or clicking the screen injects energetic heat bursts into the character grid that ripple outward and fade over time. Features customized grid density, horizontal scanline overlays, and color mixes.

<CodeRainVisualizer />

WebGL canvas component displaying the matrix digital rain simulation.

PropTypeDefaultDescription
backgroundColorstring"#000000"Canvas background hex color.
color1string"#001a0a"Primary color for cold/faded background glyph streams.
color2string"#00ff66"Secondary color for active, high-intensity particle trails and keypress explosions.
gridResolutionnumber80.0Visual density of character columns. Higher values result in smaller, denser characters.
intensityDecaynumber0.96Multiplier applied per frame to decay the visual excitement of key/mouse bursts.
explosionRadiusnumber30.0Maximum radius (in grid cells) of the heat impact ripple on key/mouse clicks.
glowIntensitynumber0.4Additive glow intensity overlay applied to hot cells (0.0 to 1.0).
scanlineIntensitynumber0.0Opacity of the CRT horizontal scanline shader filter overlay.
trailSpeednumber0.12Speed coefficient at which streams flow downwards.
burstPattern"digital" | "circular""digital"Splat shape pattern on mouse click: digital (angular blocks) or circular (smooth radial falloff).
classNamestring""Class name applied to the outer canvas wrapping div.

Examples

Classic Matrix Green
<CodeRainVisualizer />
Gold Digital RainCustom amber/gold palette with high density.
<CodeRainVisualizer
  color1="#241700"
  color2="#ffb700"
  gridResolution={100}
  trailSpeed={0.08}
/>
Circular Burst OverlayLow-density grid with large explosion zones.
<CodeRainVisualizer
  gridResolution={50}
  explosionRadius={50}
  burstPattern="circular"
  glowIntensity={0.8}
/>
Uses raw WebGL context and CanvasRenderingContext2D. Strictly client-side — requires dynamic loading with ssr: false to prevent build crashes.

Source

"use client";
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 });
  useEffect(() => {
    propsRef.current = { explosionRadius, intensityDecay, trailSpeed, burstPattern };
  }, [explosionRadius, intensityDecay, trailSpeed, burstPattern]);

  if (setupRef.current === null && typeof window !== "undefined") {
    const can = document.createElement("canvas");
    can.width = 512;
    can.height = 512;
    const context = can.getContext("2d");
View on GitHub →Report an issue