Add: tauri frontend as bevy alternative

This commit is contained in:
DaZuo0122
2026-02-13 09:57:08 +08:00
parent b0f462f63e
commit 3c3ca342c9
33 changed files with 11798 additions and 106 deletions

View File

@@ -0,0 +1,93 @@
import React from "react";
import ReactDOM from "react-dom/client";
import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import { PixiPetRenderer, type UiSpritePack, type UiSnapshot } from "./renderer/pixi_pet";
import "./styles.css";
const UI_BUILD_MARKER = "issue2-fix3";
function App(): JSX.Element {
const [snapshot, setSnapshot] = React.useState<UiSnapshot | null>(null);
const [error, setError] = React.useState<string | null>(null);
const hostRef = React.useRef<HTMLDivElement | null>(null);
const rendererRef = React.useRef<PixiPetRenderer | null>(null);
React.useEffect(() => {
let unlisten: null | (() => void) = null;
let mounted = true;
Promise.all([
invoke<UiSpritePack>("load_active_sprite_pack"),
invoke<UiSnapshot>("current_state")
])
.then(async ([pack, initialSnapshot]) => {
if (!mounted) {
return;
}
setSnapshot(initialSnapshot);
if (hostRef.current !== null) {
rendererRef.current = await PixiPetRenderer.create(
hostRef.current,
pack,
initialSnapshot
);
}
unlisten = await listen<UiSnapshot>("runtime:snapshot", (event) => {
if (!mounted) {
return;
}
const value = event.payload;
setSnapshot(value);
rendererRef.current?.applySnapshot(value);
});
})
.catch((err) => {
if (mounted) {
setError(String(err));
}
});
return () => {
mounted = false;
if (unlisten !== null) {
unlisten();
}
rendererRef.current?.dispose();
rendererRef.current = null;
};
}, []);
return (
<main className="app">
<div className="canvas-host" ref={hostRef} />
<section className="debug-panel">
<h1>sprimo-tauri</h1>
<p>ui build: {UI_BUILD_MARKER}</p>
{error !== null ? <p className="error">{error}</p> : null}
{snapshot === null ? (
<p>Loading snapshot...</p>
) : (
<dl>
<dt>state</dt>
<dd>{snapshot.state}</dd>
<dt>animation</dt>
<dd>{snapshot.current_animation}</dd>
<dt>pack</dt>
<dd>{snapshot.active_sprite_pack}</dd>
<dt>position</dt>
<dd>
{snapshot.x}, {snapshot.y}
</dd>
<dt>scale</dt>
<dd>{snapshot.scale}</dd>
</dl>
)}
</section>
</main>
);
}
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);