feat: add support for draggable grid lines in image slicing, with options to add, delete, and reset horizontal/vertical lines

This commit is contained in:
HouYunFei
2026-07-05 16:08:23 +08:00
parent 65a91b22e1
commit 0b69dfce46
4 changed files with 120 additions and 27 deletions
+15 -8
View File
@@ -24,6 +24,8 @@ export type ImageUpscaleParams = {
export type ImageSplitParams = {
rows: number;
columns: number;
horizontalLines?: number[];
verticalLines?: number[];
};
export type ImageSplitPiece = {
@@ -45,16 +47,16 @@ export async function cropDataUrl(dataUrl: string, crop?: ImageCropRect) {
export async function splitDataUrl(dataUrl: string, params: ImageSplitParams): Promise<ImageSplitPiece[]> {
const image = await loadImage(dataUrl);
const rows = Math.max(1, Math.floor(params.rows));
const columns = Math.max(1, Math.floor(params.columns));
const xCuts = buildSplitCuts(params.verticalLines, image.width, Math.max(1, Math.floor(params.columns)));
const yCuts = buildSplitCuts(params.horizontalLines, image.height, Math.max(1, Math.floor(params.rows)));
const pieces: ImageSplitPiece[] = [];
for (let row = 0; row < rows; row += 1) {
const sy = Math.floor((row * image.height) / rows);
const sh = Math.floor(((row + 1) * image.height) / rows) - sy;
for (let column = 0; column < columns; column += 1) {
const sx = Math.floor((column * image.width) / columns);
const sw = Math.floor(((column + 1) * image.width) / columns) - sx;
for (let row = 0; row < yCuts.length - 1; row += 1) {
const sy = yCuts[row];
const sh = yCuts[row + 1] - sy;
for (let column = 0; column < xCuts.length - 1; column += 1) {
const sx = xCuts[column];
const sw = xCuts[column + 1] - sx;
pieces.push({ row, column, dataUrl: drawCrop(image, sx, sy, sw, sh) });
}
}
@@ -62,6 +64,11 @@ export async function splitDataUrl(dataUrl: string, params: ImageSplitParams): P
return pieces;
}
function buildSplitCuts(lines: number[] | undefined, size: number, count: number) {
if (!lines?.length) return Array.from({ length: count + 1 }, (_, index) => Math.floor((index * size) / count));
return [0, ...lines.map((line) => Math.round(line * size)).filter((line) => line > 0 && line < size).sort((a, b) => a - b), size];
}
export async function transformAngleDataUrl(dataUrl: string, params: ImageAngleTransform) {
const image = await loadImage(dataUrl);
const canvas = document.createElement("canvas");