Files
storyteller-bevy/react-frontend/src/app/studio-viewer.tsx
T
Danny McGee cba70a62ae Single-object viewer POC (#14)
This commit implements a Sketchfab-style single-object viewer as a minimal
proof-of-concept.

### `@storyteller/studio-web`
This is a new package to house web components for interfacing with the
`@storyteller/studio` WASM library. It currently includes a single component,
`<sts-viewer />`, which is exported from `@storyteller/studio-web/viewer`.

### `react-frontend`
This is a new application intended as a proof-of-concept and testbed for React
interop with `@storyteller/studio-web`.

Web components are currently a little bit fiddly to use in a React application.
`react-frontend/src/app/studio-viewer.tsx` demonstrates how a React-idiomatic
component can be written as a thin wrapper around a web component, and
`react-frontend/src/app/app.tsx` demonstrates that wrapper component in use.
2023-12-07 15:46:32 -05:00

47 lines
1.1 KiB
TypeScript

import type { SceneStateEvent } from "@storyteller/studio";
import { ViewerElement } from "@storyteller/studio-web/viewer";
import "@storyteller/studio-web/viewer";
import { MutableRefObject, forwardRef, useEffect, useRef } from "react";
export interface Props {
objectId: string;
skyboxId: string;
onSceneStateChange?(event: SceneStateEvent): void;
}
export default forwardRef<ViewerElement, Props>(({
objectId,
skyboxId,
onSceneStateChange,
}, ref) => {
const viewerRef = useRef<ViewerElement>(null);
useEffect(() => {
const viewer = viewerRef.current;
if (viewer && onSceneStateChange) {
viewer.addEventListener("scene-state", onSceneStateChange);
return () => {
viewer.removeEventListener("scene-state", onSceneStateChange);
}
}
}, [ref]);
const refCallback = (viewer: ViewerElement) => {
(viewerRef as MutableRefObject<ViewerElement>).current = viewer;
if (typeof ref === "function")
ref(viewer);
else if (ref != null)
ref.current = viewer;
}
return (
<sts-viewer
ref={refCallback}
objectId={objectId}
skyboxId={skyboxId}
/>
);
});