Introducing Nuvyx UI v1.0.0

Matrix Code Rain

A customizable Matrix-style digital rain effect that can be used as a background or in a container.

Installation Guide

1

Install Dependencies

Utility Functions

npm install clsx tailwind-merge
2

Setup Configuration

Create file: /lib/utils.ts

Create a utils.ts file with the cn utility function

/lib/utils.ts
1import { clsx, type ClassValue } from "clsx";
2import { twMerge } from "tailwind-merge";
3
4export function cn(...inputs: ClassValue[]) {
5  return twMerge(clsx(inputs));
6}
3

Copy Component Code

Matrix Code Rain.tsx
1"use client";
2import { cn } from "@/lib/utils";
3import React, { useEffect, useRef } from "react";
4
5type MatrixCodeRainProps = {
6  color?: string;
7  charset?: string;
8  fontSize?: number;
9  fps?: number;
10  opacity?: number;
11  fullScreen?: boolean;
12  width?: string;
13  height?: string;
14};
15
16export const MatrixCodeRain = ({
17  color = "#00ff00",
18  charset = "0123#!$^&456789ABCDEFRLY",
19  fontSize = 16,
20  fps = 20,
21  opacity = 0.05,
22  fullScreen = false,
23  width = "100%",
24  height = "400px",
25}: MatrixCodeRainProps) => {
26  const canvasRef = useRef<HTMLCanvasElement>(null);
27  const animationRef = useRef<number | null>(null);
28  const particlesRef = useRef<number[]>([]);
29
30  useEffect(() => {
31    const canvas = canvasRef.current;
32    if (!canvas) return;
33
34    const ctx = canvas.getContext("2d");
35    if (!ctx) return;
36
37    let w = 0,
38      h = 0;
39    let lastFrameTime = 0;
40    const frameInterval = 1000 / fps;
41
42    const resize = () => {
43      const container = canvas.parentElement;
44      if (!container) return;
45
46      if (fullScreen) {
47        w = canvas.width = window.innerWidth;
48        h = canvas.height = window.innerHeight;
49      } else {
50        w = canvas.width = container.clientWidth;
51        h = canvas.height = container.clientHeight;
52      }
53
54      particlesRef.current = new Array(Math.ceil(w / fontSize)).fill(0);
55    };
56
57    const random = (items: string) =>
58      items[Math.floor(Math.random() * items.length)];
59
60    const draw = (timestamp: number) => {
61      if (timestamp - lastFrameTime >= frameInterval) {
62        ctx.fillStyle = `rgba(0,0,0,${opacity})`;
63        ctx.fillRect(0, 0, w, h);
64        ctx.fillStyle = color;
65        ctx.font = `${fontSize}px monospace`;
66
67        for (let i = 0; i < particlesRef.current.length; i++) {
68          const v = particlesRef.current[i];
69          ctx.fillText(random(charset), i * fontSize, v);
70          particlesRef.current[i] =
71            v >= h || v >= 10000 * Math.random() ? 0 : v + fontSize;
72        }
73
74        lastFrameTime = timestamp;
75      }
76
77      animationRef.current = requestAnimationFrame(draw);
78    };
79
80    const handleResize = () => resize();
81
82    window.addEventListener("resize", handleResize);
83    resize();
84    animationRef.current = requestAnimationFrame(draw);
85
86    return () => {
87      window.removeEventListener("resize", handleResize);
88      if (animationRef.current) {
89        cancelAnimationFrame(animationRef.current);
90      }
91    };
92  }, [color, charset, fontSize, fps, opacity, fullScreen]);
93
94  return (
95    <div
96      className={cn("relative overflow-hidden")}
97      style={{
98        width: fullScreen ? "100vw" : width,
99        height: fullScreen ? "100vh" : height,
100      }}
101    >
102      <canvas
103        ref={canvasRef}
104        className="block"
105        style={{
106          position: fullScreen ? "fixed" : "absolute",
107          top: 0,
108          left: 0,
109          width: "100%",
110          height: "100%",
111          zIndex: fullScreen ? -1 : "auto",
112        }}
113      />
114    </div>
115  );
116};
117
4

Final Steps

Update Import Paths

Make sure to update the import paths in the component code to match your project structure. For example, change @/components/ui/button to match your UI components location.

Examples

Custom Characters
Hieroglyphic

Props

NameTypeDefaultDescription
colorstring"#00ff00"The color of the matrix characters
charsetstring"0123#!$^&456789ABC"The set of characters to display in the animation
fontSizenumber16The size of the characters in pixels
fpsnumber20Frames per second - controls animation speed
opacitynumber0.05The opacity of the fade effect (0-1)
fullScreenbooleanfalseWhether to display the effect as a fullscreen background
widthstring"100%"The width of the container when not in fullscreen mode
heightstring"400px"The height of the container when not in fullscreen mode