Split sprite sheets, sticker packs, and grid images into individual files. Everything runs in the browser via the Canvas API — no upload, no server, no account.
Available in English (/) and Simplified Chinese (/zh/).
- Visual slicing — grid overlay on the source image, updated live as you change rows and columns.
- Edge trimming — crop a fixed number of pixels from every cell to drop dividing lines or padding. A red dashed guide shows what will be kept.
- Batch export — download every slice as one ZIP, or grab an individual slice on hover.
- Format control — PNG (lossless, keeps transparency) or JPG (quality 0.9, transparent areas filled white).
- Local processing — images never leave the device.
- Two locales with their own URLs — each is prerendered to static HTML with
its own
lang, title, description, canonical and hreflang tags.
- React 19 + TypeScript
- Vite 6 — client build plus an SSR pass used for prerendering
- Tailwind CSS 3 — compiled at build time
- Lucide React for icons
jszipandfile-saverfor the ZIP export
Requires Node.js 20 or newer (the build uses node --env-file-if-exists).
npm install
npm run devOpen http://localhost:3000. The dev server serves English at / and Chinese at
/zh/.
SITE_URL is required: it is the origin used to generate canonical, hreflang
and sitemap URLs. The build fails rather than emit tags pointing at the wrong
host.
cp .env.example .env # then edit SITE_URL
npm run buildor inline:
SITE_URL=https://example.com npm run buildnpm run build runs three steps:
vite build— client bundle intodist/, leaving<!--app-html-->and the<!--seo-start-->/<!--seo-end-->markers indist/index.html.vite build --config vite.config.ssr.ts— rendersentry-server.tsxand the locale data intodist-ssr/(a build artifact, removed afterwards).node scripts/prerender.mjs— renders the landing view for each locale, swaps in the per-locale head, and writesdist/index.html,dist/zh/index.html,sitemap.xmlandrobots.txt.
Other scripts:
npm run typecheck # tsc --noEmit
npm run preview # serve dist/ locally
npm run build:client # client bundle only, no prerenderwrangler.toml publishes ./dist as Cloudflare static assets:
npx wrangler deployNot yet verified end to end on Cloudflare. In particular, confirm that
/zh/resolves todist/zh/index.htmlunder your assets configuration.
- Add the language code to
Languageintypes.ts. - Create
i18n/<code>.tsimplementingTranslations(the compiler will list anything missing). - Register it in
i18n/index.ts—LANGUAGESandTEXTS.
localePath() keeps DEFAULT_LANGUAGE at the root and gives every other
locale its own directory. Routing, prerendering, hreflang and the sitemap all
derive from that list, so no other file needs touching.
├── components/
│ ├── Button.tsx # Shared button
│ ├── HelpModal.tsx # Steps dialog (Esc to close, focus-trapped)
│ ├── ImageUploader.tsx # Drag-and-drop / keyboard-accessible file input
│ ├── LandingSections.tsx # Features, how-to, use cases, privacy, FAQ
│ └── PresetInput.tsx # Numeric input with quick-select presets
├── i18n/
│ ├── en.ts # English copy
│ ├── zh.ts # Simplified Chinese copy
│ └── index.ts # Locale list, path helpers
├── scripts/
│ └── prerender.mjs # Per-locale HTML, sitemap.xml, robots.txt
├── utils/
│ └── imageProcessing.ts # Canvas slicing, blob lifecycle, ZIP export
├── App.tsx # Application shell and editor
├── entry-server.tsx # SSR entry used by the prerender step
├── index.tsx # Client entry (hydrates the prerendered shell)
├── index.html # Template with SEO and app markers
├── styles.css # Tailwind layers and global styles
├── types.ts # Shared interfaces
├── tailwind.config.js
├── vite.config.ts # Client build
└── vite.config.ssr.ts # SSR build for prerendering
- Slice files are named
slice_<row>_<col>counting from zero, inside aslices/folder in the ZIP. - Cells are computed with
Math.floor, so sheets whose dimensions do not divide evenly lose the remainder at the right and bottom edges. - Animated GIFs are read as a single frame.