mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-11-13 17:08:20 +00:00
feat: add transparency range slider to opacity fields
This commit is contained in:
@@ -81,8 +81,6 @@
|
|||||||
- [ ] сделать несколько проходное сжатие png для получения необходимого размера
|
- [ ] сделать несколько проходное сжатие png для получения необходимого размера
|
||||||
файлов, посмотреть реализацию в
|
файлов, посмотреть реализацию в
|
||||||
[twitch-emote-resizer](https://github.com/tma02/twitch-emote-resizer)
|
[twitch-emote-resizer](https://github.com/tma02/twitch-emote-resizer)
|
||||||
- [ ] Пересмотреть прозрачность в инструментах - Create empty PNG - прозрачность
|
|
||||||
должны быть настраиваемой 0-100%, а не переключателем
|
|
||||||
- [ ] Font Style - обдумать выбор шрифта (google fonts???) как организовать
|
- [ ] Font Style - обдумать выбор шрифта (google fonts???) как организовать
|
||||||
шрифты с кириллицей? сделать галочку "только с кириллицей"??? (решение о
|
шрифты с кириллицей? сделать галочку "только с кириллицей"??? (решение о
|
||||||
наборе и лицензиях: `docs/plan-platform.md` §4 — только OFL/Apache с
|
наборе и лицензиях: `docs/plan-platform.md` §4 — только OFL/Apache с
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export interface TextToImageOptions {
|
|||||||
bold: boolean;
|
bold: boolean;
|
||||||
color: string;
|
color: string;
|
||||||
backgroundColor: string;
|
backgroundColor: string;
|
||||||
transparentBg: boolean;
|
bgOpacity: number;
|
||||||
padding: number;
|
padding: number;
|
||||||
maxTextWidth?: number;
|
maxTextWidth?: number;
|
||||||
}
|
}
|
||||||
@@ -148,9 +148,11 @@ export function renderTextToImage(o: TextToImageOptions): PixelImage {
|
|||||||
const h = Math.max(1, Math.ceil(lineH + o.padding * 2));
|
const h = Math.max(1, Math.ceil(lineH + o.padding * 2));
|
||||||
const { canvas, ctx } = ctx2d(w, h);
|
const { canvas, ctx } = ctx2d(w, h);
|
||||||
|
|
||||||
if (!o.transparentBg) {
|
if (o.bgOpacity > 0) {
|
||||||
|
ctx.globalAlpha = Math.min(100, Math.max(0, o.bgOpacity)) / 100;
|
||||||
ctx.fillStyle = o.backgroundColor;
|
ctx.fillStyle = o.backgroundColor;
|
||||||
ctx.fillRect(0, 0, w, h);
|
ctx.fillRect(0, 0, w, h);
|
||||||
|
ctx.globalAlpha = 1;
|
||||||
}
|
}
|
||||||
ctx.font = fontString(o.fontSize, o.font, o.bold);
|
ctx.font = fontString(o.fontSize, o.font, o.bold);
|
||||||
ctx.fillStyle = o.color;
|
ctx.fillStyle = o.color;
|
||||||
|
|||||||
@@ -29,16 +29,22 @@ describe("randomColorBlocks", () => {
|
|||||||
|
|
||||||
describe("drawGrid", () => {
|
describe("drawGrid", () => {
|
||||||
it("линии на пересечениях непрозрачны, фон прозрачен", () => {
|
it("линии на пересечениях непрозрачны, фон прозрачен", () => {
|
||||||
const out = drawGrid(100, 100, 4, 4, 2, "#000000", true);
|
const out = drawGrid(100, 100, 4, 4, 2, "#000000", 0);
|
||||||
expect(out.data[0]).toBe(0);
|
expect(out.data[0]).toBe(0);
|
||||||
expect(out.data[3]).toBe(255); // (0,0) на линии
|
expect(out.data[3]).toBe(255); // (0,0) на линии
|
||||||
const mid = (53 * 100 + 53) * 4;
|
const mid = (53 * 100 + 53) * 4;
|
||||||
expect(out.data[mid + 3]).toBe(0); // между линиями прозрачн
|
expect(out.data[mid + 3]).toBe(0); // между линиями прозрачн
|
||||||
});
|
});
|
||||||
|
|
||||||
it("белый непрозрачный фон при transparentBg=false", () => {
|
it("белый непрозрачный фон при bgOpacity=100", () => {
|
||||||
const out = drawGrid(20, 20, 2, 2, 1, "#000000", false);
|
const out = drawGrid(20, 20, 2, 2, 1, "#000000", 100);
|
||||||
const mid = (5 * 20 + 5) * 4;
|
const mid = (5 * 20 + 5) * 4;
|
||||||
expect(out.data[mid]).toBe(255);
|
expect(out.data[mid]).toBe(255);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("полупрозрачный фон при bgOpacity=50", () => {
|
||||||
|
const out = drawGrid(20, 20, 2, 2, 1, "#000000", 50);
|
||||||
|
const mid = (5 * 20 + 5) * 4;
|
||||||
|
expect(out.data[mid + 3]).toBe(128);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ function lineMask(
|
|||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Сетка линий на прозрачном или белом фоне. */
|
/** Сетка линий на белом фоне заданной непрозрачности (0 — прозрачный). */
|
||||||
export function drawGrid(
|
export function drawGrid(
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
@@ -87,10 +87,20 @@ export function drawGrid(
|
|||||||
rows: number,
|
rows: number,
|
||||||
lineWidth: number,
|
lineWidth: number,
|
||||||
colorHex: string,
|
colorHex: string,
|
||||||
transparentBg: boolean,
|
bgOpacity: number,
|
||||||
): PixelImage {
|
): PixelImage {
|
||||||
const out = createPixelImage(width, height);
|
const out = createPixelImage(width, height);
|
||||||
if (!transparentBg) out.data.fill(255);
|
const bgAlpha = Math.round(
|
||||||
|
(Math.max(0, Math.min(100, bgOpacity)) / 100) * 255,
|
||||||
|
);
|
||||||
|
if (bgAlpha > 0) {
|
||||||
|
for (let i = 0; i < out.data.length; i += 4) {
|
||||||
|
out.data[i] = 255;
|
||||||
|
out.data[i + 1] = 255;
|
||||||
|
out.data[i + 2] = 255;
|
||||||
|
out.data[i + 3] = bgAlpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const m = /^#([0-9a-f]{6})$/i.exec(colorHex.trim());
|
const m = /^#([0-9a-f]{6})$/i.exec(colorHex.trim());
|
||||||
const r = m ? parseInt(m[1].slice(0, 2), 16) : 0;
|
const r = m ? parseInt(m[1].slice(0, 2), 16) : 0;
|
||||||
|
|||||||
@@ -9,19 +9,20 @@ export function expandCanvas(
|
|||||||
right: number,
|
right: number,
|
||||||
bottom: number,
|
bottom: number,
|
||||||
backgroundHex?: string,
|
backgroundHex?: string,
|
||||||
|
backgroundAlpha = 255,
|
||||||
): PixelImage {
|
): PixelImage {
|
||||||
const l = Math.max(0, Math.trunc(left));
|
const l = Math.max(0, Math.trunc(left));
|
||||||
const t = Math.max(0, Math.trunc(top));
|
const t = Math.max(0, Math.trunc(top));
|
||||||
const r = Math.max(0, Math.trunc(right));
|
const r = Math.max(0, Math.trunc(right));
|
||||||
const b = Math.max(0, Math.trunc(bottom));
|
const b = Math.max(0, Math.trunc(bottom));
|
||||||
const out = createPixelImage(img.width + l + r, img.height + t + b);
|
const out = createPixelImage(img.width + l + r, img.height + t + b);
|
||||||
if (backgroundHex !== undefined) {
|
if (backgroundHex !== undefined && backgroundAlpha > 0) {
|
||||||
const [cr, cg, cb] = parseHex(backgroundHex);
|
const [cr, cg, cb] = parseHex(backgroundHex);
|
||||||
for (let i = 0; i < out.data.length; i += 4) {
|
for (let i = 0; i < out.data.length; i += 4) {
|
||||||
out.data[i] = cr;
|
out.data[i] = cr;
|
||||||
out.data[i + 1] = cg;
|
out.data[i + 1] = cg;
|
||||||
out.data[i + 2] = cb;
|
out.data[i + 2] = cb;
|
||||||
out.data[i + 3] = 255;
|
out.data[i + 3] = backgroundAlpha;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let y = 0; y < img.height; y++) {
|
for (let y = 0; y < img.height; y++) {
|
||||||
|
|||||||
@@ -298,8 +298,6 @@ export const en: Dict = {
|
|||||||
textStyle: "Text style",
|
textStyle: "Text style",
|
||||||
thickness: "Thickness",
|
thickness: "Thickness",
|
||||||
threshold: "Threshold",
|
threshold: "Threshold",
|
||||||
transparent: "Transparent",
|
|
||||||
transparentBg: "Transparent bg",
|
|
||||||
waves: "Waves",
|
waves: "Waves",
|
||||||
width: "Width",
|
width: "Width",
|
||||||
x: "X",
|
x: "X",
|
||||||
|
|||||||
@@ -299,8 +299,6 @@ export const ru: Dict = {
|
|||||||
textStyle: "Стиль текста",
|
textStyle: "Стиль текста",
|
||||||
thickness: "Толщина",
|
thickness: "Толщина",
|
||||||
threshold: "Порог",
|
threshold: "Порог",
|
||||||
transparent: "Прозрачный",
|
|
||||||
transparentBg: "Прозрачный фон",
|
|
||||||
waves: "Волны",
|
waves: "Волны",
|
||||||
width: "Ширина",
|
width: "Ширина",
|
||||||
x: "X",
|
x: "X",
|
||||||
@@ -972,7 +970,7 @@ export const ru: Dict = {
|
|||||||
"add-padding": {
|
"add-padding": {
|
||||||
params: {
|
params: {
|
||||||
padding: "Поля, px",
|
padding: "Поля, px",
|
||||||
transparent: "Прозрачные поля",
|
opacity: "Непрозрачность полей, %",
|
||||||
color: "Цвет полей",
|
color: "Цвет полей",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -983,7 +981,7 @@ export const ru: Dict = {
|
|||||||
params: {
|
params: {
|
||||||
width: "Ширина полотна",
|
width: "Ширина полотна",
|
||||||
height: "Высота полотна",
|
height: "Высота полотна",
|
||||||
transparent: "Прозрачный фон",
|
opacity: "Непрозрачность фона, %",
|
||||||
color: "Цвет фона",
|
color: "Цвет фона",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1113,7 +1111,7 @@ export const ru: Dict = {
|
|||||||
params: {
|
params: {
|
||||||
width: "Ширина",
|
width: "Ширина",
|
||||||
height: "Высота",
|
height: "Высота",
|
||||||
transparent: "Прозрачный",
|
opacity: "Непрозрачность",
|
||||||
color: "Цвет",
|
color: "Цвет",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1352,7 +1350,7 @@ export const ru: Dict = {
|
|||||||
font: "Шрифт",
|
font: "Шрифт",
|
||||||
bold: "Жирный",
|
bold: "Жирный",
|
||||||
color: "Цвет текста",
|
color: "Цвет текста",
|
||||||
transparentBg: "Прозрачный фон",
|
bgOpacity: "Непрозрачность фона, %",
|
||||||
backgroundColor: "Цвет фона",
|
backgroundColor: "Цвет фона",
|
||||||
padding: "Отступ, px",
|
padding: "Отступ, px",
|
||||||
},
|
},
|
||||||
@@ -1397,7 +1395,7 @@ export const ru: Dict = {
|
|||||||
rows: "Строки",
|
rows: "Строки",
|
||||||
lineWidth: "Толщина линий, px",
|
lineWidth: "Толщина линий, px",
|
||||||
color: "Цвет линий",
|
color: "Цвет линий",
|
||||||
transparentBg: "Прозрачный фон",
|
bgOpacity: "Непрозрачность фона, %",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
quantize: {
|
quantize: {
|
||||||
|
|||||||
@@ -199,14 +199,14 @@ describe("registry-new (переведённые инструменты)", () =>
|
|||||||
const tool = TOOLS.find((t) => t.id === "create-empty")!;
|
const tool = TOOLS.find((t) => t.id === "create-empty")!;
|
||||||
const d = defaultSchemaParams(tool.schema);
|
const d = defaultSchemaParams(tool.schema);
|
||||||
expect(d.size).toEqual({ width: 800, height: 600 });
|
expect(d.size).toEqual({ width: 800, height: 600 });
|
||||||
expect(d.transparent).toBe(true);
|
expect(d.opacity).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sanitize клампит dimension к min/max и чинит мусор", () => {
|
it("sanitize клампит dimension к min/max и чинит мусор", () => {
|
||||||
const tool = TOOLS.find((t) => t.id === "create-empty")!;
|
const tool = TOOLS.find((t) => t.id === "create-empty")!;
|
||||||
const s = sanitizeSchemaParams(tool.schema, {
|
const s = sanitizeSchemaParams(tool.schema, {
|
||||||
size: { width: 999999, height: -5 },
|
size: { width: 999999, height: -5 },
|
||||||
transparent: false,
|
opacity: 50,
|
||||||
color: "#ff0000",
|
color: "#ff0000",
|
||||||
});
|
});
|
||||||
expect(s.size).toEqual({ width: 20000, height: 1 });
|
expect(s.size).toEqual({ width: 20000, height: 1 });
|
||||||
@@ -218,7 +218,7 @@ describe("registry-new (переведённые инструменты)", () =>
|
|||||||
const tool = TOOLS.find((t) => t.id === "create-empty")!;
|
const tool = TOOLS.find((t) => t.id === "create-empty")!;
|
||||||
const params = sanitizeSchemaParams(tool.schema, {
|
const params = sanitizeSchemaParams(tool.schema, {
|
||||||
size: { width: 320, height: 200 },
|
size: { width: 320, height: 200 },
|
||||||
transparent: true,
|
opacity: 0,
|
||||||
color: "#ff0000",
|
color: "#ff0000",
|
||||||
});
|
});
|
||||||
const img = asImage(await tool.run({ params }));
|
const img = asImage(await tool.run({ params }));
|
||||||
@@ -262,7 +262,7 @@ describe("registry-new (переведённые инструменты)", () =>
|
|||||||
rows: 3,
|
rows: 3,
|
||||||
lineWidth: 2,
|
lineWidth: 2,
|
||||||
color: "#000000",
|
color: "#000000",
|
||||||
transparentBg: true,
|
bgOpacity: 0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
])("генератор %s даёт картинку по dimension", async (id, params) => {
|
])("генератор %s даёт картинку по dimension", async (id, params) => {
|
||||||
@@ -336,7 +336,7 @@ describe("registry-new (переведённые инструменты)", () =>
|
|||||||
source: img,
|
source: img,
|
||||||
params: sanitizeSchemaParams(tool.schema, {
|
params: sanitizeSchemaParams(tool.schema, {
|
||||||
size: { width: 60, height: 30 },
|
size: { width: 60, height: 30 },
|
||||||
transparent: true,
|
opacity: 0,
|
||||||
color: "#ffffff",
|
color: "#ffffff",
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
@@ -633,7 +633,7 @@ describe("registry-new (переведённые инструменты)", () =>
|
|||||||
bold: true,
|
bold: true,
|
||||||
color: "#111318",
|
color: "#111318",
|
||||||
});
|
});
|
||||||
expect(d.transparentBg).toBe(false);
|
expect(d.bgOpacity).toBe(100);
|
||||||
const s = sanitizeSchemaParams(tool.schema, {
|
const s = sanitizeSchemaParams(tool.schema, {
|
||||||
style: { font: "sans", size: 9999, bold: false, color: "#123abc" },
|
style: { font: "sans", size: 9999, bold: false, color: "#123abc" },
|
||||||
padding: 200,
|
padding: 200,
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ function angleGradient(
|
|||||||
|
|
||||||
interface CreateEmptyParams {
|
interface CreateEmptyParams {
|
||||||
size: Dimension;
|
size: Dimension;
|
||||||
transparent: boolean;
|
opacity: number;
|
||||||
color: string;
|
color: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,14 +92,20 @@ export const createEmptySchema = toolSchema<CreateEmptyParams>(
|
|||||||
height: 600,
|
height: 600,
|
||||||
presets: true,
|
presets: true,
|
||||||
}),
|
}),
|
||||||
transparent: field.checkbox({ label: "fields.transparent", default: true }),
|
opacity: field.slider({
|
||||||
|
label: "fields.opacity",
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
default: 0,
|
||||||
|
}),
|
||||||
color: field.color({ label: "fields.fillColor", default: "#ffffff" }),
|
color: field.color({ label: "fields.fillColor", default: "#ffffff" }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
layout: {
|
layout: {
|
||||||
groups: [
|
groups: [
|
||||||
{ title: "groups.canvas", fields: ["size"] },
|
{ title: "groups.canvas", fields: ["size"] },
|
||||||
{ title: "groups.fill", fields: ["transparent", "color"] },
|
{ title: "groups.fill", fields: ["opacity", "color"] },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -112,10 +118,9 @@ const createEmpty: Tool<CreateEmptyParams> = {
|
|||||||
run: genTool((p) => {
|
run: genTool((p) => {
|
||||||
const w = Math.trunc(p.size.width);
|
const w = Math.trunc(p.size.width);
|
||||||
const h = Math.trunc(p.size.height);
|
const h = Math.trunc(p.size.height);
|
||||||
if (p.transparent) {
|
const [r, g, b] = rgba(p.color).slice(0, 3);
|
||||||
return solidImage(w, h, [0, 0, 0, 0]);
|
const alpha = Math.round((Math.trunc(p.opacity) / 100) * 255);
|
||||||
}
|
return solidImage(w, h, [r, g, b, alpha]);
|
||||||
return solidImage(w, h, rgba(p.color));
|
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -352,7 +357,7 @@ interface DrawGridParams {
|
|||||||
rows: number;
|
rows: number;
|
||||||
lineWidth: number;
|
lineWidth: number;
|
||||||
color: string;
|
color: string;
|
||||||
transparentBg: boolean;
|
bgOpacity: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const drawGridSchema = toolSchema<DrawGridParams>(
|
export const drawGridSchema = toolSchema<DrawGridParams>(
|
||||||
@@ -387,9 +392,12 @@ export const drawGridSchema = toolSchema<DrawGridParams>(
|
|||||||
default: 2,
|
default: 2,
|
||||||
}),
|
}),
|
||||||
color: field.color({ label: "fields.lineColor", default: "#111318" }),
|
color: field.color({ label: "fields.lineColor", default: "#111318" }),
|
||||||
transparentBg: field.checkbox({
|
bgOpacity: field.slider({
|
||||||
label: "fields.transparentBg",
|
label: "fields.opacity",
|
||||||
default: true,
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
default: 0,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -399,7 +407,7 @@ export const drawGridSchema = toolSchema<DrawGridParams>(
|
|||||||
{
|
{
|
||||||
title: "groups.grid",
|
title: "groups.grid",
|
||||||
cols: 2,
|
cols: 2,
|
||||||
fields: ["cols", "rows", "lineWidth", "color", "transparentBg"],
|
fields: ["cols", "rows", "lineWidth", "color", "bgOpacity"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -413,15 +421,7 @@ const drawGridTool: Tool<DrawGridParams> = {
|
|||||||
run: genTool((p) => {
|
run: genTool((p) => {
|
||||||
const w = Math.trunc(p.size.width);
|
const w = Math.trunc(p.size.width);
|
||||||
const h = Math.trunc(p.size.height);
|
const h = Math.trunc(p.size.height);
|
||||||
return drawGrid(
|
return drawGrid(w, h, p.cols, p.rows, p.lineWidth, p.color, p.bgOpacity);
|
||||||
w,
|
|
||||||
h,
|
|
||||||
p.cols,
|
|
||||||
p.rows,
|
|
||||||
p.lineWidth,
|
|
||||||
p.color,
|
|
||||||
p.transparentBg,
|
|
||||||
);
|
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -481,7 +481,7 @@ const placeholder: Tool<PlaceholderParams> = {
|
|||||||
bold: true,
|
bold: true,
|
||||||
color: p.color,
|
color: p.color,
|
||||||
backgroundColor: p.backgroundColor,
|
backgroundColor: p.backgroundColor,
|
||||||
transparentBg: false,
|
bgOpacity: 100,
|
||||||
padding: 0,
|
padding: 0,
|
||||||
});
|
});
|
||||||
out = changeCanvasSize(label, w, h, "center");
|
out = changeCanvasSize(label, w, h, "center");
|
||||||
@@ -931,7 +931,7 @@ const sortColorsTool: Tool<SortColorsParams> = {
|
|||||||
interface TextToPngParams {
|
interface TextToPngParams {
|
||||||
text: string;
|
text: string;
|
||||||
style: FontStyle;
|
style: FontStyle;
|
||||||
transparentBg: boolean;
|
bgOpacity: number;
|
||||||
backgroundColor: string;
|
backgroundColor: string;
|
||||||
padding: number;
|
padding: number;
|
||||||
}
|
}
|
||||||
@@ -952,9 +952,12 @@ export const textToPngSchema = toolSchema<TextToPngParams>(
|
|||||||
bold: true,
|
bold: true,
|
||||||
color: "#111318",
|
color: "#111318",
|
||||||
}),
|
}),
|
||||||
transparentBg: field.checkbox({
|
bgOpacity: field.slider({
|
||||||
label: "fields.transparentBg",
|
label: "fields.opacity",
|
||||||
default: false,
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
default: 100,
|
||||||
}),
|
}),
|
||||||
backgroundColor: field.color({
|
backgroundColor: field.color({
|
||||||
label: "fields.backgroundColor",
|
label: "fields.backgroundColor",
|
||||||
@@ -974,7 +977,7 @@ export const textToPngSchema = toolSchema<TextToPngParams>(
|
|||||||
{ title: "groups.text", fields: ["text", "style"] },
|
{ title: "groups.text", fields: ["text", "style"] },
|
||||||
{
|
{
|
||||||
title: "groups.background",
|
title: "groups.background",
|
||||||
fields: ["transparentBg", "backgroundColor"],
|
fields: ["bgOpacity", "backgroundColor"],
|
||||||
},
|
},
|
||||||
{ title: "groups.padding", fields: ["padding"] },
|
{ title: "groups.padding", fields: ["padding"] },
|
||||||
],
|
],
|
||||||
@@ -995,7 +998,7 @@ const textToPng: Tool<TextToPngParams> = {
|
|||||||
bold: p.style.bold,
|
bold: p.style.bold,
|
||||||
color: p.style.color,
|
color: p.style.color,
|
||||||
backgroundColor: p.backgroundColor,
|
backgroundColor: p.backgroundColor,
|
||||||
transparentBg: p.transparentBg,
|
bgOpacity: p.bgOpacity,
|
||||||
padding: p.padding,
|
padding: p.padding,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const addBorder: Tool<AddBorderParams> = {
|
|||||||
|
|
||||||
interface FitOnBackgroundParams {
|
interface FitOnBackgroundParams {
|
||||||
size: Dimension;
|
size: Dimension;
|
||||||
transparent: boolean;
|
opacity: number;
|
||||||
color: string;
|
color: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,9 +79,12 @@ export const fitOnBackgroundSchema = toolSchema<FitOnBackgroundParams>(
|
|||||||
height: 600,
|
height: 600,
|
||||||
presets: true,
|
presets: true,
|
||||||
}),
|
}),
|
||||||
transparent: field.checkbox({
|
opacity: field.slider({
|
||||||
label: "fields.transparent",
|
label: "fields.opacity",
|
||||||
default: false,
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
default: 100,
|
||||||
}),
|
}),
|
||||||
color: field.color({ label: "fields.background", default: "#ffffff" }),
|
color: field.color({ label: "fields.background", default: "#ffffff" }),
|
||||||
},
|
},
|
||||||
@@ -89,7 +92,7 @@ export const fitOnBackgroundSchema = toolSchema<FitOnBackgroundParams>(
|
|||||||
layout: {
|
layout: {
|
||||||
groups: [
|
groups: [
|
||||||
{ title: "groups.canvas", fields: ["size"] },
|
{ title: "groups.canvas", fields: ["size"] },
|
||||||
{ title: "groups.background", fields: ["transparent", "color"] },
|
{ title: "groups.background", fields: ["opacity", "color"] },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -113,7 +116,8 @@ const fitOnBackground: Tool<FitOnBackgroundParams> = {
|
|||||||
top,
|
top,
|
||||||
Math.max(0, width - img.width - left),
|
Math.max(0, width - img.width - left),
|
||||||
Math.max(0, height - img.height - top),
|
Math.max(0, height - img.height - top),
|
||||||
p.transparent ? undefined : p.color,
|
p.color,
|
||||||
|
Math.round((Math.trunc(p.opacity) / 100) * 255),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
@@ -331,7 +335,7 @@ const flipTool: Tool<FlipParams> = {
|
|||||||
|
|
||||||
interface AddPaddingParams {
|
interface AddPaddingParams {
|
||||||
padding: number;
|
padding: number;
|
||||||
transparent: boolean;
|
opacity: number;
|
||||||
color: string;
|
color: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,14 +348,20 @@ export const addPaddingSchema = toolSchema<AddPaddingParams>(
|
|||||||
step: 1,
|
step: 1,
|
||||||
default: 10,
|
default: 10,
|
||||||
}),
|
}),
|
||||||
transparent: field.checkbox({ label: "fields.transparent", default: true }),
|
opacity: field.slider({
|
||||||
|
label: "fields.opacity",
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
step: 1,
|
||||||
|
default: 0,
|
||||||
|
}),
|
||||||
color: field.color({ label: "fields.fillColor", default: "#ffffff" }),
|
color: field.color({ label: "fields.fillColor", default: "#ffffff" }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
layout: {
|
layout: {
|
||||||
groups: [
|
groups: [
|
||||||
{ title: "groups.padding", fields: ["padding"] },
|
{ title: "groups.padding", fields: ["padding"] },
|
||||||
{ title: "groups.fill", fields: ["transparent", "color"] },
|
{ title: "groups.fill", fields: ["opacity", "color"] },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -368,7 +378,8 @@ const addPaddingTool: Tool<AddPaddingParams> = {
|
|||||||
p.padding,
|
p.padding,
|
||||||
p.padding,
|
p.padding,
|
||||||
p.padding,
|
p.padding,
|
||||||
p.transparent ? undefined : p.color,
|
p.color,
|
||||||
|
Math.round((Math.trunc(p.opacity) / 100) * 255),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user