Massive overhaul: the renderers are now classes that implement Renderer; replaced webpack and rollup with vite; converted bundle-contents to "core" and "full" bundle profiles; renamed "inclusions" to "staticAssets", which are "url" base64-encoded images and "raw" text strings; renamed the Matrix component module to the JSX extension; built out a test scaffold at tools/test/index.html to manually test the various deploy options.

This commit is contained in:
Rezmason
2025-05-23 12:49:10 -07:00
parent 658f07c6ab
commit 3b837c6f06
29 changed files with 2338 additions and 6918 deletions

48
tools/test/index.html Normal file
View File

@@ -0,0 +1,48 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<details open id="test-standard">
<summary><strong>standard</strong></summary>
<iframe src="../../index.html?version=palimpsest"></iframe>
</details>
<details open id="test-react">
<summary><strong>standard react</strong></summary>
<div id="test-react-container"></div>
<script type="module" src="test-react.jsx?root-id=test-react-container"></script>
</details>
<details id="test-core-bundled">
<summary><strong>core bundled</strong></summary>
<script type="module">
import { REGLRenderer, WebGPURenderer, makeConfig } from "../../dist/digital-rain.core.js";
const useWebGPU = false;
const RendererClass = useWebGPU ? WebGPURenderer : REGLRenderer;
const renderer = new RendererClass();
await renderer.ready;
document.querySelector("#test-core-bundled").appendChild(renderer.canvas);
await renderer.formulate(makeConfig({once: false}));
</script>
</details>
<details id="test-core-react-bundled">
<summary><strong>core react bundled</strong></summary>
<div id="test-core-react-bundled-container"></div>
<script type="module" src="test-react.jsx?bundle=core&root-id=test-core-react-bundled-container"></script>
</details>
<details id="test-full-bundled">
<summary><strong>full bundled</strong></summary>
<script type="module">
import { REGLRenderer, WebGPURenderer, makeConfig } from "../../dist/digital-rain.full.js";
const useWebGPU = false;
const RendererClass = useWebGPU ? WebGPURenderer : REGLRenderer;
const renderer = new RendererClass();
await renderer.ready;
document.querySelector("#test-full-bundled").appendChild(renderer.canvas);
await renderer.formulate(makeConfig({once: false, version: "twilight"}));
</script>
</details>
</body>
</html>

144
tools/test/test-react.jsx Normal file
View File

@@ -0,0 +1,144 @@
import React, { useState } from "react";
import { unmountComponentAtNode } from "react-dom";
import { createRoot } from "react-dom/client";
const urlParams = new URLSearchParams(import.meta.url.replaceAll(/.*?\?/g, ""));
const rootID = urlParams.get("root-id") ?? "root";
const root = createRoot(document.getElementById(rootID));
let componentModule;
switch (urlParams.get("bundle")) {
case "core": {
componentModule = (await import("../../dist/digital-rain.core.js"));
break;
}
default: {
componentModule = (await import("../../js/Matrix"));
}
}
const { Matrix } = componentModule;
const versions = [
"classic",
"3d",
"resurrections",
"operator",
"megacity",
"nightmare",
"paradise",
"trinity",
"bugs",
"morpheus",
];
const effects = ["none", "palette", "stripes", "pride", "trans", "image", "mirror"];
const App = () => {
const [version, setVersion] = useState(versions[0]);
const [effect, setEffect] = useState("palette");
const [numColumns, setNumColumns] = useState(80);
const [resolution, setResolution] = useState(0.75);
const [cursorColor, setCursorColor] = useState(null);
const [backgroundColor, setBackgroundColor] = useState("0,0,0");
const [rendererType, setRendererType] = useState(null);
const [density, setDensity] = useState(2);
const [destroyed, setDestroyed] = useState(false);
const onVersionButtonClick = () => {
setVersion((s) => {
let index = versions.indexOf(version) + 1;
if (index === versions.length) {
index = 0;
}
const newVersion = versions[index];
console.log("version:", newVersion);
return newVersion;
});
setCursorColor(null);
setBackgroundColor(null);
};
const onEffectButtonClick = () => {
setEffect((s) => {
let index = effects.indexOf(effect) + 1;
if (index === effects.length) {
index = 0;
}
const newEffect = effects[index];
console.log("effect:", newEffect);
return newEffect;
});
setCursorColor(null);
setBackgroundColor(null);
};
const onRendererButtonClick = () => {
setRendererType(() => (rendererType === "webgpu" ? "regl" : "webgpu"));
};
const onDestroyButtonClick = () => {
setDestroyed(true);
};
return (
<>
<button onClick={onVersionButtonClick}>Version: "{version}"</button>
<button onClick={onEffectButtonClick}>Effect: "{effect}"</button>
<button onClick={onRendererButtonClick}>Renderer: {rendererType ?? "default (regl)"}</button>
<button onClick={onDestroyButtonClick}>Destroy</button>
<label htmlFor="cursor-color">Cursor color: </label>
<input
name="cursor-color"
type="color"
onChange={(e) => {
const values = e.target.value
.match(/[\da-fA-F]{2}/g)
.map((s) => parseInt(s, 16) / 0xff)
.join(",");
setCursorColor(values);
}}
/>
<label htmlFor="background-color">Background color: </label>
<input
name="background-color"
type="color"
onChange={(e) => {
const values = e.target.value
.match(/[\da-fA-F]{2}/g)
.map((s) => parseInt(s, 16) / 0xff)
.join(",");
setBackgroundColor(values);
}}
/>
<label htmlFor="num-columns"># of columns:</label>
<input
name="num-columns"
type="range"
value={numColumns}
min="10"
max="160"
step="1"
onInput={(e) => setNumColumns(parseInt(e.target.value))}
/>
<label htmlFor="resolution">resolution:</label>
<input
name="resolution"
type="range"
value={resolution}
min="0"
max="1"
step="0.01"
onInput={(e) => setResolution(parseFloat(e.target.value))}
/>
{!destroyed && (
<Matrix
style={{ width: "40vw", height: "22vh" }}
version={version}
effect={effect}
numColumns={numColumns}
resolution={resolution}
renderer={rendererType}
cursorColor={cursorColor}
backgroundColor={backgroundColor}
density={2.0}
/>
)}
</>
);
};
root.render(<App />);