- Remove runtime JavaScript from Sprite component entirely - Use CSS custom properties (--x, --y, --ex) with shared @keyframes - Add SpriteStyles component for global keyframe (include once in <head>) - Require sheetWidth/sheetHeight props (calculated by dev tool) - Remove grid/columns support (horizontal strips only) - Dev tool now auto-detects frames and calculates crop bounds - Dev server is now CLI-based with required assets directory arg - Add image picker with filter/search 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
81 lines
1.9 KiB
TypeScript
81 lines
1.9 KiB
TypeScript
#!/usr/bin/env bun
|
|
import { Glob } from "bun"
|
|
import { resolve } from "path"
|
|
import index from "./index.html"
|
|
|
|
const args = process.argv.slice(2)
|
|
const helpFlag = args.includes("--help") || args.includes("-h")
|
|
const assetsDirArg = args.find((arg) => !arg.startsWith("-"))
|
|
|
|
if (helpFlag || !assetsDirArg) {
|
|
console.log(`
|
|
tiny-sprites dev server
|
|
|
|
Usage:
|
|
tiny-sprites <assets-dir>
|
|
bun src/dev/server.tsx <assets-dir>
|
|
|
|
Arguments:
|
|
assets-dir Directory containing sprite images (required)
|
|
|
|
Options:
|
|
-h, --help Show this help message
|
|
|
|
Example:
|
|
tiny-sprites ./assets
|
|
bun --hot src/dev/server.tsx ./assets
|
|
`)
|
|
process.exit(helpFlag ? 0 : 1)
|
|
}
|
|
|
|
// Resolve to absolute path
|
|
const assetsDir = resolve(assetsDirArg)
|
|
|
|
// Verify assets directory exists
|
|
try {
|
|
const glob = new Glob("*")
|
|
await glob.scan(assetsDir).next()
|
|
} catch {
|
|
console.error(`Error: Assets directory not found: ${assetsDir}`)
|
|
process.exit(1)
|
|
}
|
|
|
|
console.log(`Assets directory: ${assetsDir}`)
|
|
|
|
const getImageList = async (): Promise<string[]> => {
|
|
const glob = new Glob("**/*.{png,jpg,jpeg,gif,webp}")
|
|
const images: string[] = []
|
|
|
|
for await (const path of glob.scan(assetsDir)) {
|
|
images.push(path)
|
|
}
|
|
|
|
return images.sort()
|
|
}
|
|
|
|
Bun.serve({
|
|
port: 3000,
|
|
routes: {
|
|
"/": index,
|
|
"/api/images": async () => {
|
|
const images = await getImageList()
|
|
return Response.json({ assetsDir, images })
|
|
},
|
|
},
|
|
async fetch(req) {
|
|
const url = new URL(req.url)
|
|
if (url.pathname.startsWith("/assets/")) {
|
|
const path = decodeURIComponent(url.pathname.replace("/assets/", ""))
|
|
const file = Bun.file(`${assetsDir}/${path}`)
|
|
if (await file.exists()) {
|
|
return new Response(file)
|
|
}
|
|
return new Response("Not found", { status: 404 })
|
|
}
|
|
return new Response("Not found", { status: 404 })
|
|
},
|
|
development: true,
|
|
})
|
|
|
|
console.log("Dev server running at http://localhost:3000")
|