gradio-experiment-sandpack / components /sandpack-examples.tsx
json-cho's picture
initial commit
d10a61a
import { Sandpack } from "@codesandbox/sandpack-react";
import { githubLight, sandpackDark } from "@codesandbox/sandpack-themes";
/**
* The only reason this is a separate import, is so
* we don't need to make the full page 'use client', but only this component.
*/
export const SandpackExamples = () => {
return (
<>
{/* Sandpack component to embed a React app with the specified files */}
<Sandpack
files={{
"/public/logo.svg": `<svg xmlns="http://www.w3.org/2000/svg" viewBox="-11.5 -10.23174 23 20.46348">
<title>React Logo</title>
<circle cx="0" cy="0" r="2.05" fill="#61dafb"/>
<g stroke="#61dafb" stroke-width="1" fill="none">
<ellipse rx="11" ry="4.2"/>
<ellipse rx="11" ry="4.2" transform="rotate(60)"/>
<ellipse rx="11" ry="4.2" transform="rotate(120)"/>
</g>
</svg>
`,
"/App.js": `
// Define constant for platform width
const PLATFORM_WIDTH = 60;
import React, { useState, useEffect, useRef } from "react";
export default function Game() {
const canvasRef = useRef(null);
const [player, setPlayer] = useState({ x: 150, y: 300, vy: -8 });
const [platforms, setPlatforms] = useState(
Array.from({ length: 6 }, (_, i) => ({ x: Math.random() * 300, y: i * 100 }))
);
const [gameOver, setGameOver] = useState(false);
useEffect(() => {
const handleKeyDown = (e) => {
if (e.key === "ArrowLeft") setPlayer((p) => ({ ...p, x: p.x - 20 }));
if (e.key === "ArrowRight") setPlayer((p) => ({ ...p, x: p.x + 20 }));
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, []);
useEffect(() => {
const gameLoop = setInterval(() => {
setPlayer((p) => {
let newY = p.y + p.vy;
let newVy = p.vy + 0.4;
if (newY > 500) {
setGameOver(true);
}
let newPlatforms = platforms.map((plat) => ({ ...plat, y: plat.y + 3 }));
newPlatforms = newPlatforms.filter((plat) => plat.y < 600);
if (newPlatforms.length < 6) {
newPlatforms.push({ x: Math.random() * 300, y: 0 });
}
setPlatforms(newPlatforms);
for (let plat of newPlatforms) {
if (
p.vy > 0 &&
p.y + 20 >= plat.y &&
p.y + 20 <= plat.y + 10 &&
p.x + 20 > plat.x &&
p.x < plat.x + 60
) {
newVy = -8;
}
}
return { x: p.x, y: newY, vy: newVy };
});
}, 30);
return () => clearInterval(gameLoop);
}, [platforms]);
return (
<>
<h1>Doodle Jump</h1>
<img width="100" src="/public/logo.svg" />
<svg width="400" height="600" className="mx-auto mt-10 border border-black bg-blue-300">
{/* Background Asset*/}
{gameOver && (
<rect width="400" height="600" fill="white" opacity="0.8" />
)}
{/* Game Over Asset*/}
{gameOver && (
<text x="200" y="300" textAnchor="middle" fontSize="24" fontWeight="bold" fill="black">
Game Over
</text>
)}
{/* Platform Asset */}
{platforms.map((plat, i) => (
<rect key={i} x={plat.x} y={plat.y} width={PLATFORM_WIDTH} height="10" fill="green" />
))}
{/* Player Asset*/}
<circle cx={player.x + 10} cy={player.y + 10} r="10" fill="red" />
</svg>
</>
);
}
`,
}}
options={{
experimental_enableServiceWorker: true,
editorHeight: 800, // default - 300
editorWidthPercentage: 10, // default - 50
}}
template="react"
/>
</>
);
};