45 lines
1.2 KiB
TypeScript
45 lines
1.2 KiB
TypeScript
![]() |
import { css } from "@emotion/css";
|
||
|
import { PicoCart, PicoPlayerHandle, makePicoConsole } from "./renderCart";
|
||
|
import { ForwardedRef, forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
|
||
|
|
||
|
type Pico8ConsoleImperatives = {
|
||
|
getPicoConsoleHandle(): PicoPlayerHandle | null;
|
||
|
}
|
||
|
|
||
|
export const Pico8Console = forwardRef((props: { carts: PicoCart[] }, forwardedRef: ForwardedRef<Pico8ConsoleImperatives>) => {
|
||
|
const {carts} = props;
|
||
|
const ref = useRef<HTMLDivElement>(null);
|
||
|
const [handle, setHandle] = useState<PicoPlayerHandle | null>(null);
|
||
|
const attachConsole = useCallback(async () => {
|
||
|
const picoConsole = await makePicoConsole({
|
||
|
carts,
|
||
|
});
|
||
|
if (ref.current) {
|
||
|
ref.current.appendChild(picoConsole.canvas);
|
||
|
}
|
||
|
setHandle(picoConsole);
|
||
|
}, [carts]);
|
||
|
useImperativeHandle(forwardedRef, () => ({
|
||
|
getPicoConsoleHandle() {
|
||
|
return handle;
|
||
|
}
|
||
|
}), [handle]);
|
||
|
useEffect(() => {
|
||
|
attachConsole();
|
||
|
}, [attachConsole]);
|
||
|
return (
|
||
|
<div ref={ref} className={css`
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
justify-content: center;
|
||
|
|
||
|
& > canvas {
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
}
|
||
|
`}></div>
|
||
|
);
|
||
|
});
|