From 2937974fe732690ca58e4d693e5c1a69ef4bfc90 Mon Sep 17 00:00:00 2001 From: Ku6epXBOCTuK Date: Thu, 10 Sep 2026 10:08:57 +0500 Subject: [PATCH] feat: update geometry tools to new types --- web/src/lib/registry-new/geometry.ts | 68 ++++++++++++++++++---------- 1 file changed, 45 insertions(+), 23 deletions(-) diff --git a/web/src/lib/registry-new/geometry.ts b/web/src/lib/registry-new/geometry.ts index ebc1968..1adb422 100644 --- a/web/src/lib/registry-new/geometry.ts +++ b/web/src/lib/registry-new/geometry.ts @@ -23,7 +23,7 @@ import { type FlipAxis, } from "../core/geometry"; import { field, toolSchema, type Dimension } from "../registry-schema"; -import type { ToolEntry } from "./types"; +import { imgTool, type ToolEntry } from "./types"; interface AddBorderParams { thickness: number; @@ -42,7 +42,8 @@ const addBorder: ToolEntry = { "Draws a colored frame of the chosen thickness around the image.", category: "geometry", schema: addBorderSchema, - run: (img, p) => + input: "image", + run: imgTool((img, p) => expandCanvas( img, p.thickness, @@ -51,6 +52,7 @@ const addBorder: ToolEntry = { p.thickness, p.color, ), + ), }; interface FitOnBackgroundParams { @@ -82,7 +84,8 @@ const fitOnBackground: ToolEntry = { "Places the image centered on a canvas of the given size with a transparent or colored background.", category: "geometry", schema: fitOnBackgroundSchema, - run: (img, p) => { + input: "image", + run: imgTool((img, p) => { const width = Math.trunc(p.size.width); const height = Math.trunc(p.size.height); if (width <= 0 || height <= 0) { @@ -98,7 +101,7 @@ const fitOnBackground: ToolEntry = { Math.max(0, height - img.height - top), p.transparent ? undefined : p.color, ); - }, + }), }; interface ChangeCanvasSizeParams { @@ -141,13 +144,15 @@ const changeCanvasSizeTool: ToolEntry = { "Sets the exact canvas size: overflow is cropped, missing space is filled with transparency. Anchor picks which part of the image stays.", category: "geometry", schema: changeCanvasSizeSchema, - run: (img, p) => + input: "image", + run: imgTool((img, p) => changeCanvasSize( img, Math.trunc(p.size.width), Math.trunc(p.size.height), p.anchor, ), + ), }; interface ResizeParams { @@ -177,7 +182,8 @@ const resizeTool: ToolEntry = { "Scales the image with bilinear interpolation. With aspect kept, one side defines the scale; if both are set, the image fits inside them.", category: "geometry", schema: resizeSchema, - run: (img, p) => { + input: "image", + run: imgTool((img, p) => { const keepAspect = p.keepAspect; let w = Math.trunc(p.size.width); let h = Math.trunc(p.size.height); @@ -196,7 +202,7 @@ const resizeTool: ToolEntry = { throw new ToolError("errors.resizeSize"); } return resize(img, w, h); - }, + }), }; interface CropParams { @@ -228,14 +234,15 @@ const cropTool: ToolEntry = { "Cuts out a rectangular area. Coordinates and sizes may go beyond the image — the area is clipped to the intersection.", category: "geometry", schema: cropSchema, - run: (img, p) => { + input: "image", + run: imgTool((img, p) => { const w = Math.trunc(p.size.width); const h = Math.trunc(p.size.height); if (w <= 0 || h <= 0) { throw new ToolError("errors.cropSize"); } return crop(img, Math.trunc(p.x), Math.trunc(p.y), w, h); - }, + }), }; interface RotateParams { @@ -259,7 +266,8 @@ const rotateTool: ToolEntry = { description: "Rotates by 90°, 180° or 270° clockwise without quality loss.", category: "geometry", schema: rotateSchema, - run: (img, p) => rotate90(img, Number(p.angle) / 90), + input: "image", + run: imgTool((img, p) => rotate90(img, Number(p.angle) / 90)), }; interface FlipParams { @@ -282,7 +290,8 @@ const flipTool: ToolEntry = { description: "Mirrors horizontally or vertically without quality loss.", category: "geometry", schema: flipSchema, - run: (img, p) => flip(img, p.axis), + input: "image", + run: imgTool((img, p) => flip(img, p.axis)), }; interface AddPaddingParams { @@ -314,7 +323,8 @@ const addPaddingTool: ToolEntry = { "Expands the canvas on all sides by the chosen number of pixels.", category: "geometry", schema: addPaddingSchema, - run: (img, p) => + input: "image", + run: imgTool((img, p) => expandCanvas( img, p.padding, @@ -323,6 +333,7 @@ const addPaddingTool: ToolEntry = { p.padding, p.transparent ? undefined : p.color, ), + ), }; interface TileParams { @@ -341,7 +352,8 @@ const tileTool: ToolEntry = { description: "Repeats the image in a grid of the chosen columns and rows.", category: "geometry", schema: tileSchema, - run: (img, p) => tile(img, p.columns, p.rows), + input: "image", + run: imgTool((img, p) => tile(img, p.columns, p.rows)), }; interface EmptyParams {} @@ -355,7 +367,8 @@ const centerByAlphaTool: ToolEntry = { "Finds the opaque part of the image and centers it on the original canvas.", category: "geometry", schema: centerByAlphaSchema, - run: (img) => centerByAlpha(img), + input: "image", + run: imgTool((img) => centerByAlpha(img)), }; interface SkewParams { @@ -375,7 +388,8 @@ const skewTool: ToolEntry = { "Shifts content horizontally and vertically — a perspective effect.", category: "geometry", schema: skewSchema, - run: (img, p) => skewImage(img, p.degX, p.degY), + input: "image", + run: imgTool((img, p) => skewImage(img, p.degX, p.degY)), }; interface RotateFreeParams { @@ -393,7 +407,8 @@ const rotateFreeTool: ToolEntry = { "Rotation by any angle. The canvas grows to fit the new bounds; corners stay transparent.", category: "geometry", schema: rotateFreeSchema, - run: (img, p) => rotateFreeImage(img, p.angle), + input: "image", + run: imgTool((img, p) => rotateFreeImage(img, p.angle)), }; interface ZoomParams { @@ -411,7 +426,8 @@ const zoomTool: ToolEntry = { "Magnifies content toward the center. The canvas keeps its size — edges are cropped.", category: "geometry", schema: zoomSchema, - run: (img, p) => zoomImage(img, p.scale), + input: "image", + run: imgTool((img, p) => zoomImage(img, p.scale)), }; interface TrimEmptySpaceParams { @@ -429,7 +445,8 @@ const trimEmptySpaceTool: ToolEntry = { "Crops transparent borders around the content. Pixels with alpha above the threshold count as content.", category: "geometry", schema: trimEmptySpaceSchema, - run: (img, p) => trimToContent(img, p.threshold), + input: "image", + run: imgTool((img, p) => trimToContent(img, p.threshold)), }; type AspectRatio = "1:1" | "4:3" | "3:4" | "3:2" | "2:3" | "16:9" | "9:16"; @@ -468,11 +485,12 @@ const changeAspectRatioTool: ToolEntry = { "Fits the image into a target aspect ratio: crop the center to fill, or pad with transparency.", category: "geometry", schema: changeAspectRatioSchema, - run: (img, p) => { + input: "image", + run: imgTool((img, p) => { const [rw, rh] = p.ratio.split(":").map(Number); const ratio = rw / rh; return p.mode === "pad" ? padToRatio(img, ratio) : cropToRatio(img, ratio); - }, + }), }; interface SwapOrientationParams { @@ -496,7 +514,8 @@ const swapOrientationTool: ToolEntry = { "Rotates the image by 90° when its orientation differs from the target — landscape becomes portrait and back. Square images are untouched.", category: "geometry", schema: swapOrientationSchema, - run: (img, p) => forceOrientation(img, p.target), + input: "image", + run: imgTool((img, p) => forceOrientation(img, p.target)), }; type SymmetricAxis = "horizontal" | "vertical"; @@ -533,7 +552,8 @@ const symmetricCopyTool: ToolEntry = { "Doubles the canvas by mirroring the kept side onto the empty half — instant symmetric pattern.", category: "geometry", schema: symmetricCopySchema, - run: (img, p) => symmetricCopy(img, p.axis, p.keepSide), + input: "image", + run: imgTool((img, p) => symmetricCopy(img, p.axis, p.keepSide)), }; interface ShiftParams { @@ -554,7 +574,8 @@ const shiftTool: ToolEntry = { description: "Moves content by the given X and Y offset.", category: "geometry", schema: shiftSchema, - run: (img, p) => + input: "image", + run: imgTool((img, p) => transformImage( img, [1, 0, 0, 1, -Math.trunc(p.offsetX), -Math.trunc(p.offsetY)], @@ -562,6 +583,7 @@ const shiftTool: ToolEntry = { img.height, p.color, ), + ), }; export const geometryEntries = [