@pixerate/editor-react 0.69.0 → 0.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-LCTQWNTL.js → chunk-63FQB5BT.js} +577 -226
- package/dist/chunk-63FQB5BT.js.map +1 -0
- package/dist/image-editor/index.cjs +616 -269
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +30 -2
- package/dist/image-editor/index.d.ts +30 -2
- package/dist/image-editor/index.js +5 -1
- package/dist/index.cjs +1045 -698
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/paint-editor/index.cjs +108 -2
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +6 -3
- package/dist/paint-editor/index.d.ts +6 -3
- package/dist/paint-editor/index.js +125 -6
- package/dist/paint-editor/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-LCTQWNTL.js.map +0 -1
|
@@ -41,6 +41,8 @@ __export(image_editor_exports, {
|
|
|
41
41
|
LayersPanel: () => LayersPanel,
|
|
42
42
|
RefineEdgePanel: () => RefineEdgePanel,
|
|
43
43
|
SelectionOptionsBar: () => SelectionOptionsBar,
|
|
44
|
+
ShapeOptionsBar: () => ShapeOptionsBar,
|
|
45
|
+
TypeOptionsBar: () => TypeOptionsBar,
|
|
44
46
|
useImageEditor: () => useImageEditor,
|
|
45
47
|
useImageHistogram: () => useImageHistogram
|
|
46
48
|
});
|
|
@@ -205,8 +207,8 @@ function useImageEditor(options = {}) {
|
|
|
205
207
|
}
|
|
206
208
|
|
|
207
209
|
// src/image-editor/ImageEditor.tsx
|
|
208
|
-
var
|
|
209
|
-
var
|
|
210
|
+
var import_react13 = __toESM(require("react"), 1);
|
|
211
|
+
var import_image_editor14 = require("@pixerate/editor/image-editor");
|
|
210
212
|
|
|
211
213
|
// src/image-editor/ControlSlider.tsx
|
|
212
214
|
var import_image_editor2 = require("@pixerate/editor/image-editor");
|
|
@@ -916,7 +918,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
916
918
|
const placement = (0, import_image_editor7.dropPlacement)(state.layers, id, row.layer.id, (0, import_image_editor7.dropZone)(fraction, row.layer.type === "group"));
|
|
917
919
|
if (placement) attempt(() => controller.moveLayer(id, placement));
|
|
918
920
|
};
|
|
919
|
-
const thumb = (layer) => layer
|
|
921
|
+
const thumb = (layer) => (0, import_image_editor7.layerHasThumbnail)(layer) ? controller.getLayerThumbnail(layer.id, { maxSide: 64 }) : null;
|
|
920
922
|
const maskThumb = (layer) => layer.mask && !layer.mask.source ? controller.getLayerThumbnail(layer.id, { maxSide: 64, mask: true }) : null;
|
|
921
923
|
const locked = (layer) => Boolean(layer.locks?.all || layer.locks?.pixels || layer.locks?.position || layer.locks?.transparency);
|
|
922
924
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "layers-panel", onClick: () => menu && setMenu(null), children: [
|
|
@@ -1109,15 +1111,25 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
1109
1111
|
}
|
|
1110
1112
|
),
|
|
1111
1113
|
row.clipped && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-slate-500", "aria-label": "Clipped", children: "\u21B3" }),
|
|
1112
|
-
layer
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1114
|
+
(0, import_image_editor7.layerHasThumbnail)(layer) ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "relative shrink-0", children: [
|
|
1115
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1116
|
+
Thumbnail,
|
|
1117
|
+
{
|
|
1118
|
+
pixels: thumb(layer),
|
|
1119
|
+
size: thumbnailSize,
|
|
1120
|
+
label: `${row.label} pixels`,
|
|
1121
|
+
selected: row.active && state.activeTarget === "pixels" && Boolean(layer.mask)
|
|
1122
|
+
}
|
|
1123
|
+
),
|
|
1124
|
+
layer.type !== "pixel" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1125
|
+
"span",
|
|
1126
|
+
{
|
|
1127
|
+
"data-testid": "layer-kind-badge",
|
|
1128
|
+
className: "absolute -bottom-1 -right-1 rounded bg-slate-700 px-0.5 text-[8px] font-bold leading-tight text-slate-100 ring-1 ring-slate-900",
|
|
1129
|
+
children: (0, import_image_editor7.layerBadge)(layer)
|
|
1130
|
+
}
|
|
1131
|
+
)
|
|
1132
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1121
1133
|
"span",
|
|
1122
1134
|
{
|
|
1123
1135
|
className: "shrink-0 grid place-items-center rounded bg-slate-800 text-[9px] text-slate-400 ring-1 ring-slate-700",
|
|
@@ -1184,6 +1196,7 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
1184
1196
|
children: row.label
|
|
1185
1197
|
}
|
|
1186
1198
|
),
|
|
1199
|
+
(0, import_image_editor7.layerWarning)(layer) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { role: "img", "data-testid": "layer-warning", "aria-label": (0, import_image_editor7.layerWarning)(layer), title: (0, import_image_editor7.layerWarning)(layer), className: "text-[10px] text-amber-400", children: "\u26A0" }),
|
|
1187
1200
|
(0, import_image_editor7.layerEffectsBadge)(layer) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1188
1201
|
"button",
|
|
1189
1202
|
{
|
|
@@ -1791,8 +1804,215 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1791
1804
|
] });
|
|
1792
1805
|
};
|
|
1793
1806
|
|
|
1794
|
-
// src/image-editor/
|
|
1807
|
+
// src/image-editor/ShapeOptionsBar.tsx
|
|
1808
|
+
var import_react11 = require("react");
|
|
1809
|
+
var import_image_editor12 = require("@pixerate/editor/image-editor");
|
|
1795
1810
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1811
|
+
var chip3 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
1812
|
+
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
1813
|
+
const [, setTick] = (0, import_react11.useState)(0);
|
|
1814
|
+
(0, import_react11.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1815
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
1816
|
+
const active = controller.getActiveLayer();
|
|
1817
|
+
const shapeId = active?.type === "shape" ? active.id : null;
|
|
1818
|
+
const set = (change) => {
|
|
1819
|
+
onChange({ ...options, ...change });
|
|
1820
|
+
if (!shapeId) return;
|
|
1821
|
+
try {
|
|
1822
|
+
setError(null);
|
|
1823
|
+
(0, import_image_editor12.applyShapeOptions)(controller, shapeId, change);
|
|
1824
|
+
} catch (e) {
|
|
1825
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
1826
|
+
}
|
|
1827
|
+
};
|
|
1828
|
+
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
1829
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
|
|
1830
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: import_image_editor12.LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-pressed": options.kind === k, className: chip3(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: import_image_editor12.SHAPE_KIND_LABELS[k] }, k)) }),
|
|
1831
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
1832
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1833
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
|
|
1834
|
+
"Fill",
|
|
1835
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1836
|
+
"input",
|
|
1837
|
+
{
|
|
1838
|
+
type: "color",
|
|
1839
|
+
"aria-label": "Fill colour",
|
|
1840
|
+
disabled: options.fill === null,
|
|
1841
|
+
value: options.fill ?? "#4f46e5",
|
|
1842
|
+
onChange: (e) => set({ fill: e.target.value }),
|
|
1843
|
+
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
1844
|
+
}
|
|
1845
|
+
)
|
|
1846
|
+
] }),
|
|
1847
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1848
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
|
|
1849
|
+
"Stroke",
|
|
1850
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1851
|
+
"input",
|
|
1852
|
+
{
|
|
1853
|
+
type: "color",
|
|
1854
|
+
"aria-label": "Stroke colour",
|
|
1855
|
+
disabled: options.stroke === null,
|
|
1856
|
+
value: options.stroke ?? "#000000",
|
|
1857
|
+
onChange: (e) => set({ stroke: e.target.value }),
|
|
1858
|
+
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
1859
|
+
}
|
|
1860
|
+
)
|
|
1861
|
+
] }),
|
|
1862
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1863
|
+
"Width",
|
|
1864
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1865
|
+
"input",
|
|
1866
|
+
{
|
|
1867
|
+
type: "number",
|
|
1868
|
+
"aria-label": "Stroke width",
|
|
1869
|
+
min: 0,
|
|
1870
|
+
max: 200,
|
|
1871
|
+
value: options.strokeWidth,
|
|
1872
|
+
onChange: (e) => set({ strokeWidth: num(e.target.value, 0, 200) }),
|
|
1873
|
+
className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
1874
|
+
}
|
|
1875
|
+
)
|
|
1876
|
+
] })
|
|
1877
|
+
] }),
|
|
1878
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
1879
|
+
options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1880
|
+
"Radius",
|
|
1881
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "number", "aria-label": "Corner radius", min: 0, max: 1e3, value: options.radius, onChange: (e) => set({ radius: num(e.target.value, 0, 1e3) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1882
|
+
] }),
|
|
1883
|
+
options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1884
|
+
"Sides",
|
|
1885
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "number", "aria-label": "Sides", min: 3, max: 100, value: options.sides, onChange: (e) => set({ sides: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1886
|
+
] }),
|
|
1887
|
+
options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1888
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1889
|
+
"Points",
|
|
1890
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "number", "aria-label": "Points", min: 3, max: 100, value: options.points, onChange: (e) => set({ points: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1891
|
+
] }),
|
|
1892
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1893
|
+
"Inner",
|
|
1894
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1895
|
+
"input",
|
|
1896
|
+
{
|
|
1897
|
+
type: "range",
|
|
1898
|
+
"aria-label": "Inner radius",
|
|
1899
|
+
min: 0.05,
|
|
1900
|
+
max: 1,
|
|
1901
|
+
step: 0.05,
|
|
1902
|
+
value: options.innerRatio,
|
|
1903
|
+
onChange: (e) => set({ innerRatio: Number(e.target.value) }),
|
|
1904
|
+
className: "accent-indigo-500"
|
|
1905
|
+
}
|
|
1906
|
+
)
|
|
1907
|
+
] })
|
|
1908
|
+
] }),
|
|
1909
|
+
options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1910
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1911
|
+
"Weight",
|
|
1912
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "number", "aria-label": "Line weight", min: 1, max: 200, value: options.weight, onChange: (e) => set({ weight: num(e.target.value, 1, 200) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1913
|
+
] }),
|
|
1914
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1915
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
|
|
1916
|
+
"Arrowhead"
|
|
1917
|
+
] })
|
|
1918
|
+
] })
|
|
1919
|
+
] }),
|
|
1920
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-[10px] text-slate-500", children: "Drag on the image to draw. Shift: square, circle or 45\xB0 line. Alt: from the centre." }),
|
|
1921
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1922
|
+
] });
|
|
1923
|
+
};
|
|
1924
|
+
|
|
1925
|
+
// src/image-editor/TypeOptionsBar.tsx
|
|
1926
|
+
var import_react12 = require("react");
|
|
1927
|
+
var import_image_editor13 = require("@pixerate/editor/image-editor");
|
|
1928
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1929
|
+
var chip4 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
1930
|
+
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
1931
|
+
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
1932
|
+
const [, setTick] = (0, import_react12.useState)(0);
|
|
1933
|
+
(0, import_react12.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1934
|
+
(0, import_react12.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
|
|
1935
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
1936
|
+
const active = controller.getActiveLayer();
|
|
1937
|
+
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
1938
|
+
const here = session?.alive ? session.styleHere() : {};
|
|
1939
|
+
const shown = {
|
|
1940
|
+
...options,
|
|
1941
|
+
...here.fontFamily ? { fontFamily: here.fontFamily } : {},
|
|
1942
|
+
...here.fontSize ? { fontSize: here.fontSize } : {},
|
|
1943
|
+
...here.fontWeight ? { fontWeight: here.fontWeight } : {},
|
|
1944
|
+
...session?.alive ? { italic: Boolean(here.italic), color: here.color ?? options.color } : {}
|
|
1945
|
+
};
|
|
1946
|
+
const fonts = controller.listFonts();
|
|
1947
|
+
const missing = active?.type === "type" ? active.missingFonts ?? [] : [];
|
|
1948
|
+
const style = (change) => {
|
|
1949
|
+
onChange({ ...options, ...change });
|
|
1950
|
+
const s = {};
|
|
1951
|
+
for (const k of ["fontFamily", "fontSize", "fontWeight", "italic", "color"]) if (k in change) s[k] = change[k];
|
|
1952
|
+
const p = change.align ? { align: change.align } : null;
|
|
1953
|
+
try {
|
|
1954
|
+
setError(null);
|
|
1955
|
+
if (session?.alive) {
|
|
1956
|
+
if (Object.keys(s).length) session.setStyle(s);
|
|
1957
|
+
if (p) session.setParagraph(p);
|
|
1958
|
+
if (session.error) setError(session.error);
|
|
1959
|
+
} else if (typeId) {
|
|
1960
|
+
if (Object.keys(s).length) controller.setTextStyle(typeId, s);
|
|
1961
|
+
if (p) controller.setParagraphStyle(typeId, p);
|
|
1962
|
+
}
|
|
1963
|
+
} catch (e) {
|
|
1964
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
1965
|
+
}
|
|
1966
|
+
};
|
|
1967
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
|
|
1968
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
1969
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1970
|
+
"Font",
|
|
1971
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1972
|
+
"input",
|
|
1973
|
+
{
|
|
1974
|
+
list: "pixerate-type-fonts",
|
|
1975
|
+
"aria-label": "Font family",
|
|
1976
|
+
value: shown.fontFamily,
|
|
1977
|
+
onChange: (e) => e.target.value.trim() && style({ fontFamily: e.target.value }),
|
|
1978
|
+
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
1979
|
+
}
|
|
1980
|
+
),
|
|
1981
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: f }, f)) })
|
|
1982
|
+
] }),
|
|
1983
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1984
|
+
"Size",
|
|
1985
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1986
|
+
"input",
|
|
1987
|
+
{
|
|
1988
|
+
type: "number",
|
|
1989
|
+
"aria-label": "Font size",
|
|
1990
|
+
min: 1,
|
|
1991
|
+
max: 2e3,
|
|
1992
|
+
value: Math.round(shown.fontSize * 10) / 10,
|
|
1993
|
+
onChange: (e) => Number(e.target.value) > 0 && style({ fontSize: Number(e.target.value) }),
|
|
1994
|
+
className: "w-16 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
1995
|
+
}
|
|
1996
|
+
)
|
|
1997
|
+
] }),
|
|
1998
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "aria-pressed": shown.fontWeight >= 600, className: `${chip4(shown.fontWeight >= 600)} font-bold`, onClick: () => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 }), children: "B" }),
|
|
1999
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "aria-pressed": shown.italic, className: `${chip4(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
|
|
2000
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "color", "aria-label": "Text colour", value: shown.color, onChange: (e) => style({ color: e.target.value }), className: "h-6 w-8 rounded border border-slate-700 bg-transparent" })
|
|
2001
|
+
] }),
|
|
2002
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: import_image_editor13.TEXT_ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "aria-pressed": options.align === a, className: chip4(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
|
|
2003
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-[10px] text-slate-500", children: "Click to type point text, drag for a paragraph box, click text to edit it. Esc finishes." }),
|
|
2004
|
+
missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
|
|
2005
|
+
"Missing ",
|
|
2006
|
+
missing.length === 1 ? "font" : "fonts",
|
|
2007
|
+
": ",
|
|
2008
|
+
missing.join(", ")
|
|
2009
|
+
] }),
|
|
2010
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
2011
|
+
] });
|
|
2012
|
+
};
|
|
2013
|
+
|
|
2014
|
+
// src/image-editor/ImageEditor.tsx
|
|
2015
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1796
2016
|
var ImageEditor = ({
|
|
1797
2017
|
editor: externalEditor,
|
|
1798
2018
|
src,
|
|
@@ -1807,47 +2027,65 @@ var ImageEditor = ({
|
|
|
1807
2027
|
const internalEditor = useImageEditor({ image: src });
|
|
1808
2028
|
const editor = externalEditor || internalEditor;
|
|
1809
2029
|
const { state, controller } = editor;
|
|
1810
|
-
const legacyProcess = (0,
|
|
1811
|
-
const canvasRef = (0,
|
|
1812
|
-
const containerRef = (0,
|
|
1813
|
-
const [activeTab, setActiveTab] = (0,
|
|
1814
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
1815
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
1816
|
-
const selectionOptionsRef = (0,
|
|
2030
|
+
const legacyProcess = (0, import_image_editor14.normalizeProcessVersion)(state.adjustments.process) < import_image_editor14.LATEST_PROCESS_VERSION;
|
|
2031
|
+
const canvasRef = (0, import_react13.useRef)(null);
|
|
2032
|
+
const containerRef = (0, import_react13.useRef)(null);
|
|
2033
|
+
const [activeTab, setActiveTab] = (0, import_react13.useState)("crop");
|
|
2034
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react13.useState)(null);
|
|
2035
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react13.useState)(import_image_editor14.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
2036
|
+
const selectionOptionsRef = (0, import_react13.useRef)(selectionOptions);
|
|
1817
2037
|
selectionOptionsRef.current = selectionOptions;
|
|
1818
|
-
const selectionGestureRef = (0,
|
|
2038
|
+
const selectionGestureRef = (0, import_react13.useRef)(null);
|
|
1819
2039
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
1820
|
-
selectionGestureRef.current = new
|
|
2040
|
+
selectionGestureRef.current = new import_image_editor14.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
1821
2041
|
}
|
|
1822
|
-
const selectionDraftRef = (0,
|
|
1823
|
-
const [selectionError, setSelectionError] = (0,
|
|
1824
|
-
const paintGestureRef = (0,
|
|
1825
|
-
const paintControllerRef = (0,
|
|
2042
|
+
const selectionDraftRef = (0, import_react13.useRef)(null);
|
|
2043
|
+
const [selectionError, setSelectionError] = (0, import_react13.useState)(null);
|
|
2044
|
+
const paintGestureRef = (0, import_react13.useRef)(null);
|
|
2045
|
+
const paintControllerRef = (0, import_react13.useRef)(controller);
|
|
1826
2046
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
1827
|
-
paintGestureRef.current = new
|
|
2047
|
+
paintGestureRef.current = new import_image_editor14.PaintGesture(controller);
|
|
1828
2048
|
paintControllerRef.current = controller;
|
|
1829
2049
|
}
|
|
1830
|
-
const brushCursorRef = (0,
|
|
1831
|
-
const [paintError, setPaintError] = (0,
|
|
1832
|
-
const transformToolRef = (0,
|
|
1833
|
-
const transformControllerRef = (0,
|
|
2050
|
+
const brushCursorRef = (0, import_react13.useRef)(null);
|
|
2051
|
+
const [paintError, setPaintError] = (0, import_react13.useState)(null);
|
|
2052
|
+
const transformToolRef = (0, import_react13.useRef)(null);
|
|
2053
|
+
const transformControllerRef = (0, import_react13.useRef)(controller);
|
|
1834
2054
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
1835
2055
|
transformToolRef.current?.cancel();
|
|
1836
|
-
transformToolRef.current = new
|
|
2056
|
+
transformToolRef.current = new import_image_editor14.FreeTransformTool(controller, {
|
|
1837
2057
|
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
1838
2058
|
});
|
|
1839
2059
|
transformControllerRef.current = controller;
|
|
1840
2060
|
}
|
|
1841
2061
|
const transformTool = transformToolRef.current;
|
|
1842
|
-
const [, setTransformTick] = (0,
|
|
1843
|
-
const [transformCursor, setTransformCursor] = (0,
|
|
1844
|
-
const [
|
|
1845
|
-
const
|
|
1846
|
-
|
|
1847
|
-
const [
|
|
1848
|
-
const
|
|
1849
|
-
|
|
1850
|
-
const
|
|
2062
|
+
const [, setTransformTick] = (0, import_react13.useState)(0);
|
|
2063
|
+
const [transformCursor, setTransformCursor] = (0, import_react13.useState)("default");
|
|
2064
|
+
const [shapeOptions, setShapeOptions] = (0, import_react13.useState)(import_image_editor14.DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
2065
|
+
const shapeOptionsRef = (0, import_react13.useRef)(shapeOptions);
|
|
2066
|
+
shapeOptionsRef.current = shapeOptions;
|
|
2067
|
+
const [typeOptions, setTypeOptions] = (0, import_react13.useState)(import_image_editor14.DEFAULT_TYPE_TOOL_OPTIONS);
|
|
2068
|
+
const typeOptionsRef = (0, import_react13.useRef)(typeOptions);
|
|
2069
|
+
typeOptionsRef.current = typeOptions;
|
|
2070
|
+
const shapeGestureRef = (0, import_react13.useRef)(null);
|
|
2071
|
+
const typeToolRef = (0, import_react13.useRef)(null);
|
|
2072
|
+
const shapeTypeControllerRef = (0, import_react13.useRef)(controller);
|
|
2073
|
+
if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
|
|
2074
|
+
typeToolRef.current?.finish();
|
|
2075
|
+
shapeGestureRef.current = new import_image_editor14.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
|
|
2076
|
+
typeToolRef.current = new import_image_editor14.TypeToolGesture(controller, () => typeOptionsRef.current);
|
|
2077
|
+
shapeTypeControllerRef.current = controller;
|
|
2078
|
+
}
|
|
2079
|
+
const typeInputRef = (0, import_react13.useRef)(null);
|
|
2080
|
+
const [typeSession, setTypeSession] = (0, import_react13.useState)(typeToolRef.current.session);
|
|
2081
|
+
const [shapeTypeError, setShapeTypeError] = (0, import_react13.useState)(null);
|
|
2082
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react13.useState)("");
|
|
2083
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react13.useState)("annotations");
|
|
2084
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react13.useState)(false);
|
|
2085
|
+
const [isInpainting, setIsInpainting] = (0, import_react13.useState)(false);
|
|
2086
|
+
const [aiError, setAiError] = (0, import_react13.useState)(null);
|
|
2087
|
+
const [aiSuccess, setAiSuccess] = (0, import_react13.useState)(null);
|
|
2088
|
+
const [aiTarget, setAiTarget] = (0, import_react13.useState)("auto");
|
|
1851
2089
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
1852
2090
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
1853
2091
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -1910,18 +2148,18 @@ var ImageEditor = ({
|
|
|
1910
2148
|
setIsInpainting(false);
|
|
1911
2149
|
}
|
|
1912
2150
|
};
|
|
1913
|
-
const [activeColor, setActiveColor] = (0,
|
|
1914
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
1915
|
-
const [fontSize, setFontSize] = (0,
|
|
1916
|
-
const [textInput, setTextInput] = (0,
|
|
1917
|
-
const draftAnnotationRef = (0,
|
|
1918
|
-
const draftCropRef = (0,
|
|
1919
|
-
const cropDragInfoRef = (0,
|
|
1920
|
-
const annotationDragInfoRef = (0,
|
|
1921
|
-
const isDrawingRef = (0,
|
|
1922
|
-
const currentPathRef = (0,
|
|
1923
|
-
const dragStartPointRef = (0,
|
|
1924
|
-
const renderCanvas = (0,
|
|
2151
|
+
const [activeColor, setActiveColor] = (0, import_react13.useState)("#ef4444");
|
|
2152
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react13.useState)(3);
|
|
2153
|
+
const [fontSize, setFontSize] = (0, import_react13.useState)(24);
|
|
2154
|
+
const [textInput, setTextInput] = (0, import_react13.useState)("");
|
|
2155
|
+
const draftAnnotationRef = (0, import_react13.useRef)(null);
|
|
2156
|
+
const draftCropRef = (0, import_react13.useRef)(null);
|
|
2157
|
+
const cropDragInfoRef = (0, import_react13.useRef)(null);
|
|
2158
|
+
const annotationDragInfoRef = (0, import_react13.useRef)(null);
|
|
2159
|
+
const isDrawingRef = (0, import_react13.useRef)(false);
|
|
2160
|
+
const currentPathRef = (0, import_react13.useRef)([]);
|
|
2161
|
+
const dragStartPointRef = (0, import_react13.useRef)(null);
|
|
2162
|
+
const renderCanvas = (0, import_react13.useCallback)(
|
|
1925
2163
|
async (draftAnnotation, draftCrop) => {
|
|
1926
2164
|
const canvas = canvasRef.current;
|
|
1927
2165
|
const container = containerRef.current;
|
|
@@ -1938,12 +2176,49 @@ var ImageEditor = ({
|
|
|
1938
2176
|
draftCrop: draftCrop !== void 0 ? draftCrop : draftCropRef.current,
|
|
1939
2177
|
draftSelectionPath: selectionDraftRef.current,
|
|
1940
2178
|
brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" && !transformTool.active ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null,
|
|
1941
|
-
freeTransform: transformTool.overlay()
|
|
2179
|
+
freeTransform: transformTool.overlay(),
|
|
2180
|
+
textEdit: typeToolRef.current?.session?.alive ? typeToolRef.current.session.overlay() : null
|
|
1942
2181
|
});
|
|
1943
2182
|
},
|
|
1944
2183
|
[controller, activeTab, transformTool]
|
|
1945
2184
|
);
|
|
1946
|
-
(0,
|
|
2185
|
+
(0, import_react13.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
2186
|
+
(0, import_react13.useEffect)(() => {
|
|
2187
|
+
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
2188
|
+
if (typeToolRef.current?.session) {
|
|
2189
|
+
typeToolRef.current.finish();
|
|
2190
|
+
setTypeSession(null);
|
|
2191
|
+
void renderCanvas();
|
|
2192
|
+
}
|
|
2193
|
+
}, [activeTab, state.activeTool, renderCanvas]);
|
|
2194
|
+
const finishTyping = () => {
|
|
2195
|
+
typeToolRef.current?.finish();
|
|
2196
|
+
setTypeSession(null);
|
|
2197
|
+
void renderCanvas();
|
|
2198
|
+
};
|
|
2199
|
+
const handleTypeKeyDown = (e) => {
|
|
2200
|
+
const session = typeToolRef.current?.session;
|
|
2201
|
+
if (!session || e.nativeEvent.isComposing) return;
|
|
2202
|
+
if (e.key === "Escape") {
|
|
2203
|
+
e.preventDefault();
|
|
2204
|
+
finishTyping();
|
|
2205
|
+
return;
|
|
2206
|
+
}
|
|
2207
|
+
if ((e.metaKey || e.ctrlKey) && ["z", "y", "c", "x", "v"].includes(e.key.toLowerCase())) return;
|
|
2208
|
+
if (session.handleKey(e)) {
|
|
2209
|
+
e.preventDefault();
|
|
2210
|
+
setShapeTypeError(session.error);
|
|
2211
|
+
}
|
|
2212
|
+
};
|
|
2213
|
+
const handleTypeInput = (e) => {
|
|
2214
|
+
const el = e.currentTarget;
|
|
2215
|
+
const session = typeToolRef.current?.session;
|
|
2216
|
+
if (session && el.value && !e.nativeEvent.isComposing) {
|
|
2217
|
+
session.insert(el.value);
|
|
2218
|
+
el.value = "";
|
|
2219
|
+
}
|
|
2220
|
+
};
|
|
2221
|
+
(0, import_react13.useEffect)(() => transformTool.subscribe(() => {
|
|
1947
2222
|
setTransformTick((n) => n + 1);
|
|
1948
2223
|
void renderCanvas();
|
|
1949
2224
|
}), [transformTool, renderCanvas]);
|
|
@@ -1954,8 +2229,8 @@ var ImageEditor = ({
|
|
|
1954
2229
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
1955
2230
|
const s = controller.getState();
|
|
1956
2231
|
const cropping = activeTab === "crop";
|
|
1957
|
-
const projection = (0,
|
|
1958
|
-
const pt = (0,
|
|
2232
|
+
const projection = (0, import_image_editor14.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
2233
|
+
const pt = (0, import_image_editor14.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
|
|
1959
2234
|
transformTool.setView(projection.scale);
|
|
1960
2235
|
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
1961
2236
|
};
|
|
@@ -1986,7 +2261,7 @@ var ImageEditor = ({
|
|
|
1986
2261
|
transformTool.up();
|
|
1987
2262
|
return true;
|
|
1988
2263
|
};
|
|
1989
|
-
(0,
|
|
2264
|
+
(0, import_react13.useEffect)(() => {
|
|
1990
2265
|
if (typeof window === "undefined") return;
|
|
1991
2266
|
const onKey = (e) => {
|
|
1992
2267
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -1994,7 +2269,7 @@ var ImageEditor = ({
|
|
|
1994
2269
|
window.addEventListener("keydown", onKey);
|
|
1995
2270
|
return () => window.removeEventListener("keydown", onKey);
|
|
1996
2271
|
}, [transformTool]);
|
|
1997
|
-
(0,
|
|
2272
|
+
(0, import_react13.useEffect)(() => {
|
|
1998
2273
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
1999
2274
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
2000
2275
|
const animId = raf(() => {
|
|
@@ -2002,12 +2277,12 @@ var ImageEditor = ({
|
|
|
2002
2277
|
});
|
|
2003
2278
|
return () => caf(animId);
|
|
2004
2279
|
}, [renderCanvas, state]);
|
|
2005
|
-
(0,
|
|
2280
|
+
(0, import_react13.useEffect)(() => {
|
|
2006
2281
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
2007
2282
|
editor.setTool("crop");
|
|
2008
2283
|
}
|
|
2009
2284
|
}, [activeTab, editor]);
|
|
2010
|
-
(0,
|
|
2285
|
+
(0, import_react13.useEffect)(() => {
|
|
2011
2286
|
const container = containerRef.current;
|
|
2012
2287
|
if (!container) return;
|
|
2013
2288
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -2043,8 +2318,8 @@ var ImageEditor = ({
|
|
|
2043
2318
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
2044
2319
|
const s = controller.getState();
|
|
2045
2320
|
return list.map((ev) => ({
|
|
2046
|
-
...(0,
|
|
2047
|
-
pressure: (0,
|
|
2321
|
+
...(0, import_image_editor14.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
2322
|
+
pressure: (0, import_image_editor14.pointerPressure)(ev)
|
|
2048
2323
|
}));
|
|
2049
2324
|
};
|
|
2050
2325
|
const handlePaintPointerDown = (e) => {
|
|
@@ -2075,10 +2350,10 @@ var ImageEditor = ({
|
|
|
2075
2350
|
if (g.error) setPaintError(g.error);
|
|
2076
2351
|
}
|
|
2077
2352
|
};
|
|
2078
|
-
(0,
|
|
2353
|
+
(0, import_react13.useEffect)(() => {
|
|
2079
2354
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
2080
2355
|
const onKey = (e) => {
|
|
2081
|
-
if ((0,
|
|
2356
|
+
if ((0, import_image_editor14.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
2082
2357
|
};
|
|
2083
2358
|
window.addEventListener("keydown", onKey);
|
|
2084
2359
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -2089,7 +2364,7 @@ var ImageEditor = ({
|
|
|
2089
2364
|
const canvasPt = getCanvasEventPoint(e);
|
|
2090
2365
|
if (activeTab === "select") {
|
|
2091
2366
|
const gesture = selectionGestureRef.current;
|
|
2092
|
-
const imgPt = (0,
|
|
2367
|
+
const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2093
2368
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
2094
2369
|
return;
|
|
2095
2370
|
}
|
|
@@ -2100,8 +2375,8 @@ var ImageEditor = ({
|
|
|
2100
2375
|
width: state.imageDimensions.width,
|
|
2101
2376
|
height: state.imageDimensions.height
|
|
2102
2377
|
};
|
|
2103
|
-
const handle = (0,
|
|
2104
|
-
const startImgPt = (0,
|
|
2378
|
+
const handle = (0, import_image_editor14.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2379
|
+
const startImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
2105
2380
|
if (handle) {
|
|
2106
2381
|
cropDragInfoRef.current = {
|
|
2107
2382
|
handle,
|
|
@@ -2119,13 +2394,24 @@ var ImageEditor = ({
|
|
|
2119
2394
|
}
|
|
2120
2395
|
return;
|
|
2121
2396
|
}
|
|
2397
|
+
if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
|
|
2398
|
+
const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2399
|
+
setShapeTypeError(null);
|
|
2400
|
+
if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
|
|
2401
|
+
else {
|
|
2402
|
+
typeToolRef.current.down(imgPt, { shift: e.shiftKey });
|
|
2403
|
+
setTypeSession(typeToolRef.current.session);
|
|
2404
|
+
void renderCanvas();
|
|
2405
|
+
}
|
|
2406
|
+
return;
|
|
2407
|
+
}
|
|
2122
2408
|
if (activeTab === "annotate") {
|
|
2123
|
-
const imgPt = (0,
|
|
2409
|
+
const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2124
2410
|
dragStartPointRef.current = imgPt;
|
|
2125
2411
|
if (state.activeTool === "select") {
|
|
2126
2412
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
2127
2413
|
const ann = state.annotations[i];
|
|
2128
|
-
if ((0,
|
|
2414
|
+
if ((0, import_image_editor14.hitTestAnnotation)(imgPt, ann)) {
|
|
2129
2415
|
editor.selectAnnotation(ann.id);
|
|
2130
2416
|
annotationDragInfoRef.current = {
|
|
2131
2417
|
annId: ann.id,
|
|
@@ -2161,7 +2447,7 @@ var ImageEditor = ({
|
|
|
2161
2447
|
const canvasPt = getCanvasEventPoint(e);
|
|
2162
2448
|
if (activeTab === "select") {
|
|
2163
2449
|
const gesture = selectionGestureRef.current;
|
|
2164
|
-
if (gesture.active && gesture.move((0,
|
|
2450
|
+
if (gesture.active && gesture.move((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
2165
2451
|
selectionDraftRef.current = gesture.draftPath;
|
|
2166
2452
|
renderCanvas();
|
|
2167
2453
|
}
|
|
@@ -2170,7 +2456,7 @@ var ImageEditor = ({
|
|
|
2170
2456
|
if (activeTab === "crop") {
|
|
2171
2457
|
const drag = cropDragInfoRef.current;
|
|
2172
2458
|
if (drag) {
|
|
2173
|
-
const currentImgPt = (0,
|
|
2459
|
+
const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
2174
2460
|
let newCrop;
|
|
2175
2461
|
if (drag.handle === "new") {
|
|
2176
2462
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -2184,7 +2470,7 @@ var ImageEditor = ({
|
|
|
2184
2470
|
height: Math.round(Math.max(20, maxY - minY))
|
|
2185
2471
|
};
|
|
2186
2472
|
} else {
|
|
2187
|
-
newCrop = (0,
|
|
2473
|
+
newCrop = (0, import_image_editor14.calculateCropDrag)(
|
|
2188
2474
|
drag.startCrop,
|
|
2189
2475
|
drag.handle,
|
|
2190
2476
|
drag.startImgPt,
|
|
@@ -2204,15 +2490,23 @@ var ImageEditor = ({
|
|
|
2204
2490
|
width: state.imageDimensions.width,
|
|
2205
2491
|
height: state.imageDimensions.height
|
|
2206
2492
|
};
|
|
2207
|
-
const handle = (0,
|
|
2208
|
-
canvas.style.cursor = (0,
|
|
2493
|
+
const handle = (0, import_image_editor14.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2494
|
+
canvas.style.cursor = (0, import_image_editor14.getCropCursor)(handle, state.transform);
|
|
2495
|
+
}
|
|
2496
|
+
return;
|
|
2497
|
+
}
|
|
2498
|
+
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
2499
|
+
const g = shapeGestureRef.current;
|
|
2500
|
+
if (g.active) {
|
|
2501
|
+
g.move((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
|
|
2502
|
+
if (g.error) setShapeTypeError(g.error);
|
|
2209
2503
|
}
|
|
2210
2504
|
return;
|
|
2211
2505
|
}
|
|
2212
2506
|
if (activeTab === "annotate") {
|
|
2213
2507
|
if (annotationDragInfoRef.current) {
|
|
2214
2508
|
const drag = annotationDragInfoRef.current;
|
|
2215
|
-
const currentImgPt2 = (0,
|
|
2509
|
+
const currentImgPt2 = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2216
2510
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
2217
2511
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
2218
2512
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -2224,10 +2518,10 @@ var ImageEditor = ({
|
|
|
2224
2518
|
const startPt = dragStartPointRef.current;
|
|
2225
2519
|
if (!startPt) {
|
|
2226
2520
|
if (state.activeTool === "select") {
|
|
2227
|
-
const imgPt = (0,
|
|
2521
|
+
const imgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2228
2522
|
let hovered = false;
|
|
2229
2523
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
2230
|
-
if ((0,
|
|
2524
|
+
if ((0, import_image_editor14.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
2231
2525
|
hovered = true;
|
|
2232
2526
|
break;
|
|
2233
2527
|
}
|
|
@@ -2238,7 +2532,7 @@ var ImageEditor = ({
|
|
|
2238
2532
|
}
|
|
2239
2533
|
return;
|
|
2240
2534
|
}
|
|
2241
|
-
const currentImgPt = (0,
|
|
2535
|
+
const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2242
2536
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2243
2537
|
currentPathRef.current.push(currentImgPt);
|
|
2244
2538
|
const draft = {
|
|
@@ -2318,7 +2612,7 @@ var ImageEditor = ({
|
|
|
2318
2612
|
if (activeTab === "select") {
|
|
2319
2613
|
const gesture = selectionGestureRef.current;
|
|
2320
2614
|
if (gesture.active) {
|
|
2321
|
-
gesture.end((0,
|
|
2615
|
+
gesture.end((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
2322
2616
|
selectionDraftRef.current = null;
|
|
2323
2617
|
renderCanvas();
|
|
2324
2618
|
}
|
|
@@ -2335,6 +2629,19 @@ var ImageEditor = ({
|
|
|
2335
2629
|
}
|
|
2336
2630
|
return;
|
|
2337
2631
|
}
|
|
2632
|
+
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
2633
|
+
shapeGestureRef.current.up();
|
|
2634
|
+
return;
|
|
2635
|
+
}
|
|
2636
|
+
if (activeTab === "annotate" && state.activeTool === "type") {
|
|
2637
|
+
const tool = typeToolRef.current;
|
|
2638
|
+
tool.up((0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
|
|
2639
|
+
setTypeSession(tool.session);
|
|
2640
|
+
if (tool.error) setShapeTypeError(tool.error);
|
|
2641
|
+
void renderCanvas();
|
|
2642
|
+
if (tool.session) setTimeout(() => typeInputRef.current?.focus(), 0);
|
|
2643
|
+
return;
|
|
2644
|
+
}
|
|
2338
2645
|
if (activeTab === "annotate") {
|
|
2339
2646
|
if (annotationDragInfoRef.current) {
|
|
2340
2647
|
annotationDragInfoRef.current = null;
|
|
@@ -2342,7 +2649,7 @@ var ImageEditor = ({
|
|
|
2342
2649
|
}
|
|
2343
2650
|
const startPt = dragStartPointRef.current;
|
|
2344
2651
|
if (startPt) {
|
|
2345
|
-
const currentImgPt = (0,
|
|
2652
|
+
const currentImgPt = (0, import_image_editor14.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2346
2653
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2347
2654
|
if (currentPathRef.current.length > 1) {
|
|
2348
2655
|
editor.addAnnotation({
|
|
@@ -2438,15 +2745,15 @@ var ImageEditor = ({
|
|
|
2438
2745
|
link.click();
|
|
2439
2746
|
}
|
|
2440
2747
|
};
|
|
2441
|
-
return /* @__PURE__ */ (0,
|
|
2748
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2442
2749
|
"div",
|
|
2443
2750
|
{
|
|
2444
2751
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
2445
2752
|
style,
|
|
2446
2753
|
children: [
|
|
2447
|
-
/* @__PURE__ */ (0,
|
|
2448
|
-
/* @__PURE__ */ (0,
|
|
2449
|
-
/* @__PURE__ */ (0,
|
|
2754
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-wrap items-center justify-between px-4 py-3 bg-slate-950/80 border-b border-slate-800 gap-3", children: [
|
|
2755
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
2756
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2450
2757
|
"button",
|
|
2451
2758
|
{
|
|
2452
2759
|
type: "button",
|
|
@@ -2458,7 +2765,7 @@ var ImageEditor = ({
|
|
|
2458
2765
|
children: "Transform & Crop"
|
|
2459
2766
|
}
|
|
2460
2767
|
),
|
|
2461
|
-
/* @__PURE__ */ (0,
|
|
2768
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2462
2769
|
"button",
|
|
2463
2770
|
{
|
|
2464
2771
|
type: "button",
|
|
@@ -2470,7 +2777,7 @@ var ImageEditor = ({
|
|
|
2470
2777
|
children: "Adjustments"
|
|
2471
2778
|
}
|
|
2472
2779
|
),
|
|
2473
|
-
/* @__PURE__ */ (0,
|
|
2780
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2474
2781
|
"button",
|
|
2475
2782
|
{
|
|
2476
2783
|
type: "button",
|
|
@@ -2482,7 +2789,7 @@ var ImageEditor = ({
|
|
|
2482
2789
|
children: "Layers"
|
|
2483
2790
|
}
|
|
2484
2791
|
),
|
|
2485
|
-
/* @__PURE__ */ (0,
|
|
2792
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2486
2793
|
"button",
|
|
2487
2794
|
{
|
|
2488
2795
|
type: "button",
|
|
@@ -2494,7 +2801,7 @@ var ImageEditor = ({
|
|
|
2494
2801
|
children: "Paint"
|
|
2495
2802
|
}
|
|
2496
2803
|
),
|
|
2497
|
-
/* @__PURE__ */ (0,
|
|
2804
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2498
2805
|
"button",
|
|
2499
2806
|
{
|
|
2500
2807
|
type: "button",
|
|
@@ -2506,7 +2813,7 @@ var ImageEditor = ({
|
|
|
2506
2813
|
children: "Select & Mask"
|
|
2507
2814
|
}
|
|
2508
2815
|
),
|
|
2509
|
-
/* @__PURE__ */ (0,
|
|
2816
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2510
2817
|
"button",
|
|
2511
2818
|
{
|
|
2512
2819
|
type: "button",
|
|
@@ -2518,7 +2825,7 @@ var ImageEditor = ({
|
|
|
2518
2825
|
children: "Annotations"
|
|
2519
2826
|
}
|
|
2520
2827
|
),
|
|
2521
|
-
/* @__PURE__ */ (0,
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2522
2829
|
"button",
|
|
2523
2830
|
{
|
|
2524
2831
|
type: "button",
|
|
@@ -2530,7 +2837,7 @@ var ImageEditor = ({
|
|
|
2530
2837
|
children: "Depth Mask"
|
|
2531
2838
|
}
|
|
2532
2839
|
),
|
|
2533
|
-
/* @__PURE__ */ (0,
|
|
2840
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2534
2841
|
"button",
|
|
2535
2842
|
{
|
|
2536
2843
|
type: "button",
|
|
@@ -2540,14 +2847,14 @@ var ImageEditor = ({
|
|
|
2540
2847
|
},
|
|
2541
2848
|
className: `px-3 py-1.5 rounded-md font-medium transition-colors flex items-center gap-1.5 ${activeTab === "ai" ? "bg-indigo-600 text-white shadow" : "text-slate-400 hover:text-slate-200"}`,
|
|
2542
2849
|
children: [
|
|
2543
|
-
/* @__PURE__ */ (0,
|
|
2850
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
|
|
2544
2851
|
"AI Tools"
|
|
2545
2852
|
]
|
|
2546
2853
|
}
|
|
2547
2854
|
)
|
|
2548
2855
|
] }),
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2550
|
-
/* @__PURE__ */ (0,
|
|
2856
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2857
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2551
2858
|
"button",
|
|
2552
2859
|
{
|
|
2553
2860
|
type: "button",
|
|
@@ -2558,7 +2865,7 @@ var ImageEditor = ({
|
|
|
2558
2865
|
children: "\u21A9"
|
|
2559
2866
|
}
|
|
2560
2867
|
),
|
|
2561
|
-
/* @__PURE__ */ (0,
|
|
2868
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2562
2869
|
"button",
|
|
2563
2870
|
{
|
|
2564
2871
|
type: "button",
|
|
@@ -2569,7 +2876,7 @@ var ImageEditor = ({
|
|
|
2569
2876
|
children: "\u21AA"
|
|
2570
2877
|
}
|
|
2571
2878
|
),
|
|
2572
|
-
/* @__PURE__ */ (0,
|
|
2879
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2573
2880
|
"button",
|
|
2574
2881
|
{
|
|
2575
2882
|
type: "button",
|
|
@@ -2578,8 +2885,8 @@ var ImageEditor = ({
|
|
|
2578
2885
|
children: "Reset"
|
|
2579
2886
|
}
|
|
2580
2887
|
),
|
|
2581
|
-
/* @__PURE__ */ (0,
|
|
2582
|
-
/* @__PURE__ */ (0,
|
|
2888
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
2889
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2583
2890
|
"button",
|
|
2584
2891
|
{
|
|
2585
2892
|
type: "button",
|
|
@@ -2589,11 +2896,11 @@ var ImageEditor = ({
|
|
|
2589
2896
|
children: "-"
|
|
2590
2897
|
}
|
|
2591
2898
|
),
|
|
2592
|
-
/* @__PURE__ */ (0,
|
|
2899
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
2593
2900
|
Math.round(state.zoom * 100),
|
|
2594
2901
|
"%"
|
|
2595
2902
|
] }),
|
|
2596
|
-
/* @__PURE__ */ (0,
|
|
2903
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2597
2904
|
"button",
|
|
2598
2905
|
{
|
|
2599
2906
|
type: "button",
|
|
@@ -2603,8 +2910,8 @@ var ImageEditor = ({
|
|
|
2603
2910
|
children: "+"
|
|
2604
2911
|
}
|
|
2605
2912
|
),
|
|
2606
|
-
/* @__PURE__ */ (0,
|
|
2607
|
-
/* @__PURE__ */ (0,
|
|
2913
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
2914
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2608
2915
|
"button",
|
|
2609
2916
|
{
|
|
2610
2917
|
type: "button",
|
|
@@ -2615,7 +2922,7 @@ var ImageEditor = ({
|
|
|
2615
2922
|
children: "Hold Compare"
|
|
2616
2923
|
}
|
|
2617
2924
|
),
|
|
2618
|
-
/* @__PURE__ */ (0,
|
|
2925
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2619
2926
|
"button",
|
|
2620
2927
|
{
|
|
2621
2928
|
type: "button",
|
|
@@ -2626,38 +2933,59 @@ var ImageEditor = ({
|
|
|
2626
2933
|
)
|
|
2627
2934
|
] })
|
|
2628
2935
|
] }),
|
|
2629
|
-
transformTool.active && /* @__PURE__ */ (0,
|
|
2630
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */ (0,
|
|
2631
|
-
/* @__PURE__ */ (0,
|
|
2632
|
-
/* @__PURE__ */ (0,
|
|
2936
|
+
transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
|
|
2937
|
+
!transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { role: "alert", className: "border-b border-rose-900 bg-rose-950/80 px-4 py-1.5 text-xs text-rose-200", children: transformTool.error }),
|
|
2938
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
2939
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2633
2940
|
"div",
|
|
2634
2941
|
{
|
|
2635
2942
|
ref: containerRef,
|
|
2636
2943
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
2637
|
-
children:
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2944
|
+
children: [
|
|
2945
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2946
|
+
"canvas",
|
|
2947
|
+
{
|
|
2948
|
+
ref: canvasRef,
|
|
2949
|
+
onMouseDown: handleMouseDown,
|
|
2950
|
+
onMouseMove: handleMouseMove,
|
|
2951
|
+
onMouseUp: handleMouseUp,
|
|
2952
|
+
onMouseLeave: handleMouseUp,
|
|
2953
|
+
onPointerDown: handlePaintPointerDown,
|
|
2954
|
+
onPointerMove: handlePaintPointerMove,
|
|
2955
|
+
onPointerUp: handlePaintPointerUp,
|
|
2956
|
+
onPointerCancel: () => paintGestureRef.current?.cancel(),
|
|
2957
|
+
"data-testid": "image-editor-canvas",
|
|
2958
|
+
style: transformTool.active ? { cursor: transformCursor } : void 0,
|
|
2959
|
+
className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : activeTab === "annotate" && state.activeTool === "type" ? "cursor-text" : activeTab === "annotate" && state.activeTool === "shape" ? "cursor-crosshair" : ""}`
|
|
2960
|
+
}
|
|
2961
|
+
),
|
|
2962
|
+
typeSession && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2963
|
+
"textarea",
|
|
2964
|
+
{
|
|
2965
|
+
ref: typeInputRef,
|
|
2966
|
+
"aria-label": "Edit text",
|
|
2967
|
+
"data-testid": "type-input",
|
|
2968
|
+
autoCapitalize: "off",
|
|
2969
|
+
autoCorrect: "off",
|
|
2970
|
+
spellCheck: false,
|
|
2971
|
+
onKeyDown: handleTypeKeyDown,
|
|
2972
|
+
onInput: handleTypeInput,
|
|
2973
|
+
onCompositionEnd: (e) => {
|
|
2974
|
+
const session = typeToolRef.current?.session;
|
|
2975
|
+
if (session && e.data) session.insert(e.data);
|
|
2976
|
+
e.currentTarget.value = "";
|
|
2977
|
+
},
|
|
2978
|
+
className: "absolute left-0 top-0 h-px w-px opacity-0"
|
|
2979
|
+
}
|
|
2980
|
+
)
|
|
2981
|
+
]
|
|
2654
2982
|
}
|
|
2655
2983
|
),
|
|
2656
|
-
/* @__PURE__ */ (0,
|
|
2657
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
2658
|
-
/* @__PURE__ */ (0,
|
|
2659
|
-
/* @__PURE__ */ (0,
|
|
2660
|
-
/* @__PURE__ */ (0,
|
|
2984
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "w-full md:w-80 bg-slate-900/90 border-t md:border-t-0 md:border-l border-slate-800 p-4 overflow-y-auto h-auto md:h-full md:max-h-[560px]", children: [
|
|
2985
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
2986
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
2987
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
2988
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2661
2989
|
"button",
|
|
2662
2990
|
{
|
|
2663
2991
|
type: "button",
|
|
@@ -2669,7 +2997,7 @@ var ImageEditor = ({
|
|
|
2669
2997
|
children: "Freeform"
|
|
2670
2998
|
}
|
|
2671
2999
|
),
|
|
2672
|
-
/* @__PURE__ */ (0,
|
|
3000
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2673
3001
|
"button",
|
|
2674
3002
|
{
|
|
2675
3003
|
type: "button",
|
|
@@ -2681,7 +3009,7 @@ var ImageEditor = ({
|
|
|
2681
3009
|
children: "1:1 Square"
|
|
2682
3010
|
}
|
|
2683
3011
|
),
|
|
2684
|
-
/* @__PURE__ */ (0,
|
|
3012
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2685
3013
|
"button",
|
|
2686
3014
|
{
|
|
2687
3015
|
type: "button",
|
|
@@ -2693,7 +3021,7 @@ var ImageEditor = ({
|
|
|
2693
3021
|
children: "4:3 Standard"
|
|
2694
3022
|
}
|
|
2695
3023
|
),
|
|
2696
|
-
/* @__PURE__ */ (0,
|
|
3024
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2697
3025
|
"button",
|
|
2698
3026
|
{
|
|
2699
3027
|
type: "button",
|
|
@@ -2705,7 +3033,7 @@ var ImageEditor = ({
|
|
|
2705
3033
|
children: "16:9 Wide"
|
|
2706
3034
|
}
|
|
2707
3035
|
),
|
|
2708
|
-
/* @__PURE__ */ (0,
|
|
3036
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2709
3037
|
"button",
|
|
2710
3038
|
{
|
|
2711
3039
|
type: "button",
|
|
@@ -2717,7 +3045,7 @@ var ImageEditor = ({
|
|
|
2717
3045
|
children: "3:2 Photo"
|
|
2718
3046
|
}
|
|
2719
3047
|
),
|
|
2720
|
-
/* @__PURE__ */ (0,
|
|
3048
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2721
3049
|
"button",
|
|
2722
3050
|
{
|
|
2723
3051
|
type: "button",
|
|
@@ -2730,10 +3058,10 @@ var ImageEditor = ({
|
|
|
2730
3058
|
}
|
|
2731
3059
|
)
|
|
2732
3060
|
] }),
|
|
2733
|
-
/* @__PURE__ */ (0,
|
|
2734
|
-
/* @__PURE__ */ (0,
|
|
2735
|
-
/* @__PURE__ */ (0,
|
|
2736
|
-
/* @__PURE__ */ (0,
|
|
3061
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3062
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
3063
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
3064
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2737
3065
|
"button",
|
|
2738
3066
|
{
|
|
2739
3067
|
type: "button",
|
|
@@ -2742,7 +3070,7 @@ var ImageEditor = ({
|
|
|
2742
3070
|
children: "Rotate -90\xB0"
|
|
2743
3071
|
}
|
|
2744
3072
|
),
|
|
2745
|
-
/* @__PURE__ */ (0,
|
|
3073
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2746
3074
|
"button",
|
|
2747
3075
|
{
|
|
2748
3076
|
type: "button",
|
|
@@ -2751,7 +3079,7 @@ var ImageEditor = ({
|
|
|
2751
3079
|
children: "Rotate +90\xB0"
|
|
2752
3080
|
}
|
|
2753
3081
|
),
|
|
2754
|
-
/* @__PURE__ */ (0,
|
|
3082
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2755
3083
|
"button",
|
|
2756
3084
|
{
|
|
2757
3085
|
type: "button",
|
|
@@ -2760,7 +3088,7 @@ var ImageEditor = ({
|
|
|
2760
3088
|
children: "Flip Horizontal"
|
|
2761
3089
|
}
|
|
2762
3090
|
),
|
|
2763
|
-
/* @__PURE__ */ (0,
|
|
3091
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2764
3092
|
"button",
|
|
2765
3093
|
{
|
|
2766
3094
|
type: "button",
|
|
@@ -2771,10 +3099,10 @@ var ImageEditor = ({
|
|
|
2771
3099
|
)
|
|
2772
3100
|
] })
|
|
2773
3101
|
] }),
|
|
2774
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
2775
|
-
/* @__PURE__ */ (0,
|
|
2776
|
-
/* @__PURE__ */ (0,
|
|
2777
|
-
/* @__PURE__ */ (0,
|
|
3102
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3103
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3104
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
3105
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2778
3106
|
"button",
|
|
2779
3107
|
{
|
|
2780
3108
|
type: "button",
|
|
@@ -2784,25 +3112,25 @@ var ImageEditor = ({
|
|
|
2784
3112
|
}
|
|
2785
3113
|
)
|
|
2786
3114
|
] }),
|
|
2787
|
-
/* @__PURE__ */ (0,
|
|
2788
|
-
|
|
2789
|
-
/* @__PURE__ */ (0,
|
|
3115
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Histogram, { histogram: editor.histogram }),
|
|
3116
|
+
import_image_editor14.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react13.default.Fragment, { children: [
|
|
3117
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2790
3118
|
ControlSlider,
|
|
2791
3119
|
{
|
|
2792
3120
|
spec,
|
|
2793
|
-
value: (0,
|
|
3121
|
+
value: (0, import_image_editor14.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
2794
3122
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
2795
3123
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
2796
3124
|
}
|
|
2797
3125
|
),
|
|
2798
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
3126
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2799
3127
|
"div",
|
|
2800
3128
|
{
|
|
2801
3129
|
className: "flex items-center justify-between gap-2 rounded border border-amber-500/30 bg-amber-500/10 px-2 py-1.5 text-[10px] text-amber-200",
|
|
2802
3130
|
"data-testid": "image-editor-process-notice",
|
|
2803
3131
|
children: [
|
|
2804
|
-
/* @__PURE__ */ (0,
|
|
2805
|
-
/* @__PURE__ */ (0,
|
|
3132
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
3133
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2806
3134
|
"button",
|
|
2807
3135
|
{
|
|
2808
3136
|
type: "button",
|
|
@@ -2815,7 +3143,7 @@ var ImageEditor = ({
|
|
|
2815
3143
|
}
|
|
2816
3144
|
)
|
|
2817
3145
|
] }, spec.id)),
|
|
2818
|
-
/* @__PURE__ */ (0,
|
|
3146
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2819
3147
|
AdjustmentLayersPanel,
|
|
2820
3148
|
{
|
|
2821
3149
|
controller,
|
|
@@ -2824,9 +3152,9 @@ var ImageEditor = ({
|
|
|
2824
3152
|
}
|
|
2825
3153
|
) })
|
|
2826
3154
|
] }),
|
|
2827
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
2828
|
-
/* @__PURE__ */ (0,
|
|
2829
|
-
/* @__PURE__ */ (0,
|
|
3155
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3156
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
3157
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2830
3158
|
"button",
|
|
2831
3159
|
{
|
|
2832
3160
|
type: "button",
|
|
@@ -2837,12 +3165,12 @@ var ImageEditor = ({
|
|
|
2837
3165
|
children: "Free Transform"
|
|
2838
3166
|
}
|
|
2839
3167
|
),
|
|
2840
|
-
/* @__PURE__ */ (0,
|
|
3168
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LayersPanel, { controller })
|
|
2841
3169
|
] }),
|
|
2842
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
2843
|
-
/* @__PURE__ */ (0,
|
|
2844
|
-
/* @__PURE__ */ (0,
|
|
2845
|
-
/* @__PURE__ */ (0,
|
|
3170
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3171
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
3172
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(BrushOptionsBar, { controller }),
|
|
3173
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2846
3174
|
"button",
|
|
2847
3175
|
{
|
|
2848
3176
|
type: "button",
|
|
@@ -2853,12 +3181,29 @@ var ImageEditor = ({
|
|
|
2853
3181
|
children: "Free Transform"
|
|
2854
3182
|
}
|
|
2855
3183
|
),
|
|
2856
|
-
paintError && /* @__PURE__ */ (0,
|
|
2857
|
-
/* @__PURE__ */ (0,
|
|
3184
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
3185
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LayersPanel, { controller }) })
|
|
2858
3186
|
] }),
|
|
2859
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
2860
|
-
/* @__PURE__ */ (0,
|
|
2861
|
-
/* @__PURE__ */ (0,
|
|
3187
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3188
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
|
|
3189
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3190
|
+
"button",
|
|
3191
|
+
{
|
|
3192
|
+
type: "button",
|
|
3193
|
+
"aria-pressed": state.activeTool === t,
|
|
3194
|
+
onClick: () => editor.setTool(t),
|
|
3195
|
+
className: `py-1.5 px-2 rounded-lg font-medium border transition-colors ${state.activeTool === t ? "bg-indigo-600 border-indigo-500 text-white" : "bg-slate-800 border-slate-700 text-slate-300 hover:bg-slate-700"}`,
|
|
3196
|
+
children: t === "shape" ? "Shape" : "Type"
|
|
3197
|
+
},
|
|
3198
|
+
t
|
|
3199
|
+
)) }),
|
|
3200
|
+
state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
|
|
3201
|
+
state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
|
|
3202
|
+
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: finishTyping, className: "self-start rounded bg-slate-800 px-2 py-1 text-[11px] text-slate-200 hover:bg-slate-700", children: "Done editing text" }),
|
|
3203
|
+
shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
|
|
3204
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3205
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
3206
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2862
3207
|
"button",
|
|
2863
3208
|
{
|
|
2864
3209
|
type: "button",
|
|
@@ -2868,9 +3213,9 @@ var ImageEditor = ({
|
|
|
2868
3213
|
},
|
|
2869
3214
|
t
|
|
2870
3215
|
)) }),
|
|
2871
|
-
/* @__PURE__ */ (0,
|
|
2872
|
-
/* @__PURE__ */ (0,
|
|
2873
|
-
/* @__PURE__ */ (0,
|
|
3216
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
3217
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
3218
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2874
3219
|
"input",
|
|
2875
3220
|
{
|
|
2876
3221
|
type: "color",
|
|
@@ -2879,15 +3224,15 @@ var ImageEditor = ({
|
|
|
2879
3224
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
2880
3225
|
}
|
|
2881
3226
|
),
|
|
2882
|
-
/* @__PURE__ */ (0,
|
|
2883
|
-
/* @__PURE__ */ (0,
|
|
2884
|
-
/* @__PURE__ */ (0,
|
|
2885
|
-
/* @__PURE__ */ (0,
|
|
3227
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
3228
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
3229
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Width:" }),
|
|
3230
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "font-mono", children: [
|
|
2886
3231
|
strokeWidth,
|
|
2887
3232
|
"px"
|
|
2888
3233
|
] })
|
|
2889
3234
|
] }),
|
|
2890
|
-
/* @__PURE__ */ (0,
|
|
3235
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2891
3236
|
"input",
|
|
2892
3237
|
{
|
|
2893
3238
|
type: "range",
|
|
@@ -2900,10 +3245,10 @@ var ImageEditor = ({
|
|
|
2900
3245
|
)
|
|
2901
3246
|
] })
|
|
2902
3247
|
] }),
|
|
2903
|
-
/* @__PURE__ */ (0,
|
|
2904
|
-
/* @__PURE__ */ (0,
|
|
2905
|
-
/* @__PURE__ */ (0,
|
|
2906
|
-
/* @__PURE__ */ (0,
|
|
3248
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3249
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
3250
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex gap-2", children: [
|
|
3251
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2907
3252
|
"input",
|
|
2908
3253
|
{
|
|
2909
3254
|
type: "text",
|
|
@@ -2914,7 +3259,7 @@ var ImageEditor = ({
|
|
|
2914
3259
|
className: "flex-1 bg-slate-950 border border-slate-700 rounded-lg px-2.5 py-1.5 text-xs text-slate-100 placeholder-slate-500 focus:outline-none focus:border-indigo-500"
|
|
2915
3260
|
}
|
|
2916
3261
|
),
|
|
2917
|
-
/* @__PURE__ */ (0,
|
|
3262
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2918
3263
|
"button",
|
|
2919
3264
|
{
|
|
2920
3265
|
type: "button",
|
|
@@ -2924,14 +3269,14 @@ var ImageEditor = ({
|
|
|
2924
3269
|
}
|
|
2925
3270
|
)
|
|
2926
3271
|
] }),
|
|
2927
|
-
/* @__PURE__ */ (0,
|
|
2928
|
-
/* @__PURE__ */ (0,
|
|
2929
|
-
/* @__PURE__ */ (0,
|
|
3272
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
3273
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Font Size:" }),
|
|
3274
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "font-mono", children: [
|
|
2930
3275
|
fontSize,
|
|
2931
3276
|
"px"
|
|
2932
3277
|
] })
|
|
2933
3278
|
] }),
|
|
2934
|
-
/* @__PURE__ */ (0,
|
|
3279
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2935
3280
|
"input",
|
|
2936
3281
|
{
|
|
2937
3282
|
type: "range",
|
|
@@ -2942,14 +3287,14 @@ var ImageEditor = ({
|
|
|
2942
3287
|
className: "w-full accent-indigo-500"
|
|
2943
3288
|
}
|
|
2944
3289
|
),
|
|
2945
|
-
/* @__PURE__ */ (0,
|
|
2946
|
-
/* @__PURE__ */ (0,
|
|
2947
|
-
/* @__PURE__ */ (0,
|
|
3290
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3291
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3292
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "text-slate-400", children: [
|
|
2948
3293
|
"Layers (",
|
|
2949
3294
|
state.annotations.length,
|
|
2950
3295
|
")"
|
|
2951
3296
|
] }),
|
|
2952
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
3297
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2953
3298
|
"button",
|
|
2954
3299
|
{
|
|
2955
3300
|
type: "button",
|
|
@@ -2958,7 +3303,7 @@ var ImageEditor = ({
|
|
|
2958
3303
|
children: "Delete Selected"
|
|
2959
3304
|
}
|
|
2960
3305
|
),
|
|
2961
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
3306
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2962
3307
|
"button",
|
|
2963
3308
|
{
|
|
2964
3309
|
type: "button",
|
|
@@ -2969,10 +3314,10 @@ var ImageEditor = ({
|
|
|
2969
3314
|
)
|
|
2970
3315
|
] })
|
|
2971
3316
|
] }),
|
|
2972
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
2973
|
-
/* @__PURE__ */ (0,
|
|
2974
|
-
/* @__PURE__ */ (0,
|
|
2975
|
-
/* @__PURE__ */ (0,
|
|
3317
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3318
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3319
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
3320
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2976
3321
|
"button",
|
|
2977
3322
|
{
|
|
2978
3323
|
type: "button",
|
|
@@ -2982,8 +3327,8 @@ var ImageEditor = ({
|
|
|
2982
3327
|
}
|
|
2983
3328
|
)
|
|
2984
3329
|
] }),
|
|
2985
|
-
/* @__PURE__ */ (0,
|
|
2986
|
-
/* @__PURE__ */ (0,
|
|
3330
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
3331
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2987
3332
|
"input",
|
|
2988
3333
|
{
|
|
2989
3334
|
type: "checkbox",
|
|
@@ -2992,12 +3337,12 @@ var ImageEditor = ({
|
|
|
2992
3337
|
className: "rounded accent-indigo-500"
|
|
2993
3338
|
}
|
|
2994
3339
|
),
|
|
2995
|
-
/* @__PURE__ */ (0,
|
|
3340
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
2996
3341
|
] }),
|
|
2997
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
2998
|
-
/* @__PURE__ */ (0,
|
|
2999
|
-
/* @__PURE__ */ (0,
|
|
3000
|
-
/* @__PURE__ */ (0,
|
|
3342
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3343
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
|
|
3344
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
3345
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3001
3346
|
"input",
|
|
3002
3347
|
{
|
|
3003
3348
|
type: "text",
|
|
@@ -3008,8 +3353,8 @@ var ImageEditor = ({
|
|
|
3008
3353
|
}
|
|
3009
3354
|
)
|
|
3010
3355
|
] }),
|
|
3011
|
-
/* @__PURE__ */ (0,
|
|
3012
|
-
/* @__PURE__ */ (0,
|
|
3356
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex gap-2", children: [
|
|
3357
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3013
3358
|
"button",
|
|
3014
3359
|
{
|
|
3015
3360
|
type: "button",
|
|
@@ -3018,7 +3363,7 @@ var ImageEditor = ({
|
|
|
3018
3363
|
children: "Threshold Mode"
|
|
3019
3364
|
}
|
|
3020
3365
|
),
|
|
3021
|
-
/* @__PURE__ */ (0,
|
|
3366
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3022
3367
|
"button",
|
|
3023
3368
|
{
|
|
3024
3369
|
type: "button",
|
|
@@ -3028,12 +3373,12 @@ var ImageEditor = ({
|
|
|
3028
3373
|
}
|
|
3029
3374
|
)
|
|
3030
3375
|
] }),
|
|
3031
|
-
/* @__PURE__ */ (0,
|
|
3032
|
-
/* @__PURE__ */ (0,
|
|
3033
|
-
/* @__PURE__ */ (0,
|
|
3034
|
-
/* @__PURE__ */ (0,
|
|
3376
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
|
|
3377
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3378
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
3379
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
3035
3380
|
] }),
|
|
3036
|
-
/* @__PURE__ */ (0,
|
|
3381
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3037
3382
|
"input",
|
|
3038
3383
|
{
|
|
3039
3384
|
type: "range",
|
|
@@ -3047,12 +3392,12 @@ var ImageEditor = ({
|
|
|
3047
3392
|
}
|
|
3048
3393
|
)
|
|
3049
3394
|
] }),
|
|
3050
|
-
/* @__PURE__ */ (0,
|
|
3051
|
-
/* @__PURE__ */ (0,
|
|
3052
|
-
/* @__PURE__ */ (0,
|
|
3053
|
-
/* @__PURE__ */ (0,
|
|
3395
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
|
|
3396
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3397
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
3398
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
3054
3399
|
] }),
|
|
3055
|
-
/* @__PURE__ */ (0,
|
|
3400
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3056
3401
|
"input",
|
|
3057
3402
|
{
|
|
3058
3403
|
type: "range",
|
|
@@ -3066,12 +3411,12 @@ var ImageEditor = ({
|
|
|
3066
3411
|
}
|
|
3067
3412
|
)
|
|
3068
3413
|
] }),
|
|
3069
|
-
/* @__PURE__ */ (0,
|
|
3070
|
-
/* @__PURE__ */ (0,
|
|
3071
|
-
/* @__PURE__ */ (0,
|
|
3072
|
-
/* @__PURE__ */ (0,
|
|
3414
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
|
|
3415
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3416
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Softness:" }),
|
|
3417
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
3073
3418
|
] }),
|
|
3074
|
-
/* @__PURE__ */ (0,
|
|
3419
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3075
3420
|
"input",
|
|
3076
3421
|
{
|
|
3077
3422
|
type: "range",
|
|
@@ -3083,8 +3428,8 @@ var ImageEditor = ({
|
|
|
3083
3428
|
}
|
|
3084
3429
|
)
|
|
3085
3430
|
] }),
|
|
3086
|
-
/* @__PURE__ */ (0,
|
|
3087
|
-
/* @__PURE__ */ (0,
|
|
3431
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
3432
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3088
3433
|
"input",
|
|
3089
3434
|
{
|
|
3090
3435
|
type: "checkbox",
|
|
@@ -3093,12 +3438,12 @@ var ImageEditor = ({
|
|
|
3093
3438
|
className: "rounded accent-indigo-500"
|
|
3094
3439
|
}
|
|
3095
3440
|
),
|
|
3096
|
-
/* @__PURE__ */ (0,
|
|
3441
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Invert Mask" })
|
|
3097
3442
|
] })
|
|
3098
3443
|
] })
|
|
3099
3444
|
] }),
|
|
3100
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
3101
|
-
/* @__PURE__ */ (0,
|
|
3445
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3446
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3102
3447
|
SelectionOptionsBar,
|
|
3103
3448
|
{
|
|
3104
3449
|
controller,
|
|
@@ -3108,9 +3453,9 @@ var ImageEditor = ({
|
|
|
3108
3453
|
quickMask: Boolean(state.quickMask)
|
|
3109
3454
|
}
|
|
3110
3455
|
),
|
|
3111
|
-
selectionError && /* @__PURE__ */ (0,
|
|
3112
|
-
/* @__PURE__ */ (0,
|
|
3113
|
-
/* @__PURE__ */ (0,
|
|
3456
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
3457
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex gap-1", children: [
|
|
3458
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3114
3459
|
"button",
|
|
3115
3460
|
{
|
|
3116
3461
|
type: "button",
|
|
@@ -3121,7 +3466,7 @@ var ImageEditor = ({
|
|
|
3121
3466
|
children: "Transform Selection"
|
|
3122
3467
|
}
|
|
3123
3468
|
),
|
|
3124
|
-
/* @__PURE__ */ (0,
|
|
3469
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3125
3470
|
"button",
|
|
3126
3471
|
{
|
|
3127
3472
|
type: "button",
|
|
@@ -3133,12 +3478,12 @@ var ImageEditor = ({
|
|
|
3133
3478
|
}
|
|
3134
3479
|
)
|
|
3135
3480
|
] }),
|
|
3136
|
-
/* @__PURE__ */ (0,
|
|
3481
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
3137
3482
|
] }),
|
|
3138
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
3139
|
-
/* @__PURE__ */ (0,
|
|
3140
|
-
/* @__PURE__ */ (0,
|
|
3141
|
-
/* @__PURE__ */ (0,
|
|
3483
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3484
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
3485
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Results go to" }),
|
|
3486
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3142
3487
|
"select",
|
|
3143
3488
|
{
|
|
3144
3489
|
"aria-label": "AI result target",
|
|
@@ -3146,54 +3491,54 @@ var ImageEditor = ({
|
|
|
3146
3491
|
onChange: (e) => setAiTarget(e.target.value),
|
|
3147
3492
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
3148
3493
|
children: [
|
|
3149
|
-
/* @__PURE__ */ (0,
|
|
3150
|
-
/* @__PURE__ */ (0,
|
|
3151
|
-
/* @__PURE__ */ (0,
|
|
3494
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
3495
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
3496
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "replace", children: "Replace image" })
|
|
3152
3497
|
]
|
|
3153
3498
|
}
|
|
3154
3499
|
)
|
|
3155
3500
|
] }),
|
|
3156
|
-
/* @__PURE__ */ (0,
|
|
3157
|
-
/* @__PURE__ */ (0,
|
|
3158
|
-
/* @__PURE__ */ (0,
|
|
3159
|
-
/* @__PURE__ */ (0,
|
|
3501
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3502
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3503
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3504
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" }) }),
|
|
3160
3505
|
"Background Removal"
|
|
3161
3506
|
] }),
|
|
3162
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
3507
|
+
isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-indigo-900/60 text-indigo-300 animate-pulse", children: "Removing..." })
|
|
3163
3508
|
] }),
|
|
3164
|
-
/* @__PURE__ */ (0,
|
|
3165
|
-
/* @__PURE__ */ (0,
|
|
3509
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
3510
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3166
3511
|
"button",
|
|
3167
3512
|
{
|
|
3168
3513
|
type: "button",
|
|
3169
3514
|
onClick: handleRemoveBackground,
|
|
3170
3515
|
disabled: isRemovingBg || isInpainting,
|
|
3171
3516
|
className: "mt-1 px-3 py-2 rounded-lg bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2",
|
|
3172
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
3173
|
-
/* @__PURE__ */ (0,
|
|
3517
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3518
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
3174
3519
|
"Removing Background..."
|
|
3175
|
-
] }) : /* @__PURE__ */ (0,
|
|
3176
|
-
/* @__PURE__ */ (0,
|
|
3520
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3521
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
|
|
3177
3522
|
"Remove Background"
|
|
3178
3523
|
] })
|
|
3179
3524
|
}
|
|
3180
3525
|
)
|
|
3181
3526
|
] }),
|
|
3182
|
-
/* @__PURE__ */ (0,
|
|
3183
|
-
/* @__PURE__ */ (0,
|
|
3184
|
-
/* @__PURE__ */ (0,
|
|
3185
|
-
/* @__PURE__ */ (0,
|
|
3186
|
-
/* @__PURE__ */ (0,
|
|
3187
|
-
/* @__PURE__ */ (0,
|
|
3527
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3528
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3529
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3530
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
3531
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "m21.64 3.64-1.28-1.28a1.2 1.2 0 0 0-1.7 0l-9.72 9.72-1.94 4.86 4.86-1.94 9.72-9.72a1.2 1.2 0 0 0 .06-1.64z" }),
|
|
3532
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "m14 7 3 3" })
|
|
3188
3533
|
] }),
|
|
3189
3534
|
"Generative Inpainting"
|
|
3190
3535
|
] }),
|
|
3191
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
3536
|
+
isInpainting && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-900/60 text-purple-300 animate-pulse", children: "Inpainting..." })
|
|
3192
3537
|
] }),
|
|
3193
|
-
/* @__PURE__ */ (0,
|
|
3194
|
-
/* @__PURE__ */ (0,
|
|
3195
|
-
/* @__PURE__ */ (0,
|
|
3196
|
-
/* @__PURE__ */ (0,
|
|
3538
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
3539
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3540
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
3541
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3197
3542
|
"textarea",
|
|
3198
3543
|
{
|
|
3199
3544
|
id: "ai-inpaint-prompt-react",
|
|
@@ -3205,10 +3550,10 @@ var ImageEditor = ({
|
|
|
3205
3550
|
}
|
|
3206
3551
|
)
|
|
3207
3552
|
] }),
|
|
3208
|
-
/* @__PURE__ */ (0,
|
|
3209
|
-
/* @__PURE__ */ (0,
|
|
3210
|
-
/* @__PURE__ */ (0,
|
|
3211
|
-
/* @__PURE__ */ (0,
|
|
3553
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3554
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
3555
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
3556
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3212
3557
|
"button",
|
|
3213
3558
|
{
|
|
3214
3559
|
type: "button",
|
|
@@ -3221,7 +3566,7 @@ var ImageEditor = ({
|
|
|
3221
3566
|
]
|
|
3222
3567
|
}
|
|
3223
3568
|
),
|
|
3224
|
-
/* @__PURE__ */ (0,
|
|
3569
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3225
3570
|
"button",
|
|
3226
3571
|
{
|
|
3227
3572
|
type: "button",
|
|
@@ -3236,25 +3581,25 @@ var ImageEditor = ({
|
|
|
3236
3581
|
)
|
|
3237
3582
|
] })
|
|
3238
3583
|
] }),
|
|
3239
|
-
/* @__PURE__ */ (0,
|
|
3584
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3240
3585
|
"button",
|
|
3241
3586
|
{
|
|
3242
3587
|
type: "button",
|
|
3243
3588
|
onClick: handleInpaint,
|
|
3244
3589
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
3245
3590
|
className: "mt-1 px-3 py-2 rounded-lg bg-purple-600 hover:bg-purple-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2",
|
|
3246
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
3247
|
-
/* @__PURE__ */ (0,
|
|
3591
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3592
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
3248
3593
|
"Generating Inpaint..."
|
|
3249
|
-
] }) : /* @__PURE__ */ (0,
|
|
3250
|
-
/* @__PURE__ */ (0,
|
|
3594
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3595
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }),
|
|
3251
3596
|
"Apply Inpainting"
|
|
3252
3597
|
] })
|
|
3253
3598
|
}
|
|
3254
3599
|
)
|
|
3255
3600
|
] }),
|
|
3256
|
-
aiError && /* @__PURE__ */ (0,
|
|
3257
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
3601
|
+
aiError && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
3602
|
+
aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
3258
3603
|
] })
|
|
3259
3604
|
] })
|
|
3260
3605
|
] })
|
|
@@ -3275,6 +3620,8 @@ var ImageEditor = ({
|
|
|
3275
3620
|
LayersPanel,
|
|
3276
3621
|
RefineEdgePanel,
|
|
3277
3622
|
SelectionOptionsBar,
|
|
3623
|
+
ShapeOptionsBar,
|
|
3624
|
+
TypeOptionsBar,
|
|
3278
3625
|
useImageEditor,
|
|
3279
3626
|
useImageHistogram
|
|
3280
3627
|
});
|