feat: add layout groupt to tools

This commit is contained in:
2026-09-05 17:47:41 +05:00
parent d48262e482
commit e662d1df24
6 changed files with 381 additions and 155 deletions
+23 -3
View File
@@ -24,8 +24,14 @@
> раскладка `schema.layout` реализована** (шаг 32): тип `ToolSchemaLayout` > раскладка `schema.layout` реализована** (шаг 32): тип `ToolSchemaLayout`
> {groups: [{title?, cols?, fields}]}, рендер групп в `SchemaFields.svelte` > {groups: [{title?, cols?, fields}]}, рендер групп в `SchemaFields.svelte`
> (заголовок группы + сетка колонок, неупомянутые поля — в общей группе), > (заголовок группы + сетка колонок, неупомянутые поля — в общей группе),
> пилот — `add-text` (группы Text/Placement/Plate). > пилот — `add-text` (группы Text/Placement/Plate). **UI-макеты расставлены
> Следующее: шаг 33 — UI-макет каждого переведённого инструмента (ревью по одному). > по переведённым инструментам** (шаг 33): geometry (fit-on-background,
> change-canvas-size, resize, crop), маски alpha (Shape/Position), generate
> (create-empty, linear-gradient, color-spectrum, random-colors, draw-grid,
> step-colors, placeholder, text-to-png), text (add-text, date-stamp),
> filters (randomize-pixels, add-noise) — везде, где канвас отделён от
> параметров эффекта либо фигура от позиции.
> Следующее: шаг 34 — поглощение `tool-views.ts` (Фаза 5, зачистка).
> >
> Ключевые файлы нового registry: `web/src/lib/registry-new/{types,index,*}.ts` > Ключевые файлы нового registry: `web/src/lib/registry-new/{types,index,*}.ts`
> (по файлу на категорию: geometry/alpha/convert/analyze/filters/color/generate) > (по файлу на категорию: geometry/alpha/convert/analyze/filters/color/generate)
@@ -422,7 +428,21 @@ Typed field builders + `Field<T>` + `toolSchema<P>()` + `ToolSchema<P>` —
неупомянутые поля — в общей группе в конце, без заголовка). Пилот — неупомянутые поля — в общей группе в конце, без заголовка). Пилот —
`add-text-png` (Text: text+style; Placement: position+margin; Plate). `add-text-png` (Text: text+style; Placement: position+margin; Plate).
Тесты: schema-layout в registry-schema.test.ts; полные запуски чисты. Тесты: schema-layout в registry-schema.test.ts; полные запуски чисты.
33. Для каждого переведённого инструмента — UI-макет, принимается отдельно. 33. Для каждого переведённого инструмента — UI-макет **расставлен** ✔.
Layout-группы заданы там, где группировка содержательна (канвас отдельно
от параметров эффекта, фигура отдельно от позиции; составные виджеты —
внутри групп целиком):
- geometry: fit-on-background (Canvas/Background), change-canvas-size
(Canvas/Anchor), resize (Canvas/Scaling), crop (Offset/Crop area);
- alpha-маски: circle/square/star/wavy (Shape — с 2 колонками где плотно,
Position — offset);
- generate: create-empty (Canvas/Fill), linear-gradient (Canvas/Colors),
color-spectrum (Canvas/Spectrum), random-colors (Canvas/Random),
draw-grid (Canvas/Grid), step-colors (Colors/Output), placeholder
(Canvas/Colors/Text), text-to-png (Text/Background/Padding);
- text: add-text, date-stamp (Text/Placement/Plate);
- filters: randomize-pixels (Blocks), add-noise (Noise/Seed).
Инструменты с 1–3 простыми полями остались без layout (одна общая группа).
### Фаза 5 — зачистка ### Фаза 5 — зачистка
+75 -23
View File
@@ -77,10 +77,20 @@ interface CircleMaskParams {
offset: Offset; offset: Offset;
} }
const circleMaskSchema = toolSchema<CircleMaskParams>({ const circleMaskSchema = toolSchema<CircleMaskParams>(
size: field.slider({ min: 20, max: 100, step: 1, default: 100 }), {
offset: field.offset({ min: -50, max: 50, x: 0, y: 0 }), size: field.slider({ min: 20, max: 100, step: 1, default: 100 }),
}); offset: field.offset({ min: -50, max: 50, x: 0, y: 0 }),
},
{
layout: {
groups: [
{ title: "Shape", fields: ["size"] },
{ title: "Position", fields: ["offset"] },
],
},
},
);
const circleMask: ToolEntry<CircleMaskParams> = { const circleMask: ToolEntry<CircleMaskParams> = {
id: "circle-mask-png", id: "circle-mask-png",
@@ -104,11 +114,25 @@ interface SquareMaskParams {
offset: Offset; offset: Offset;
} }
const squareMaskSchema = toolSchema<SquareMaskParams>({ const squareMaskSchema = toolSchema<SquareMaskParams>(
widthPct: field.slider({ min: 10, max: 100, step: 1, default: 100 }), {
heightPct: field.slider({ min: 10, max: 100, step: 1, default: 100 }), widthPct: field.slider({ min: 10, max: 100, step: 1, default: 100 }),
offset: field.offset({ min: -50, max: 50, x: 0, y: 0 }), heightPct: field.slider({ min: 10, max: 100, step: 1, default: 100 }),
}); offset: field.offset({ min: -50, max: 50, x: 0, y: 0 }),
},
{
layout: {
groups: [
{
title: "Shape",
cols: 2,
fields: ["widthPct", "heightPct"],
},
{ title: "Position", fields: ["offset"] },
],
},
},
);
const squareMask: ToolEntry<SquareMaskParams> = { const squareMask: ToolEntry<SquareMaskParams> = {
id: "square-mask-png", id: "square-mask-png",
@@ -134,13 +158,27 @@ interface StarMaskParams {
offset: Offset; offset: Offset;
} }
const starMaskSchema = toolSchema<StarMaskParams>({ const starMaskSchema = toolSchema<StarMaskParams>(
points: field.slider({ min: 3, max: 12, step: 1, default: 5 }), {
innerRadius: field.slider({ min: 10, max: 90, step: 1, default: 45 }), points: field.slider({ min: 3, max: 12, step: 1, default: 5 }),
size: field.slider({ min: 20, max: 100, step: 1, default: 100 }), innerRadius: field.slider({ min: 10, max: 90, step: 1, default: 45 }),
rotation: field.slider({ min: -180, max: 180, step: 1, default: 0 }), size: field.slider({ min: 20, max: 100, step: 1, default: 100 }),
offset: field.offset({ min: -50, max: 50, x: 0, y: 0 }), rotation: field.slider({ min: -180, max: 180, step: 1, default: 0 }),
}); offset: field.offset({ min: -50, max: 50, x: 0, y: 0 }),
},
{
layout: {
groups: [
{
title: "Shape",
cols: 2,
fields: ["points", "innerRadius", "size", "rotation"],
},
{ title: "Position", fields: ["offset"] },
],
},
},
);
const starMask: ToolEntry<StarMaskParams> = { const starMask: ToolEntry<StarMaskParams> = {
id: "star-mask-png", id: "star-mask-png",
@@ -166,13 +204,27 @@ interface WavyMaskParams {
offset: Offset; offset: Offset;
} }
const wavyMaskSchema = toolSchema<WavyMaskParams>({ const wavyMaskSchema = toolSchema<WavyMaskParams>(
size: field.slider({ min: 20, max: 100, step: 1, default: 90 }), {
amplitude: field.slider({ min: 2, max: 30, step: 1, default: 8 }), size: field.slider({ min: 20, max: 100, step: 1, default: 90 }),
waves: field.slider({ min: 3, max: 24, step: 1, default: 8 }), amplitude: field.slider({ min: 2, max: 30, step: 1, default: 8 }),
phase: field.slider({ min: 0, max: 360, step: 1, default: 0 }), waves: field.slider({ min: 3, max: 24, step: 1, default: 8 }),
offset: field.offset({ min: -50, max: 50, x: 0, y: 0 }), phase: field.slider({ min: 0, max: 360, step: 1, default: 0 }),
}); offset: field.offset({ min: -50, max: 50, x: 0, y: 0 }),
},
{
layout: {
groups: [
{
title: "Shape",
cols: 2,
fields: ["size", "amplitude", "waves", "phase"],
},
{ title: "Position", fields: ["offset"] },
],
},
},
);
const wavyMask: ToolEntry<WavyMaskParams> = { const wavyMask: ToolEntry<WavyMaskParams> = {
id: "wavy-mask-png", id: "wavy-mask-png",
+32 -15
View File
@@ -45,10 +45,17 @@ interface RandomizePixelsParams {
seed: number; seed: number;
} }
export const randomizePixelsSchema = toolSchema<RandomizePixelsParams>({ export const randomizePixelsSchema = toolSchema<RandomizePixelsParams>(
blockSize: field.slider({ min: 1, max: 64, step: 1, default: 8 }), {
seed: field.number({ min: 0, max: 999999, step: 1, default: 42 }), blockSize: field.slider({ min: 1, max: 64, step: 1, default: 8 }),
}); seed: field.number({ min: 0, max: 999999, step: 1, default: 42 }),
},
{
layout: {
groups: [{ title: "Blocks", cols: 2, fields: ["blockSize", "seed"] }],
},
},
);
const randomizePixels: ToolEntry<RandomizePixelsParams> = { const randomizePixels: ToolEntry<RandomizePixelsParams> = {
id: "randomize-pixels-png", id: "randomize-pixels-png",
@@ -66,17 +73,27 @@ interface AddNoiseParams {
seed: number; seed: number;
} }
export const addNoiseSchema = toolSchema<AddNoiseParams>({ export const addNoiseSchema = toolSchema<AddNoiseParams>(
amount: field.slider({ min: 0, max: 100, step: 1, default: 25 }), {
mode: field.select({ amount: field.slider({ min: 0, max: 100, step: 1, default: 25 }),
default: "mono", mode: field.select({
options: [ default: "mono",
{ value: "mono", label: "Monochrome grain" }, options: [
{ value: "color", label: "Color noise" }, { value: "mono", label: "Monochrome grain" },
], { value: "color", label: "Color noise" },
}), ],
seed: field.number({ min: 0, max: 999999, step: 1, default: 1234 }), }),
}); seed: field.number({ min: 0, max: 999999, step: 1, default: 1234 }),
},
{
layout: {
groups: [
{ title: "Noise", cols: 2, fields: ["amount", "mode"] },
{ title: "Seed", fields: ["seed"] },
],
},
},
);
const addNoiseTool: ToolEntry<AddNoiseParams> = { const addNoiseTool: ToolEntry<AddNoiseParams> = {
id: "add-noise-png", id: "add-noise-png",
+152 -66
View File
@@ -69,11 +69,21 @@ interface CreateEmptyParams {
color: string; color: string;
} }
export const createEmptySchema = toolSchema<CreateEmptyParams>({ export const createEmptySchema = toolSchema<CreateEmptyParams>(
size: field.dimension({ min: 1, max: 20000, width: 800, height: 600 }), {
transparent: field.checkbox({ default: true }), size: field.dimension({ min: 1, max: 20000, width: 800, height: 600 }),
color: field.color({ default: "#ffffff" }), transparent: field.checkbox({ default: true }),
}); color: field.color({ default: "#ffffff" }),
},
{
layout: {
groups: [
{ title: "Canvas", fields: ["size"] },
{ title: "Fill", fields: ["transparent", "color"] },
],
},
},
);
const createEmpty: ToolEntry<CreateEmptyParams> = { const createEmpty: ToolEntry<CreateEmptyParams> = {
id: "create-empty-png", id: "create-empty-png",
@@ -144,10 +154,20 @@ interface LinearGradientParams {
gradient: Gradient; gradient: Gradient;
} }
export const linearGradientSchema = toolSchema<LinearGradientParams>({ export const linearGradientSchema = toolSchema<LinearGradientParams>(
size: field.dimension({ min: 1, max: 20000, width: 800, height: 600 }), {
gradient: field.gradient({ from: "#000000", to: "#ffffff", angle: 0 }), size: field.dimension({ min: 1, max: 20000, width: 800, height: 600 }),
}); gradient: field.gradient({ from: "#000000", to: "#ffffff", angle: 0 }),
},
{
layout: {
groups: [
{ title: "Canvas", fields: ["size"] },
{ title: "Colors", fields: ["gradient"] },
],
},
},
);
const linearGradient: ToolEntry<LinearGradientParams> = { const linearGradient: ToolEntry<LinearGradientParams> = {
id: "linear-gradient-png", id: "linear-gradient-png",
@@ -176,18 +196,28 @@ interface ColorSpectrumParams {
lightness: number; lightness: number;
} }
export const colorSpectrumSchema = toolSchema<ColorSpectrumParams>({ export const colorSpectrumSchema = toolSchema<ColorSpectrumParams>(
size: field.dimension({ min: 1, max: 5000, width: 1024, height: 128 }), {
direction: field.select({ size: field.dimension({ min: 1, max: 5000, width: 1024, height: 128 }),
default: "horizontal", direction: field.select({
options: [ default: "horizontal",
{ value: "horizontal", label: "Horizontal" }, options: [
{ value: "vertical", label: "Vertical" }, { value: "horizontal", label: "Horizontal" },
], { value: "vertical", label: "Vertical" },
}), ],
saturation: field.slider({ min: 0, max: 100, step: 1, default: 100 }), }),
lightness: field.slider({ min: 0, max: 100, step: 1, default: 50 }), saturation: field.slider({ min: 0, max: 100, step: 1, default: 100 }),
}); lightness: field.slider({ min: 0, max: 100, step: 1, default: 50 }),
},
{
layout: {
groups: [
{ title: "Canvas", fields: ["size"] },
{ title: "Spectrum", fields: ["direction", "saturation", "lightness"] },
],
},
},
);
const colorSpectrumTool: ToolEntry<ColorSpectrumParams> = { const colorSpectrumTool: ToolEntry<ColorSpectrumParams> = {
id: "color-spectrum-png", id: "color-spectrum-png",
@@ -209,11 +239,21 @@ interface RandomColorsParams {
seed: number; seed: number;
} }
export const randomColorsSchema = toolSchema<RandomColorsParams>({ export const randomColorsSchema = toolSchema<RandomColorsParams>(
size: field.dimension({ min: 1, max: 5000, width: 512, height: 512 }), {
blockSize: field.slider({ min: 4, max: 256, step: 2, default: 64 }), size: field.dimension({ min: 1, max: 5000, width: 512, height: 512 }),
seed: field.number({ min: 0, max: 999999999, step: 1, default: 7 }), blockSize: field.slider({ min: 4, max: 256, step: 2, default: 64 }),
}); seed: field.number({ min: 0, max: 999999999, step: 1, default: 7 }),
},
{
layout: {
groups: [
{ title: "Canvas", fields: ["size"] },
{ title: "Random", cols: 2, fields: ["blockSize", "seed"] },
],
},
},
);
const randomColors: ToolEntry<RandomColorsParams> = { const randomColors: ToolEntry<RandomColorsParams> = {
id: "random-colors-png", id: "random-colors-png",
@@ -238,14 +278,28 @@ interface DrawGridParams {
transparentBg: boolean; transparentBg: boolean;
} }
export const drawGridSchema = toolSchema<DrawGridParams>({ export const drawGridSchema = toolSchema<DrawGridParams>(
size: field.dimension({ min: 1, max: 5000, width: 512, height: 512 }), {
cols: field.slider({ min: 1, max: 64, step: 1, default: 8 }), size: field.dimension({ min: 1, max: 5000, width: 512, height: 512 }),
rows: field.slider({ min: 1, max: 64, step: 1, default: 8 }), cols: field.slider({ min: 1, max: 64, step: 1, default: 8 }),
lineWidth: field.slider({ min: 1, max: 40, step: 1, default: 2 }), rows: field.slider({ min: 1, max: 64, step: 1, default: 8 }),
color: field.color({ default: "#111318" }), lineWidth: field.slider({ min: 1, max: 40, step: 1, default: 2 }),
transparentBg: field.checkbox({ default: true }), color: field.color({ default: "#111318" }),
}); transparentBg: field.checkbox({ default: true }),
},
{
layout: {
groups: [
{ title: "Canvas", fields: ["size"] },
{
title: "Grid",
cols: 2,
fields: ["cols", "rows", "lineWidth", "color", "transparentBg"],
},
],
},
},
);
const drawGridTool: ToolEntry<DrawGridParams> = { const drawGridTool: ToolEntry<DrawGridParams> = {
id: "draw-grid-png", id: "draw-grid-png",
@@ -276,12 +330,23 @@ interface PlaceholderParams {
showText: boolean; showText: boolean;
} }
export const placeholderSchema = toolSchema<PlaceholderParams>({ export const placeholderSchema = toolSchema<PlaceholderParams>(
size: field.dimension({ min: 1, max: 5000, width: 800, height: 400 }), {
backgroundColor: field.color({ default: "#dfe2e8" }), size: field.dimension({ min: 1, max: 5000, width: 800, height: 400 }),
color: field.color({ default: "#5c6470" }), backgroundColor: field.color({ default: "#dfe2e8" }),
showText: field.checkbox({ default: true }), color: field.color({ default: "#5c6470" }),
}); showText: field.checkbox({ default: true }),
},
{
layout: {
groups: [
{ title: "Canvas", fields: ["size"] },
{ title: "Colors", cols: 2, fields: ["backgroundColor", "color"] },
{ title: "Text", fields: ["showText"] },
],
},
},
);
const placeholder: ToolEntry<PlaceholderParams> = { const placeholder: ToolEntry<PlaceholderParams> = {
id: "placeholder-png", id: "placeholder-png",
@@ -337,18 +402,28 @@ interface StepColorsParams {
layout: "strip" | "grid"; layout: "strip" | "grid";
} }
export const stepColorsSchema = toolSchema<StepColorsParams>({ export const stepColorsSchema = toolSchema<StepColorsParams>(
pair: field.colorPair({ from: "#000000", to: "#ffffff" }), {
steps: field.slider({ min: 2, max: 12, step: 1, default: 6 }), pair: field.colorPair({ from: "#000000", to: "#ffffff" }),
width: field.slider({ min: 128, max: 1024, step: 16, default: 512 }), steps: field.slider({ min: 2, max: 12, step: 1, default: 6 }),
layout: field.select({ width: field.slider({ min: 128, max: 1024, step: 16, default: 512 }),
default: "grid", layout: field.select({
options: [ default: "grid",
{ value: "grid", label: "Grid" }, options: [
{ value: "strip", label: "Strip" }, { value: "grid", label: "Grid" },
], { value: "strip", label: "Strip" },
}), ],
}); }),
},
{
layout: {
groups: [
{ title: "Colors", fields: ["pair"] },
{ title: "Output", cols: 2, fields: ["steps", "width", "layout"] },
],
},
},
);
const stepColorsTool: ToolEntry<StepColorsParams> = { const stepColorsTool: ToolEntry<StepColorsParams> = {
id: "step-colors-png", id: "step-colors-png",
@@ -372,20 +447,31 @@ interface TextToPngParams {
padding: number; padding: number;
} }
export const textToPngSchema = toolSchema<TextToPngParams>({ export const textToPngSchema = toolSchema<TextToPngParams>(
text: field.text({ default: "Hello!", placeholder: "Your text" }), {
style: field.fontStyle({ text: field.text({ default: "Hello!", placeholder: "Your text" }),
min: 8, style: field.fontStyle({
max: 300, min: 8,
size: 96, max: 300,
font: "sans", size: 96,
bold: true, font: "sans",
color: "#111318", bold: true,
}), color: "#111318",
transparentBg: field.checkbox({ default: false }), }),
backgroundColor: field.color({ default: "#ffffff" }), transparentBg: field.checkbox({ default: false }),
padding: field.slider({ min: 0, max: 200, step: 2, default: 24 }), backgroundColor: field.color({ default: "#ffffff" }),
}); padding: field.slider({ min: 0, max: 200, step: 2, default: 24 }),
},
{
layout: {
groups: [
{ title: "Text", fields: ["text", "style"] },
{ title: "Background", fields: ["transparentBg", "backgroundColor"] },
{ title: "Padding", fields: ["padding"] },
],
},
},
);
const textToPng: ToolEntry<TextToPngParams> = { const textToPng: ToolEntry<TextToPngParams> = {
id: "text-to-png", id: "text-to-png",
+71 -31
View File
@@ -43,11 +43,21 @@ interface FitOnBackgroundParams {
color: string; color: string;
} }
export const fitOnBackgroundSchema = toolSchema<FitOnBackgroundParams>({ export const fitOnBackgroundSchema = toolSchema<FitOnBackgroundParams>(
size: field.dimension({ min: 1, max: 20000, width: 800, height: 600 }), {
transparent: field.checkbox({ default: false }), size: field.dimension({ min: 1, max: 20000, width: 800, height: 600 }),
color: field.color({ default: "#ffffff" }), transparent: field.checkbox({ default: false }),
}); color: field.color({ default: "#ffffff" }),
},
{
layout: {
groups: [
{ title: "Canvas", fields: ["size"] },
{ title: "Background", fields: ["transparent", "color"] },
],
},
},
);
const fitOnBackground: ToolEntry<FitOnBackgroundParams> = { const fitOnBackground: ToolEntry<FitOnBackgroundParams> = {
id: "fit-on-background-png", id: "fit-on-background-png",
@@ -80,23 +90,33 @@ interface ChangeCanvasSizeParams {
anchor: Anchor9; anchor: Anchor9;
} }
export const changeCanvasSizeSchema = toolSchema<ChangeCanvasSizeParams>({ export const changeCanvasSizeSchema = toolSchema<ChangeCanvasSizeParams>(
size: field.dimension({ min: 1, max: 20000, width: 800, height: 600 }), {
anchor: field.select({ size: field.dimension({ min: 1, max: 20000, width: 800, height: 600 }),
default: "center", anchor: field.select({
options: [ default: "center",
{ value: "top-left", label: "Top left" }, options: [
{ value: "top-center", label: "Top center" }, { value: "top-left", label: "Top left" },
{ value: "top-right", label: "Top right" }, { value: "top-center", label: "Top center" },
{ value: "middle-left", label: "Middle left" }, { value: "top-right", label: "Top right" },
{ value: "center", label: "Center" }, { value: "middle-left", label: "Middle left" },
{ value: "middle-right", label: "Middle right" }, { value: "center", label: "Center" },
{ value: "bottom-left", label: "Bottom left" }, { value: "middle-right", label: "Middle right" },
{ value: "bottom-center", label: "Bottom center" }, { value: "bottom-left", label: "Bottom left" },
{ value: "bottom-right", label: "Bottom right" }, { value: "bottom-center", label: "Bottom center" },
], { value: "bottom-right", label: "Bottom right" },
}), ],
}); }),
},
{
layout: {
groups: [
{ title: "Canvas", fields: ["size"] },
{ title: "Anchor", fields: ["anchor"] },
],
},
},
);
const changeCanvasSizeTool: ToolEntry<ChangeCanvasSizeParams> = { const changeCanvasSizeTool: ToolEntry<ChangeCanvasSizeParams> = {
id: "change-canvas-size-png", id: "change-canvas-size-png",
@@ -119,10 +139,20 @@ interface ResizeParams {
keepAspect: boolean; keepAspect: boolean;
} }
export const resizeSchema = toolSchema<ResizeParams>({ export const resizeSchema = toolSchema<ResizeParams>(
size: field.dimension({ min: 0, max: 20000, width: 0, height: 0 }), {
keepAspect: field.checkbox({ default: true }), size: field.dimension({ min: 0, max: 20000, width: 0, height: 0 }),
}); keepAspect: field.checkbox({ default: true }),
},
{
layout: {
groups: [
{ title: "Canvas", fields: ["size"] },
{ title: "Scaling", fields: ["keepAspect"] },
],
},
},
);
const resizeTool: ToolEntry<ResizeParams> = { const resizeTool: ToolEntry<ResizeParams> = {
id: "resize-png", id: "resize-png",
@@ -159,11 +189,21 @@ interface CropParams {
size: Dimension; size: Dimension;
} }
export const cropSchema = toolSchema<CropParams>({ export const cropSchema = toolSchema<CropParams>(
x: field.number({ min: -100000, max: 100000, step: 1, default: 0 }), {
y: field.number({ min: -100000, max: 100000, step: 1, default: 0 }), x: field.number({ min: -100000, max: 100000, step: 1, default: 0 }),
size: field.dimension({ min: 0, max: 100000, width: 0, height: 0 }), y: field.number({ min: -100000, max: 100000, step: 1, default: 0 }),
}); size: field.dimension({ min: 0, max: 100000, width: 0, height: 0 }),
},
{
layout: {
groups: [
{ title: "Offset", fields: ["x", "y"] },
{ title: "Crop area", fields: ["size"] },
],
},
},
);
const cropTool: ToolEntry<CropParams> = { const cropTool: ToolEntry<CropParams> = {
id: "crop-png", id: "crop-png",
+28 -17
View File
@@ -70,23 +70,34 @@ interface DateStampParams {
plate: Plate; plate: Plate;
} }
const dateStampSchema = toolSchema<DateStampParams>({ const dateStampSchema = toolSchema<DateStampParams>(
format: field.text({ {
default: "YYYY-MM-DD", format: field.text({
placeholder: "YYYY-MM-DD hh:mm", default: "YYYY-MM-DD",
}), placeholder: "YYYY-MM-DD hh:mm",
style: field.fontStyle({ }),
min: 8, style: field.fontStyle({
max: 200, min: 8,
size: 32, max: 200,
font: "mono", size: 32,
bold: false, font: "mono",
color: "#ffffff", bold: false,
}), color: "#ffffff",
position: field.position9({ default: "bottom-right" }), }),
margin: field.slider({ min: 0, max: 200, step: 1, default: 20 }), position: field.position9({ default: "bottom-right" }),
plate: field.plate({ enabled: true, color: "#000000", opacity: 55 }), margin: field.slider({ min: 0, max: 200, step: 1, default: 20 }),
}); plate: field.plate({ enabled: true, color: "#000000", opacity: 55 }),
},
{
layout: {
groups: [
{ title: "Text", fields: ["format", "style"] },
{ title: "Placement", fields: ["position", "margin"] },
{ title: "Plate", fields: ["plate"] },
],
},
},
);
const dateStamp: ToolEntry<DateStampParams> = { const dateStamp: ToolEntry<DateStampParams> = {
id: "date-stamp-png", id: "date-stamp-png",