make react component
This commit is contained in:
1 parent
55fca0a5c2
commit
d606a8002f
8 files changed
+117
-66
No files matched your search
+9
-27
@@ -1,34 +1,16 @@
|
||||
import { css } from "@emotion/css";
|
||||
import { Center, Cover, Stack } from "@firebox/components";
|
||||
import { Pico8Console } from "./pico8-client/Pico8Console";
|
||||
import testcarts from "./testcarts";
|
||||
|
||||
const App = (props: { name: string }) => {
|
||||
const {name} = props;
|
||||
const App = (props: {}) => {
|
||||
return (
|
||||
<Stack>
|
||||
<div className={css`background-color: floralwhite;`}>
|
||||
<Cover gap pad>
|
||||
<Center>
|
||||
<Stack gap={-1}>
|
||||
<h1>Hello, {name}!</h1>
|
||||
<p>Welcome to a website with a certain design philosophy. Tell me how it's working out! I want to see this text wrap a few times. Hopefully this sentence will help.</p>
|
||||
</Stack>
|
||||
</Center>
|
||||
<Cover.Footer>A page by Dylan Pizzo</Cover.Footer>
|
||||
</Cover>
|
||||
</div>
|
||||
<div className={css`background-color: aliceblue;`}>
|
||||
<Cover gap pad>
|
||||
<Center>
|
||||
<Stack gap={-1}>
|
||||
<h1>Hello, {name}!</h1>
|
||||
<p>Welcome to a website with a certain design philosophy. Tell me how it's working out! I want to see this text wrap a few times. Hopefully this sentence will help.</p>
|
||||
</Stack>
|
||||
</Center>
|
||||
<Cover.Footer>A page by Dylan Pizzo</Cover.Footer>
|
||||
</Cover>
|
||||
</div>
|
||||
</Stack>
|
||||
<div className={css`
|
||||
min-height: 100vh;
|
||||
`}>
|
||||
<Pico8Console carts={testcarts.carts} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const app = <App name="World" />;
|
||||
export const app = <App />;
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
// import { createRoot } from "react-dom/client";
|
||||
// import { app } from "./app.js";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { app } from "./app.js";
|
||||
|
||||
// const domNode = document.getElementById("root")!;
|
||||
// const root = createRoot(domNode);
|
||||
// root.render(app);
|
||||
const domNode = document.getElementById("root")!;
|
||||
const root = createRoot(domNode);
|
||||
root.render(app);
|
||||
|
||||
export * from "./pico8-client/index";
|
||||
// export * from "./pico8-client/index";
|
||||
@@ -0,0 +1,44 @@
|
||||
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>
|
||||
);
|
||||
});
|
||||
@@ -1,9 +1,9 @@
|
||||
// @ts-ignore
|
||||
import "./build/veryRawRenderCart.js";
|
||||
|
||||
type PicoBool = 0 | 1;
|
||||
export type PicoBool = 0 | 1;
|
||||
|
||||
type RenderCart = (Module: {canvas: HTMLCanvasElement}, cartNames: string[], cartDatas: number[][], audioContext: AudioContext) => {
|
||||
export type RenderCart = (Module: {canvas: HTMLCanvasElement}, cartNames: string[], cartDatas: number[][], audioContext: AudioContext) => {
|
||||
p8_touch_detected?: PicoBool;
|
||||
p8_dropped_cart?: string;
|
||||
p8_dropped_cart_name?: string;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { assertNever } from "@firebox/tsutil";
|
||||
import { pngToRom } from "./pngToRom";
|
||||
import { renderCart as rawRenderCart } from "./rawRenderCart";
|
||||
import { RenderCart, renderCart as rawRenderCart } from "./rawRenderCart";
|
||||
|
||||
type PicoCart = {
|
||||
export type PicoCart = {
|
||||
name: string;
|
||||
src: string;
|
||||
} | {
|
||||
@@ -20,7 +20,9 @@ type PlayerButtons = {
|
||||
menu: boolean;
|
||||
}
|
||||
|
||||
type PicoPlayerHandle = {
|
||||
export type PicoPlayerHandle = {
|
||||
raw: ReturnType<RenderCart>;
|
||||
rawModule: unknown;
|
||||
// external things
|
||||
readonly canvas: HTMLCanvasElement;
|
||||
|
||||
@@ -35,16 +37,16 @@ type PicoPlayerHandle = {
|
||||
setGamepadCount: (count: number) => void;
|
||||
readonly gpio: number[]; // read + write (should be 256-tuple)
|
||||
|
||||
// state (all communicated out)
|
||||
// state
|
||||
readonly state: {
|
||||
readonly frameNumber: number;
|
||||
readonly isPaused: boolean;
|
||||
readonly hasFocus: boolean;
|
||||
readonly requestPointerLock: boolean;
|
||||
readonly requirePageNavigateConfirmation: boolean;
|
||||
readonly showDpad: boolean;
|
||||
readonly shutdownRequested: boolean;
|
||||
readonly soundVolume: number;
|
||||
frameNumber: number;
|
||||
isPaused: boolean;
|
||||
hasFocus: boolean;
|
||||
requestPointerLock: boolean;
|
||||
requirePageNavigateConfirmation: boolean;
|
||||
showDpad: boolean;
|
||||
shutdownRequested: boolean;
|
||||
soundVolume: number;
|
||||
};
|
||||
|
||||
// misc?
|
||||
@@ -109,6 +111,8 @@ export const makePicoConsole = async (props: {
|
||||
];
|
||||
handle.pico8_gamepads = {count: 0};
|
||||
return {
|
||||
raw: handle,
|
||||
rawModule: Module,
|
||||
canvas,
|
||||
state: {
|
||||
frameNumber: handle.pico8_state.frame_number!,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
const hexToArray = (hex: string) => {
|
||||
const h = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
|
||||
const a = [];
|
||||
for (let i = 0; i < hex.length; i+=2) {
|
||||
a.push(16*h.indexOf(hex[i])+h.indexOf(hex[i+1]));
|
||||
}
|
||||
return a;
|
||||
};
|
||||
|
||||
export default {
|
||||
"carts": [
|
||||
{
|
||||
"name": "mygame",
|
||||
"rom": hexToArray("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Line truncated
|
||||
},
|
||||
{
|
||||
"name": "secondcart",
|
||||
"src": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAADNCAYAAAA/pXupAAAItUlEQVR4Ae2drY4jyxmG36pqMHBBwLmAwAMGHLhRHGlBwLmAE2mkWJGlM2BhYMCCBQEHDlhg4ChzCQcEDKhIfQFzCYELAgYEut2R7Clvucc/Pf1T3R4/j2R903Z39dTXT78fNbPZrQLzxWK5PYAtRnJyRmVRFpJkJSdntSpWRXyek1wh7Xx3Hht0cmVhCqmU5OS02YVToeJ5/5LK571ZZ52KlVbOFipWz5t3m/0Xxcn9z6bTbHvrIOB8sVjOpjeD7N9JpjCu1Ob5hu1v/zKSC5vffG+lYrWtTnKFc5vfT+9/dBzYv9sK4Mxm/0UpK7nVtj/R/qVCzp3F/ueL+62EZja71fwf/1z+/Oc/7b4Bkjbbl+SMVJQ69Pa75zekcK44RwFOG/Jt/zs9kIogwKZdZ5h+A0tolF0NlnyAhJY2wJAgICBgU77Mv/IEEXAg+X6YS09zfbn9iaeIgInl++Sln57T77ff68u7DzxJBEzH7aeJsqc/SpL+/snr9umBJ3mpAn755fPO59B31e+PXV/nHrPPP+j7h9/oP/87T/l+/DB5VY2vC599x/F3h46Prbfvt33Hx65LJmCQ4favf9tNqOg4/B2fu++7k6kXXRd4/6/bi0yNXx/8i79D/fHDRL8++BfHddeLZXvtOk3IuljkUHJ1IXacqrCbnm2vjeVq+iK0TcBOBKyTYG3Xq6bmWxTp1PGxxGqSnl2KNMgIrpOIVWG+/PJ573enRN53Han37ftQg0zx+afGZ/Xcpus0wSi7Ws6mN8w1SM58cd9PAgIMOoIBEBAQEAABAQEBEBBGSdbm4vning6CZtObYQSUpOV//6Ps3XeHf3/6+u1m777T8unrixp+g3OMsKthR3As0bFz2q4Bb5PWAtYRKKQdQC8CnhKMhIPeBHxtuiEj7PjQxfit83t83r6/GdEI2Ajvc00m73dqYDJ5T4eh3xFcJUiHfJBMwDj1AJILSNrBaEZwSENSEeqQdZV+1QqQREDv87V0cWU0w2AjmCSE5ALGqQeQXEDSDkYzgkMakopQh6yr9KtWgCQCep+vpYsroxkGG8EkISQXME49gOQCknYwmhEc0pBUhDpkXaVftQIkEdD7fC1dXBnNMNgIJgkhuYBx6gEkF5C0g9GM4JCGpCLUIesq/aoVIImA3udr6eLKaIbBRjBJCMkFjFMPILmApB2MZgSHNCQVoQ5ZV+lXrQBJBPQ+X0sXV0YzDDaCSUJILmCcegDJBSTtYDQjOKQhqQh1yLpKv2oFSCKg9/laurgymmGwEUwSQnIB49QDSC4gaQejGcEhDUlFqEPWVfpVK0ASAb3P19LFldEMg41gkhCSCxinHkByAUk7GM0IDmlIKkIdsq7Sr1oBkiRgNfG8z7ef88AYyRrJGRkZjtMe264XnEx+tz6eTH5/Jg2BQV9/ZVfL2fSm0cXzxb38w8OLcex9fmaj2EgqsaFJN7IrtfGn9QiOxeuzIf1yXvL13Y+U3ehEwLgh3uc79fL0eFuC9N2PrKv0q9ZLHrjnKMhQ/WgtoPf5Wrq4th3NCHI5/Wg0go9FahdJyMi9nH40ErDakDj1EIQX5jX9aCTgodRDEF6YXkbwaxoS0vA1qYggl9uPWgIea0hIv7iGD4LwwvQ+gquJ532+/SAIL0wjAds0pJqICMIL82oBX9uQY2mHIPSj1xF8Ku0QhH6cFLDLhoQ0jFMRQXhhjgrYpiEh/eIaPgjCC9P7CK4mnve5/u3znQREEF6YQ/1oLeC+RCyjREQQXphj/ehEwD7TDkHedj86EfAPPacdgrzdfnQiYNyQkIZ9pyKCvI1+ZG0XnzynX7W2bUifD/EcBXmr/WiUgPEbU0087/PthwQhUXsR8FhDukxCBHn7/WgkYJU2aYcgl92PWgKeakjbtEOQy+1HLQFf05CQhm1TEUEuox+tR3BIv7iGT62GWCtrrHHGGOussXLGGRlrjbHOPX8nGeeMM8Y4yVgjY2U25xljrJWsNZK1kjWyknGyz2vY5/UkKytrn9eW3V5jw71N789qEMb8whhlV8vZ9KbRxfPFvfzDw1o27/Nt7Wo0wxmQXamNP60T8FQiAvQ6giXtpB5AcgFJOxhUwH1pSCpCHbKu0q9aAZII6H2+li6ujGYYbASThJBcwDj1AJILSNrBaEZwSENSEeqQdZV+1QqQREDv87V0cWU0w2AjmCSE5ALGqQeQXEDSDkYzgkMakopQh6yr9KtWgCQCep+vpYsroxkGG8EkISQXME49gOQCknYwmhEc0pBUhDpkXaVftQIkEdD7fC1dXBnNMNgIJgkhuYBx6gEkF5C0g9GM4JCGpCLUIesq/aoVIImA3udr6eLKaIbBRjBJCMkFjFMPILmApB2MZgSHNCQVoQ5ZV+lXrQCDJCAAAgICAiAgICAAAgICAiAgjI6s/QpXdBGGEXA2vaGDwAgGBARAQEBAAAQEBARAQEBAAASE8ZK1ufjx8ZEOgq6vr0lAYAQDICAgIAACAgICICAgIAACAgICICAgIAACAgICICAgICAgAAICAgIgICAgAAICAgL0S9bVQh8/ftz+fXd39+I4PufQ8bH1jt1z3/26Oo7vfex+MIIEjB9E+DuW7e7u7sVx3fX2yRevt+/8Y/9P3d+DaIfuh3wjEjBOhSbXhk/T9arnn5K8zkvQ136hpwRs+kDDtccS7TUJvG9U7ju/jeSk38gE3PegQg0Pu5pwpxLqlDxdpVD1/z2UqPtSG5pjlF0tZ9ObRhc/Pj7SQdD19XWj6+aL+/4SEGDQEQxQh2yI6AWYL+41m04zEhAGk48RDIPKh4AwqHwICIPKh4AwqHwICIPKJ0l2Np1m88U9nYLk8m0TEAlhCPkkaXvCRsLFktZdFtYarVblJotMKWtLs1rZ0pUrK+vK1apUacrSlTKyKiVrtCrKlTG2NGXpjLXFysgYldaUplBZ2KI0P/9lmhUr56zKlZFUaFXuu///AS4EJeAobygDAAAAEHRFWHRMb2RlUE5HADIwMTEwMjIx41m2wQAAAABJRU5ErkJggg=="
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user