Files
ttstd-infinite-canvas/web/src/lib/canvas/canvas-grid-split.ts
soonstudio-ai 8e82e67cb3 feat(canvas): 多角度贴节点、宫格切分菜单与多选虚线框跟随
把多角度改成贴在图片节点下方的 3D 编辑器并跟随拖动;宫格切分并入图片工具,自定义面板不关菜单;切分后子图按网格排开;多选虚线框随拖动预览平移。
2026-09-14 17:19:56 +08:00

50 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { ImageSplitParams } from "@/lib/canvas/canvas-image-data";
export const CANVAS_GRID_SPLIT_MAX = 5;
export const CANVAS_GRID_SPLIT_GAP = 48;
export const CANVAS_GRID_SPLIT_PRESETS: Array<{ rows: number; columns: number; label: string }> = [
{ rows: 2, columns: 2, label: "4宫格 (2×2)" },
{ rows: 3, columns: 3, label: "9宫格 (3×3)" },
{ rows: 4, columns: 4, label: "16宫格 (4×4)" },
{ rows: 5, columns: 5, label: "25宫格 (5×5)" },
];
export type GridSplitCellSize = {
row: number;
column: number;
width: number;
height: number;
};
export function clampGridSplitSize(value: number) {
if (!Number.isFinite(value)) return 2;
return Math.max(1, Math.min(CANVAS_GRID_SPLIT_MAX, Math.round(value)));
}
export function isValidGridSplit(params: ImageSplitParams) {
const rows = clampGridSplitSize(params.rows);
const columns = clampGridSplitSize(params.columns);
return rows * columns >= 2;
}
export function layoutGridSplitCells(origin: { x: number; y: number }, cells: GridSplitCellSize[], gap = CANVAS_GRID_SPLIT_GAP) {
const columnCount = Math.max(0, ...cells.map((cell) => cell.column)) + 1;
const rowCount = Math.max(0, ...cells.map((cell) => cell.row)) + 1;
const columnWidth = Array.from({ length: columnCount }, (_, column) => Math.max(1, ...cells.filter((cell) => cell.column === column).map((cell) => cell.width)));
const rowHeight = Array.from({ length: rowCount }, (_, row) => Math.max(1, ...cells.filter((cell) => cell.row === row).map((cell) => cell.height)));
const columnX: number[] = [];
let x = origin.x;
for (let column = 0; column < columnCount; column += 1) {
columnX.push(x);
x += (columnWidth[column] || 1) + gap;
}
const rowY: number[] = [];
let y = origin.y;
for (let row = 0; row < rowCount; row += 1) {
rowY.push(y);
y += (rowHeight[row] || 1) + gap;
}
return cells.map((cell) => ({ x: columnX[cell.column] || origin.x, y: rowY[cell.row] || origin.y }));
}