import React, { useState } from "react"; import { clone, type Asset } from "../engine/schema.ts"; import { sliceImage, validateImage } from "../engine/two-d.ts"; import { Field2D } from "./Inspector2D.tsx"; export function SpriteEditor({ asset, save, }: { asset: Asset; save: (a: Asset) => Promise; }) { const [draft, setDraft] = useState(clone(asset)), [w, setW] = useState(asset.image!.frames[0].width), [h, setH] = useState(asset.image!.frames[0].height), [margin, setMargin] = useState(0), [spacing, setSpacing] = useState(0), [selected, setSelected] = useState(0), [error, setError] = useState(""); const im = draft.image!, frame = im.frames[selected] || im.frames[0]; const update = (v: any) => setDraft({ ...draft, image: { ...im, ...v } }); const modify = (v: any) => update({ frames: im.frames.map((f, i) => (i === selected ? { ...f, ...v } : f)), }); return (
{draft.name} {im.frames.map((f, i) => ( ))}

{im.width} × {im.height} · {im.frames.length} кадров

update({ pixelsPerUnit })} />

Нарезка по сетке

Кадр {selected}

{(["x", "y", "width", "height"] as const).map((k) => ( modify({ [k]: v })} /> ))} {[0, 1].map((i) => ( modify({ pivot: frame.pivot.map((x, j) => (j === i ? v : x)) }) } /> ))}

Pivot: 0–1, от верхнего левого угла. Изменения применяются ко всем спрайтам ресурса. Если нарезка удаляет используемые кадры, сначала исправьте клипы и Tilemap.

{error &&

{error}

}
); }