import { useEffect, useState } from "react"; import { Button, InputNumber, Modal } from "antd"; import { Grid2x2 } from "lucide-react"; import { readImageMeta } from "@/lib/image-utils"; import type { ImageSplitParams } from "@/lib/canvas/canvas-image-data"; export type CanvasImageSplitParams = ImageSplitParams; const defaultParams: CanvasImageSplitParams = { rows: 2, columns: 2 }; const maxGridSize = 12; export function CanvasNodeSplitDialog({ dataUrl, open, onClose, onConfirm }: { dataUrl: string; open: boolean; onClose: () => void; onConfirm: (params: CanvasImageSplitParams) => void }) { const [params, setParams] = useState(defaultParams); const [image, setImage] = useState<{ width: number; height: number } | null>(null); const total = params.rows * params.columns; const pieceSize = image ? { width: Math.max(1, Math.floor(image.width / params.columns)), height: Math.max(1, Math.floor(image.height / params.rows)) } : null; useEffect(() => { if (!open) return; setParams(defaultParams); setImage(null); }, [dataUrl, open]); useEffect(() => { if (!open) return; void readImageMeta(dataUrl).then(setImage); }, [dataUrl, open]); const update = (key: keyof CanvasImageSplitParams, value: string | number | null) => { setParams((current) => ({ ...current, [key]: clampGrid(value ?? current[key]) })); }; return (

切分图片

生成 {total} 个图片子节点,并按原图网格排列到画布右侧

原图 {image ? `${image.width} x ${image.height} px` : "读取中"}
update("rows", value)} /> update("columns", value)} />
子节点 {total} 个
单块约 {pieceSize ? `${pieceSize.width} x ${pieceSize.height}` : "未知"}
); } function NumberField({ label, value, onChange }: { label: string; value: number; onChange: (value: string | number | null) => void }) { return ( ); } function SplitGrid({ rows, columns }: CanvasImageSplitParams) { return (
{Array.from({ length: columns - 1 }).map((_, index) => (
))} {Array.from({ length: rows - 1 }).map((_, index) => (
))}
); } function clampGrid(value: string | number) { const numberValue = Number(value); return Math.min(maxGridSize, Math.max(1, Math.round(Number.isFinite(numberValue) ? numberValue : 1))); }