mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-16 21:39:29 -07:00
Matrix React component 1.0.0
This commit is contained in:
140
js/Matrix.js
Normal file
140
js/Matrix.js
Normal file
@@ -0,0 +1,140 @@
|
||||
import React, { useEffect, useRef, memo } from "react";
|
||||
import { createRain, destroyRain } from "./regl/main";
|
||||
import makeConfig from "./utils/config";
|
||||
|
||||
/**
|
||||
* @typedef {object} Colour
|
||||
* @property {"hsl"|"rgb"} space
|
||||
* @property {number[]} values // 3-tuple [0-1] or [0-360,0-1,0-1]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Complete runtime configuration for the Matrix / Digital-Rain component.
|
||||
*
|
||||
* @typedef {{
|
||||
* /* ------------- core identity ------------- * /
|
||||
* version?: (
|
||||
* "classic" | "megacity" | "neomatrixology" | "operator" |
|
||||
* "nightmare" | "paradise" | "resurrections" | "trinity" |
|
||||
* "morpheus" | "bugs" | "palimpsest" | "twilight" |
|
||||
* "holoplay" | "3d" | "throwback" | "updated" |
|
||||
* "1999" | "2003" | "2021" | string /* custom * /
|
||||
* ),
|
||||
* font?: keyof typeof fonts, // "matrixcode", …
|
||||
* effect?: "palette" | "stripe" | string,
|
||||
*
|
||||
* /* ------------- texture assets ------------- * /
|
||||
* baseTexture?: keyof typeof textureURLs | null,
|
||||
* glintTexture?: keyof typeof textureURLs | null,
|
||||
*
|
||||
* /* ------------- global toggles ------------- * /
|
||||
* useCamera?: boolean,
|
||||
* volumetric?: boolean,
|
||||
* loops?: boolean,
|
||||
* skipIntro?: boolean,
|
||||
* renderer?: "regl" | "three" | string,
|
||||
* suppressWarnings?: boolean,
|
||||
* useHalfFloat?: boolean,
|
||||
* useHoloplay?: boolean,
|
||||
* isometric?: boolean,
|
||||
*
|
||||
* /* ------------- glyph appearance ------------- * /
|
||||
* glyphEdgeCrop?: number,
|
||||
* glyphHeightToWidth?: number,
|
||||
* glyphVerticalSpacing?: number,
|
||||
* glyphFlip?: boolean,
|
||||
* glyphRotation?: number, // radians (multiples of π/2 supported)
|
||||
*
|
||||
* /* ------------- cursor & glint ------------- * /
|
||||
* isolateCursor?: boolean,
|
||||
* cursorColor?: Colour,
|
||||
* cursorIntensity?: number,
|
||||
* isolateGlint?: boolean,
|
||||
* glintColor?: Colour,
|
||||
* glintIntensity?: number,
|
||||
*
|
||||
* /* ------------- animation & timing ------------- * /
|
||||
* animationSpeed?: number,
|
||||
* fps?: number,
|
||||
* cycleSpeed?: number,
|
||||
* cycleFrameSkip?: number,
|
||||
* fallSpeed?: number,
|
||||
* forwardSpeed?: number,
|
||||
* raindropLength?: number,
|
||||
* slant?: number, // radians
|
||||
*
|
||||
* /* ------------- optical effects ------------- * /
|
||||
* bloomStrength?: number,
|
||||
* bloomSize?: number,
|
||||
* highPassThreshold?: number,
|
||||
* baseBrightness?: number,
|
||||
* baseContrast?: number,
|
||||
* glintBrightness?: number,
|
||||
* glintContrast?: number,
|
||||
* brightnessOverride?: number,
|
||||
* brightnessThreshold?: number,
|
||||
* brightnessDecay?: number,
|
||||
* ditherMagnitude?: number,
|
||||
* hasThunder?: boolean,
|
||||
*
|
||||
* /* ------------- geometry ------------- * /
|
||||
* numColumns?: number,
|
||||
* density?: number,
|
||||
* isPolar?: boolean,
|
||||
* rippleTypeName?: ("circle"|"box"|string|null),
|
||||
* rippleThickness?: number,
|
||||
* rippleScale?: number,
|
||||
* rippleSpeed?: number,
|
||||
*
|
||||
* /* ------------- colour mapping ------------- * /
|
||||
* palette?: {color: Colour, at: number}[],
|
||||
* stripeColors?: Colour[],
|
||||
* backgroundColor?: Colour,
|
||||
* glyphIntensity?: number,
|
||||
*
|
||||
* /* ------------- misc / experimental ------------- * /
|
||||
* resolution?: number,
|
||||
* testFix?: string|null,
|
||||
*
|
||||
* /* ------------- React pass-through ------------- * /
|
||||
* style?: React.CSSProperties,
|
||||
* className?: string,
|
||||
*
|
||||
* /* ------------- catch-all ------------- * /
|
||||
* [key: string]: unknown
|
||||
* }} MatrixProps
|
||||
*/
|
||||
|
||||
/** @param {MatrixProps} props */
|
||||
export const Matrix = memo((props) => {
|
||||
const { style, className, ...rest } = props;
|
||||
const elProps = { style, className };
|
||||
const matrix = useRef(null);
|
||||
const rainRef = useRef(null);
|
||||
const canvasRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.style.width = "100%";
|
||||
canvas.style.height = "100%";
|
||||
canvasRef.current = canvas;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
matrix.current.appendChild(canvasRef.current);
|
||||
const gl = canvasRef.current.getContext("webgl");
|
||||
createRain(canvasRef.current, makeConfig({ ...rest }), gl).then(
|
||||
(handles) => {
|
||||
rainRef.current = handles;
|
||||
}
|
||||
);
|
||||
|
||||
return () => {
|
||||
if (rainRef.current) {
|
||||
destroyRain(rainRef.current);
|
||||
}
|
||||
};
|
||||
}, [props]);
|
||||
|
||||
return <div ref={matrix} {...elProps}></div>;
|
||||
});
|
||||
Reference in New Issue
Block a user