From 9456957e63bc5d864f80e0bda7ec5b8befc514cf Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Tue, 6 Jan 2026 11:39:43 -0800 Subject: [PATCH] feat: add dev tool client component with hono jsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/dev/app.tsx | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/dev/app.tsx diff --git a/src/dev/app.tsx b/src/dev/app.tsx new file mode 100644 index 0000000..000ca33 --- /dev/null +++ b/src/dev/app.tsx @@ -0,0 +1,114 @@ +import { useState } from "hono/jsx" +import { render } from "hono/jsx/dom" + +const App = () => { + const [spriteUrl, setSpriteUrl] = useState("") + const [width, setWidth] = useState(32) + const [height, setHeight] = useState(32) + const [frames, setFrames] = useState(4) + const [columns, setColumns] = useState() + const [frameDuration, setFrameDuration] = useState(100) + + const handleFileChange = (e: Event) => { + const file = (e.target as HTMLInputElement).files?.[0] + if (!file) return + setSpriteUrl(URL.createObjectURL(file)) + } + + const isGrid = columns !== undefined + const cols = isGrid ? columns : frames + const rows = isGrid ? Math.ceil(frames / columns!) : 1 + const sheetWidth = cols * width + const sheetHeight = rows * height + const totalDuration = frames * frameDuration + + const keyframeId = "sprite-preview" + let keyframes: string + + if (isGrid) { + const steps: string[] = [] + for (let i = 0; i < frames; i++) { + const col = i % columns! + const row = Math.floor(i / columns!) + const x = -col * width + const y = -row * height + const percent = (i / frames) * 100 + steps.push(`${percent}%{background-position:${x}px ${y}px}`) + } + keyframes = `@keyframes ${keyframeId}{${steps.join("")}}` + } else { + keyframes = `@keyframes ${keyframeId}{from{background-position:0 0}to{background-position:-${sheetWidth}px 0}}` + } + + const previewStyle = { + width: `${width}px`, + height: `${height}px`, + backgroundImage: `url('${spriteUrl}')`, + backgroundSize: `${sheetWidth}px ${sheetHeight}px`, + animation: `${keyframeId} ${totalDuration}ms steps(${frames}) infinite`, + } + + const columnsAttr = columns ? `\n columns={${columns}}` : "" + const code = `` + + const copyCode = () => navigator.clipboard.writeText(code) + + return ( +
+
+ + + + + + +
+
+
+ {spriteUrl ? ( + <> + +
+ + ) : ( + Upload a spritesheet to preview + )} +
+