@pixerate/editor-react 0.64.0 → 0.66.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-M4WLX3IR.js → chunk-LCTQWNTL.js} +468 -194
- package/dist/chunk-LCTQWNTL.js.map +1 -0
- package/dist/image-editor/index.cjs +505 -232
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +15 -2
- package/dist/image-editor/index.d.ts +15 -2
- package/dist/image-editor/index.js +3 -1
- package/dist/index.cjs +934 -661
- 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 +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-M4WLX3IR.js.map +0 -1
|
@@ -34,6 +34,7 @@ __export(image_editor_exports, {
|
|
|
34
34
|
BrushOptionsBar: () => BrushOptionsBar,
|
|
35
35
|
ControlSlider: () => ControlSlider,
|
|
36
36
|
CurvesEditor: () => CurvesEditor,
|
|
37
|
+
FreeTransformOptionsBar: () => FreeTransformOptionsBar,
|
|
37
38
|
Histogram: () => Histogram,
|
|
38
39
|
ImageEditor: () => ImageEditor,
|
|
39
40
|
LayerEffectsPanel: () => LayerEffectsPanel,
|
|
@@ -204,8 +205,8 @@ function useImageEditor(options = {}) {
|
|
|
204
205
|
}
|
|
205
206
|
|
|
206
207
|
// src/image-editor/ImageEditor.tsx
|
|
207
|
-
var
|
|
208
|
-
var
|
|
208
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
209
|
+
var import_image_editor12 = require("@pixerate/editor/image-editor");
|
|
209
210
|
|
|
210
211
|
// src/image-editor/ControlSlider.tsx
|
|
211
212
|
var import_image_editor2 = require("@pixerate/editor/image-editor");
|
|
@@ -1124,6 +1125,22 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
1124
1125
|
children: (0, import_image_editor7.layerBadge)(layer)
|
|
1125
1126
|
}
|
|
1126
1127
|
),
|
|
1128
|
+
layer.mask && !layer.mask.source && layer.type === "pixel" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1129
|
+
"button",
|
|
1130
|
+
{
|
|
1131
|
+
type: "button",
|
|
1132
|
+
"aria-label": `${layer.mask.linked === false ? "Link" : "Unlink"} ${row.label} mask`,
|
|
1133
|
+
"aria-pressed": layer.mask.linked !== false,
|
|
1134
|
+
title: layer.mask.linked === false ? "Mask unlinked: it stays put when the layer moves or transforms. Click to link." : "Mask linked: it moves with the layer. Click to unlink.",
|
|
1135
|
+
"data-testid": "layer-mask-link",
|
|
1136
|
+
className: `shrink-0 text-[10px] leading-none ${layer.mask.linked === false ? "text-slate-600" : "text-slate-300"}`,
|
|
1137
|
+
onClick: (e) => {
|
|
1138
|
+
e.stopPropagation();
|
|
1139
|
+
attempt(() => controller.setLayerMaskProps(layer.id, { linked: layer.mask.linked === false }));
|
|
1140
|
+
},
|
|
1141
|
+
children: layer.mask.linked === false ? "\u26D3\uFE0E\u0338" : "\u26D3\uFE0E"
|
|
1142
|
+
}
|
|
1143
|
+
),
|
|
1127
1144
|
layer.mask && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1128
1145
|
Thumbnail,
|
|
1129
1146
|
{
|
|
@@ -1635,8 +1652,147 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1635
1652
|
] });
|
|
1636
1653
|
};
|
|
1637
1654
|
|
|
1638
|
-
// src/image-editor/
|
|
1655
|
+
// src/image-editor/FreeTransformOptionsBar.tsx
|
|
1656
|
+
var import_react10 = require("react");
|
|
1657
|
+
var import_image_editor11 = require("@pixerate/editor/image-editor");
|
|
1639
1658
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1659
|
+
var chip2 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
1660
|
+
var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
|
|
1661
|
+
var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
1662
|
+
const [, setTick] = (0, import_react10.useState)(0);
|
|
1663
|
+
(0, import_react10.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
|
|
1664
|
+
const bar = tool.bar();
|
|
1665
|
+
if (!tool.active || !bar) return null;
|
|
1666
|
+
const warp = tool.warpBar();
|
|
1667
|
+
const warpNumber = (key, raw) => {
|
|
1668
|
+
const v = Number(raw);
|
|
1669
|
+
if (raw.trim() !== "" && Number.isFinite(v) && v !== warp[key]) tool.setWarp({ [key]: Math.max(-100, Math.min(100, v)) });
|
|
1670
|
+
};
|
|
1671
|
+
const apply = (field, raw) => {
|
|
1672
|
+
const v = Number(raw);
|
|
1673
|
+
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
1674
|
+
};
|
|
1675
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "free-transform-options", role: "toolbar", "aria-label": "Free Transform options", children: [
|
|
1676
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor11.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", title: m.title, "aria-pressed": tool.mode === m.id, className: chip2(tool.mode === m.id), onClick: () => tool.setMode(m.id), children: m.label }, m.id)) }),
|
|
1677
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor11.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": `Reference point ${a}`, title: `Reference point: ${a}`, className: "h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500", onClick: () => tool.setReference(a) }, a)) }),
|
|
1678
|
+
tool.mode === "warp" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
|
|
1679
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1680
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Warp" }),
|
|
1681
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("select", { "aria-label": "Warp style", value: warp.style, onChange: (e) => tool.setWarp({ style: e.target.value }), className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5", children: import_image_editor11.WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: o.id, children: o.label }, o.id)) })
|
|
1682
|
+
] }),
|
|
1683
|
+
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1684
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
|
|
1685
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1686
|
+
"input",
|
|
1687
|
+
{
|
|
1688
|
+
type: "number",
|
|
1689
|
+
"aria-label": k === "bend" ? "Warp bend in percent" : `Warp ${k} distortion in percent`,
|
|
1690
|
+
defaultValue: warp[k],
|
|
1691
|
+
min: -100,
|
|
1692
|
+
max: 100,
|
|
1693
|
+
disabled: warp.style === "custom",
|
|
1694
|
+
className: "w-14 rounded border border-slate-700 bg-slate-900 px-1 py-0.5 text-right disabled:opacity-40",
|
|
1695
|
+
onBlur: (e) => warpNumber(k, e.currentTarget.value),
|
|
1696
|
+
onKeyDown: (e) => {
|
|
1697
|
+
if (e.key === "Enter") {
|
|
1698
|
+
e.preventDefault();
|
|
1699
|
+
e.stopPropagation();
|
|
1700
|
+
warpNumber(k, e.currentTarget.value);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
},
|
|
1704
|
+
`${k}:${warp[k]}`
|
|
1705
|
+
),
|
|
1706
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-500", children: "%" })
|
|
1707
|
+
] }, k)),
|
|
1708
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1709
|
+
"button",
|
|
1710
|
+
{
|
|
1711
|
+
type: "button",
|
|
1712
|
+
title: "Bend along the vertical axis",
|
|
1713
|
+
"aria-pressed": warp.orientation === "vertical",
|
|
1714
|
+
disabled: warp.style === "custom",
|
|
1715
|
+
className: chip2(warp.orientation === "vertical"),
|
|
1716
|
+
onClick: () => tool.setWarp({ orientation: warp.orientation === "vertical" ? "horizontal" : "vertical" }),
|
|
1717
|
+
children: "Vertical"
|
|
1718
|
+
}
|
|
1719
|
+
),
|
|
1720
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1721
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Grid" }),
|
|
1722
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1723
|
+
"select",
|
|
1724
|
+
{
|
|
1725
|
+
"aria-label": "Warp grid",
|
|
1726
|
+
value: import_image_editor11.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
|
|
1727
|
+
onChange: (e) => {
|
|
1728
|
+
const g = import_image_editor11.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
|
|
1729
|
+
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
1730
|
+
},
|
|
1731
|
+
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1732
|
+
children: import_image_editor11.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: g.id, children: g.label }, g.id))
|
|
1733
|
+
}
|
|
1734
|
+
)
|
|
1735
|
+
] })
|
|
1736
|
+
] }),
|
|
1737
|
+
tool.mode !== "warp" && import_image_editor11.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
|
|
1738
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: f.label }),
|
|
1739
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1740
|
+
"input",
|
|
1741
|
+
{
|
|
1742
|
+
type: "number",
|
|
1743
|
+
"aria-label": f.title,
|
|
1744
|
+
defaultValue: round(bar[f.id], f.unit),
|
|
1745
|
+
disabled: !bar.affine,
|
|
1746
|
+
step: f.unit === "px" ? 1 : 0.1,
|
|
1747
|
+
className: "w-16 rounded border border-slate-700 bg-slate-900 px-1 py-0.5 text-right disabled:opacity-40",
|
|
1748
|
+
onBlur: (e) => apply(f.id, e.currentTarget.value),
|
|
1749
|
+
onKeyDown: (e) => {
|
|
1750
|
+
if (e.key === "Enter") {
|
|
1751
|
+
e.preventDefault();
|
|
1752
|
+
e.stopPropagation();
|
|
1753
|
+
apply(f.id, e.currentTarget.value);
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
},
|
|
1757
|
+
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
1758
|
+
),
|
|
1759
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-500", children: f.unit }),
|
|
1760
|
+
f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1761
|
+
"button",
|
|
1762
|
+
{
|
|
1763
|
+
type: "button",
|
|
1764
|
+
"aria-label": "Keep width and height proportional",
|
|
1765
|
+
"aria-pressed": tool.proportional,
|
|
1766
|
+
className: chip2(tool.proportional),
|
|
1767
|
+
onClick: () => {
|
|
1768
|
+
tool.proportional = !tool.proportional;
|
|
1769
|
+
setTick((n) => n + 1);
|
|
1770
|
+
},
|
|
1771
|
+
children: "\u26D3\uFE0E"
|
|
1772
|
+
}
|
|
1773
|
+
)
|
|
1774
|
+
] }, f.id)),
|
|
1775
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1776
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
|
|
1777
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1778
|
+
"select",
|
|
1779
|
+
{
|
|
1780
|
+
"aria-label": "Interpolation",
|
|
1781
|
+
value: tool.interpolation,
|
|
1782
|
+
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
1783
|
+
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1784
|
+
children: import_image_editor11.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
1785
|
+
}
|
|
1786
|
+
)
|
|
1787
|
+
] }),
|
|
1788
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", title: "Commit (Enter)", className: "px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500", onClick: () => tool.commit(), children: "Commit" }),
|
|
1789
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip2(false), onClick: () => tool.cancel(), children: "Cancel" }),
|
|
1790
|
+
tool.error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
|
|
1791
|
+
] });
|
|
1792
|
+
};
|
|
1793
|
+
|
|
1794
|
+
// src/image-editor/ImageEditor.tsx
|
|
1795
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1640
1796
|
var ImageEditor = ({
|
|
1641
1797
|
editor: externalEditor,
|
|
1642
1798
|
src,
|
|
@@ -1651,35 +1807,47 @@ var ImageEditor = ({
|
|
|
1651
1807
|
const internalEditor = useImageEditor({ image: src });
|
|
1652
1808
|
const editor = externalEditor || internalEditor;
|
|
1653
1809
|
const { state, controller } = editor;
|
|
1654
|
-
const legacyProcess = (0,
|
|
1655
|
-
const canvasRef = (0,
|
|
1656
|
-
const containerRef = (0,
|
|
1657
|
-
const [activeTab, setActiveTab] = (0,
|
|
1658
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
1659
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
1660
|
-
const selectionOptionsRef = (0,
|
|
1810
|
+
const legacyProcess = (0, import_image_editor12.normalizeProcessVersion)(state.adjustments.process) < import_image_editor12.LATEST_PROCESS_VERSION;
|
|
1811
|
+
const canvasRef = (0, import_react11.useRef)(null);
|
|
1812
|
+
const containerRef = (0, import_react11.useRef)(null);
|
|
1813
|
+
const [activeTab, setActiveTab] = (0, import_react11.useState)("crop");
|
|
1814
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react11.useState)(null);
|
|
1815
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react11.useState)(import_image_editor12.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
1816
|
+
const selectionOptionsRef = (0, import_react11.useRef)(selectionOptions);
|
|
1661
1817
|
selectionOptionsRef.current = selectionOptions;
|
|
1662
|
-
const selectionGestureRef = (0,
|
|
1818
|
+
const selectionGestureRef = (0, import_react11.useRef)(null);
|
|
1663
1819
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
1664
|
-
selectionGestureRef.current = new
|
|
1820
|
+
selectionGestureRef.current = new import_image_editor12.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
1665
1821
|
}
|
|
1666
|
-
const selectionDraftRef = (0,
|
|
1667
|
-
const [selectionError, setSelectionError] = (0,
|
|
1668
|
-
const paintGestureRef = (0,
|
|
1669
|
-
const paintControllerRef = (0,
|
|
1822
|
+
const selectionDraftRef = (0, import_react11.useRef)(null);
|
|
1823
|
+
const [selectionError, setSelectionError] = (0, import_react11.useState)(null);
|
|
1824
|
+
const paintGestureRef = (0, import_react11.useRef)(null);
|
|
1825
|
+
const paintControllerRef = (0, import_react11.useRef)(controller);
|
|
1670
1826
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
1671
|
-
paintGestureRef.current = new
|
|
1827
|
+
paintGestureRef.current = new import_image_editor12.PaintGesture(controller);
|
|
1672
1828
|
paintControllerRef.current = controller;
|
|
1673
1829
|
}
|
|
1674
|
-
const brushCursorRef = (0,
|
|
1675
|
-
const [paintError, setPaintError] = (0,
|
|
1676
|
-
const
|
|
1677
|
-
const
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1830
|
+
const brushCursorRef = (0, import_react11.useRef)(null);
|
|
1831
|
+
const [paintError, setPaintError] = (0, import_react11.useState)(null);
|
|
1832
|
+
const transformToolRef = (0, import_react11.useRef)(null);
|
|
1833
|
+
const transformControllerRef = (0, import_react11.useRef)(controller);
|
|
1834
|
+
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
1835
|
+
transformToolRef.current?.cancel();
|
|
1836
|
+
transformToolRef.current = new import_image_editor12.FreeTransformTool(controller, {
|
|
1837
|
+
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
1838
|
+
});
|
|
1839
|
+
transformControllerRef.current = controller;
|
|
1840
|
+
}
|
|
1841
|
+
const transformTool = transformToolRef.current;
|
|
1842
|
+
const [, setTransformTick] = (0, import_react11.useState)(0);
|
|
1843
|
+
const [transformCursor, setTransformCursor] = (0, import_react11.useState)("default");
|
|
1844
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react11.useState)("");
|
|
1845
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react11.useState)("annotations");
|
|
1846
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react11.useState)(false);
|
|
1847
|
+
const [isInpainting, setIsInpainting] = (0, import_react11.useState)(false);
|
|
1848
|
+
const [aiError, setAiError] = (0, import_react11.useState)(null);
|
|
1849
|
+
const [aiSuccess, setAiSuccess] = (0, import_react11.useState)(null);
|
|
1850
|
+
const [aiTarget, setAiTarget] = (0, import_react11.useState)("auto");
|
|
1683
1851
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
1684
1852
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
1685
1853
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -1742,18 +1910,18 @@ var ImageEditor = ({
|
|
|
1742
1910
|
setIsInpainting(false);
|
|
1743
1911
|
}
|
|
1744
1912
|
};
|
|
1745
|
-
const [activeColor, setActiveColor] = (0,
|
|
1746
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
1747
|
-
const [fontSize, setFontSize] = (0,
|
|
1748
|
-
const [textInput, setTextInput] = (0,
|
|
1749
|
-
const draftAnnotationRef = (0,
|
|
1750
|
-
const draftCropRef = (0,
|
|
1751
|
-
const cropDragInfoRef = (0,
|
|
1752
|
-
const annotationDragInfoRef = (0,
|
|
1753
|
-
const isDrawingRef = (0,
|
|
1754
|
-
const currentPathRef = (0,
|
|
1755
|
-
const dragStartPointRef = (0,
|
|
1756
|
-
const renderCanvas = (0,
|
|
1913
|
+
const [activeColor, setActiveColor] = (0, import_react11.useState)("#ef4444");
|
|
1914
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react11.useState)(3);
|
|
1915
|
+
const [fontSize, setFontSize] = (0, import_react11.useState)(24);
|
|
1916
|
+
const [textInput, setTextInput] = (0, import_react11.useState)("");
|
|
1917
|
+
const draftAnnotationRef = (0, import_react11.useRef)(null);
|
|
1918
|
+
const draftCropRef = (0, import_react11.useRef)(null);
|
|
1919
|
+
const cropDragInfoRef = (0, import_react11.useRef)(null);
|
|
1920
|
+
const annotationDragInfoRef = (0, import_react11.useRef)(null);
|
|
1921
|
+
const isDrawingRef = (0, import_react11.useRef)(false);
|
|
1922
|
+
const currentPathRef = (0, import_react11.useRef)([]);
|
|
1923
|
+
const dragStartPointRef = (0, import_react11.useRef)(null);
|
|
1924
|
+
const renderCanvas = (0, import_react11.useCallback)(
|
|
1757
1925
|
async (draftAnnotation, draftCrop) => {
|
|
1758
1926
|
const canvas = canvasRef.current;
|
|
1759
1927
|
const container = containerRef.current;
|
|
@@ -1769,12 +1937,64 @@ var ImageEditor = ({
|
|
|
1769
1937
|
draftAnnotation: draftAnnotation !== void 0 ? draftAnnotation : draftAnnotationRef.current,
|
|
1770
1938
|
draftCrop: draftCrop !== void 0 ? draftCrop : draftCropRef.current,
|
|
1771
1939
|
draftSelectionPath: selectionDraftRef.current,
|
|
1772
|
-
brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null
|
|
1940
|
+
brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" && !transformTool.active ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null,
|
|
1941
|
+
freeTransform: transformTool.overlay()
|
|
1773
1942
|
});
|
|
1774
1943
|
},
|
|
1775
|
-
[controller, activeTab]
|
|
1944
|
+
[controller, activeTab, transformTool]
|
|
1776
1945
|
);
|
|
1777
|
-
(0,
|
|
1946
|
+
(0, import_react11.useEffect)(() => transformTool.subscribe(() => {
|
|
1947
|
+
setTransformTick((n) => n + 1);
|
|
1948
|
+
void renderCanvas();
|
|
1949
|
+
}), [transformTool, renderCanvas]);
|
|
1950
|
+
const transformPoint = (e) => {
|
|
1951
|
+
const canvas = canvasRef.current;
|
|
1952
|
+
const rect = canvas.getBoundingClientRect();
|
|
1953
|
+
const sx = rect.width > 0 ? canvas.width / rect.width : 1;
|
|
1954
|
+
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
1955
|
+
const s = controller.getState();
|
|
1956
|
+
const cropping = activeTab === "crop";
|
|
1957
|
+
const projection = (0, import_image_editor12.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
1958
|
+
const pt = (0, import_image_editor12.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
|
|
1959
|
+
transformTool.setView(projection.scale);
|
|
1960
|
+
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
1961
|
+
};
|
|
1962
|
+
const handleTransformPointerDown = (e) => {
|
|
1963
|
+
if (!transformTool.active) return false;
|
|
1964
|
+
if (e.button !== 0) return true;
|
|
1965
|
+
e.preventDefault();
|
|
1966
|
+
try {
|
|
1967
|
+
e.currentTarget.setPointerCapture?.(e.pointerId);
|
|
1968
|
+
} catch {
|
|
1969
|
+
}
|
|
1970
|
+
const { pt, tolerance } = transformPoint(e);
|
|
1971
|
+
transformTool.down(pt, tolerance);
|
|
1972
|
+
return true;
|
|
1973
|
+
};
|
|
1974
|
+
const handleTransformPointerMove = (e) => {
|
|
1975
|
+
if (!transformTool.active) return false;
|
|
1976
|
+
const { pt, tolerance } = transformPoint(e);
|
|
1977
|
+
if (e.buttons & 1) transformTool.move(pt, e);
|
|
1978
|
+
else {
|
|
1979
|
+
const over = transformTool.hit(pt, tolerance);
|
|
1980
|
+
setTransformCursor(transformTool.cursor(over));
|
|
1981
|
+
}
|
|
1982
|
+
return true;
|
|
1983
|
+
};
|
|
1984
|
+
const handleTransformPointerUp = () => {
|
|
1985
|
+
if (!transformTool.active) return false;
|
|
1986
|
+
transformTool.up();
|
|
1987
|
+
return true;
|
|
1988
|
+
};
|
|
1989
|
+
(0, import_react11.useEffect)(() => {
|
|
1990
|
+
if (typeof window === "undefined") return;
|
|
1991
|
+
const onKey = (e) => {
|
|
1992
|
+
if (transformTool.key(e)) e.preventDefault();
|
|
1993
|
+
};
|
|
1994
|
+
window.addEventListener("keydown", onKey);
|
|
1995
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
1996
|
+
}, [transformTool]);
|
|
1997
|
+
(0, import_react11.useEffect)(() => {
|
|
1778
1998
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
1779
1999
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
1780
2000
|
const animId = raf(() => {
|
|
@@ -1782,12 +2002,12 @@ var ImageEditor = ({
|
|
|
1782
2002
|
});
|
|
1783
2003
|
return () => caf(animId);
|
|
1784
2004
|
}, [renderCanvas, state]);
|
|
1785
|
-
(0,
|
|
2005
|
+
(0, import_react11.useEffect)(() => {
|
|
1786
2006
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
1787
2007
|
editor.setTool("crop");
|
|
1788
2008
|
}
|
|
1789
2009
|
}, [activeTab, editor]);
|
|
1790
|
-
(0,
|
|
2010
|
+
(0, import_react11.useEffect)(() => {
|
|
1791
2011
|
const container = containerRef.current;
|
|
1792
2012
|
if (!container) return;
|
|
1793
2013
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -1823,11 +2043,12 @@ var ImageEditor = ({
|
|
|
1823
2043
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
1824
2044
|
const s = controller.getState();
|
|
1825
2045
|
return list.map((ev) => ({
|
|
1826
|
-
...(0,
|
|
1827
|
-
pressure: (0,
|
|
2046
|
+
...(0, import_image_editor12.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
2047
|
+
pressure: (0, import_image_editor12.pointerPressure)(ev)
|
|
1828
2048
|
}));
|
|
1829
2049
|
};
|
|
1830
2050
|
const handlePaintPointerDown = (e) => {
|
|
2051
|
+
if (handleTransformPointerDown(e)) return;
|
|
1831
2052
|
if (activeTab !== "paint" || e.button !== 0) return;
|
|
1832
2053
|
e.preventDefault();
|
|
1833
2054
|
try {
|
|
@@ -1838,6 +2059,7 @@ var ImageEditor = ({
|
|
|
1838
2059
|
setPaintError(paintGestureRef.current.down(first));
|
|
1839
2060
|
};
|
|
1840
2061
|
const handlePaintPointerMove = (e) => {
|
|
2062
|
+
if (handleTransformPointerMove(e)) return;
|
|
1841
2063
|
if (activeTab !== "paint") return;
|
|
1842
2064
|
const samples = paintSamples(e);
|
|
1843
2065
|
brushCursorRef.current = samples[samples.length - 1] ?? null;
|
|
@@ -1845,6 +2067,7 @@ var ImageEditor = ({
|
|
|
1845
2067
|
else void renderCanvas();
|
|
1846
2068
|
};
|
|
1847
2069
|
const handlePaintPointerUp = () => {
|
|
2070
|
+
if (handleTransformPointerUp()) return;
|
|
1848
2071
|
if (activeTab !== "paint") return;
|
|
1849
2072
|
const g = paintGestureRef.current;
|
|
1850
2073
|
if (g.active) {
|
|
@@ -1852,21 +2075,21 @@ var ImageEditor = ({
|
|
|
1852
2075
|
if (g.error) setPaintError(g.error);
|
|
1853
2076
|
}
|
|
1854
2077
|
};
|
|
1855
|
-
(0,
|
|
2078
|
+
(0, import_react11.useEffect)(() => {
|
|
1856
2079
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
1857
2080
|
const onKey = (e) => {
|
|
1858
|
-
if ((0,
|
|
2081
|
+
if ((0, import_image_editor12.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
1859
2082
|
};
|
|
1860
2083
|
window.addEventListener("keydown", onKey);
|
|
1861
2084
|
return () => window.removeEventListener("keydown", onKey);
|
|
1862
2085
|
}, [activeTab, controller]);
|
|
1863
2086
|
const handleMouseDown = (e) => {
|
|
1864
2087
|
const canvas = canvasRef.current;
|
|
1865
|
-
if (!canvas) return;
|
|
2088
|
+
if (!canvas || transformTool.active) return;
|
|
1866
2089
|
const canvasPt = getCanvasEventPoint(e);
|
|
1867
2090
|
if (activeTab === "select") {
|
|
1868
2091
|
const gesture = selectionGestureRef.current;
|
|
1869
|
-
const imgPt = (0,
|
|
2092
|
+
const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
1870
2093
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
1871
2094
|
return;
|
|
1872
2095
|
}
|
|
@@ -1877,8 +2100,8 @@ var ImageEditor = ({
|
|
|
1877
2100
|
width: state.imageDimensions.width,
|
|
1878
2101
|
height: state.imageDimensions.height
|
|
1879
2102
|
};
|
|
1880
|
-
const handle = (0,
|
|
1881
|
-
const startImgPt = (0,
|
|
2103
|
+
const handle = (0, import_image_editor12.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2104
|
+
const startImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
1882
2105
|
if (handle) {
|
|
1883
2106
|
cropDragInfoRef.current = {
|
|
1884
2107
|
handle,
|
|
@@ -1897,12 +2120,12 @@ var ImageEditor = ({
|
|
|
1897
2120
|
return;
|
|
1898
2121
|
}
|
|
1899
2122
|
if (activeTab === "annotate") {
|
|
1900
|
-
const imgPt = (0,
|
|
2123
|
+
const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
1901
2124
|
dragStartPointRef.current = imgPt;
|
|
1902
2125
|
if (state.activeTool === "select") {
|
|
1903
2126
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
1904
2127
|
const ann = state.annotations[i];
|
|
1905
|
-
if ((0,
|
|
2128
|
+
if ((0, import_image_editor12.hitTestAnnotation)(imgPt, ann)) {
|
|
1906
2129
|
editor.selectAnnotation(ann.id);
|
|
1907
2130
|
annotationDragInfoRef.current = {
|
|
1908
2131
|
annId: ann.id,
|
|
@@ -1934,11 +2157,11 @@ var ImageEditor = ({
|
|
|
1934
2157
|
};
|
|
1935
2158
|
const handleMouseMove = (e) => {
|
|
1936
2159
|
const canvas = canvasRef.current;
|
|
1937
|
-
if (!canvas) return;
|
|
2160
|
+
if (!canvas || transformTool.active) return;
|
|
1938
2161
|
const canvasPt = getCanvasEventPoint(e);
|
|
1939
2162
|
if (activeTab === "select") {
|
|
1940
2163
|
const gesture = selectionGestureRef.current;
|
|
1941
|
-
if (gesture.active && gesture.move((0,
|
|
2164
|
+
if (gesture.active && gesture.move((0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
1942
2165
|
selectionDraftRef.current = gesture.draftPath;
|
|
1943
2166
|
renderCanvas();
|
|
1944
2167
|
}
|
|
@@ -1947,7 +2170,7 @@ var ImageEditor = ({
|
|
|
1947
2170
|
if (activeTab === "crop") {
|
|
1948
2171
|
const drag = cropDragInfoRef.current;
|
|
1949
2172
|
if (drag) {
|
|
1950
|
-
const currentImgPt = (0,
|
|
2173
|
+
const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
1951
2174
|
let newCrop;
|
|
1952
2175
|
if (drag.handle === "new") {
|
|
1953
2176
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -1961,7 +2184,7 @@ var ImageEditor = ({
|
|
|
1961
2184
|
height: Math.round(Math.max(20, maxY - minY))
|
|
1962
2185
|
};
|
|
1963
2186
|
} else {
|
|
1964
|
-
newCrop = (0,
|
|
2187
|
+
newCrop = (0, import_image_editor12.calculateCropDrag)(
|
|
1965
2188
|
drag.startCrop,
|
|
1966
2189
|
drag.handle,
|
|
1967
2190
|
drag.startImgPt,
|
|
@@ -1981,15 +2204,15 @@ var ImageEditor = ({
|
|
|
1981
2204
|
width: state.imageDimensions.width,
|
|
1982
2205
|
height: state.imageDimensions.height
|
|
1983
2206
|
};
|
|
1984
|
-
const handle = (0,
|
|
1985
|
-
canvas.style.cursor = (0,
|
|
2207
|
+
const handle = (0, import_image_editor12.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2208
|
+
canvas.style.cursor = (0, import_image_editor12.getCropCursor)(handle, state.transform);
|
|
1986
2209
|
}
|
|
1987
2210
|
return;
|
|
1988
2211
|
}
|
|
1989
2212
|
if (activeTab === "annotate") {
|
|
1990
2213
|
if (annotationDragInfoRef.current) {
|
|
1991
2214
|
const drag = annotationDragInfoRef.current;
|
|
1992
|
-
const currentImgPt2 = (0,
|
|
2215
|
+
const currentImgPt2 = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
1993
2216
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
1994
2217
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
1995
2218
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -2001,10 +2224,10 @@ var ImageEditor = ({
|
|
|
2001
2224
|
const startPt = dragStartPointRef.current;
|
|
2002
2225
|
if (!startPt) {
|
|
2003
2226
|
if (state.activeTool === "select") {
|
|
2004
|
-
const imgPt = (0,
|
|
2227
|
+
const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2005
2228
|
let hovered = false;
|
|
2006
2229
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
2007
|
-
if ((0,
|
|
2230
|
+
if ((0, import_image_editor12.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
2008
2231
|
hovered = true;
|
|
2009
2232
|
break;
|
|
2010
2233
|
}
|
|
@@ -2015,7 +2238,7 @@ var ImageEditor = ({
|
|
|
2015
2238
|
}
|
|
2016
2239
|
return;
|
|
2017
2240
|
}
|
|
2018
|
-
const currentImgPt = (0,
|
|
2241
|
+
const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2019
2242
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2020
2243
|
currentPathRef.current.push(currentImgPt);
|
|
2021
2244
|
const draft = {
|
|
@@ -2090,12 +2313,12 @@ var ImageEditor = ({
|
|
|
2090
2313
|
};
|
|
2091
2314
|
const handleMouseUp = (e) => {
|
|
2092
2315
|
const canvas = canvasRef.current;
|
|
2093
|
-
if (!canvas) return;
|
|
2316
|
+
if (!canvas || transformTool.active) return;
|
|
2094
2317
|
const canvasPt = getCanvasEventPoint(e);
|
|
2095
2318
|
if (activeTab === "select") {
|
|
2096
2319
|
const gesture = selectionGestureRef.current;
|
|
2097
2320
|
if (gesture.active) {
|
|
2098
|
-
gesture.end((0,
|
|
2321
|
+
gesture.end((0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
2099
2322
|
selectionDraftRef.current = null;
|
|
2100
2323
|
renderCanvas();
|
|
2101
2324
|
}
|
|
@@ -2119,7 +2342,7 @@ var ImageEditor = ({
|
|
|
2119
2342
|
}
|
|
2120
2343
|
const startPt = dragStartPointRef.current;
|
|
2121
2344
|
if (startPt) {
|
|
2122
|
-
const currentImgPt = (0,
|
|
2345
|
+
const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2123
2346
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2124
2347
|
if (currentPathRef.current.length > 1) {
|
|
2125
2348
|
editor.addAnnotation({
|
|
@@ -2215,15 +2438,15 @@ var ImageEditor = ({
|
|
|
2215
2438
|
link.click();
|
|
2216
2439
|
}
|
|
2217
2440
|
};
|
|
2218
|
-
return /* @__PURE__ */ (0,
|
|
2441
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2219
2442
|
"div",
|
|
2220
2443
|
{
|
|
2221
2444
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
2222
2445
|
style,
|
|
2223
2446
|
children: [
|
|
2224
|
-
/* @__PURE__ */ (0,
|
|
2225
|
-
/* @__PURE__ */ (0,
|
|
2226
|
-
/* @__PURE__ */ (0,
|
|
2447
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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: [
|
|
2448
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
2449
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2227
2450
|
"button",
|
|
2228
2451
|
{
|
|
2229
2452
|
type: "button",
|
|
@@ -2235,7 +2458,7 @@ var ImageEditor = ({
|
|
|
2235
2458
|
children: "Transform & Crop"
|
|
2236
2459
|
}
|
|
2237
2460
|
),
|
|
2238
|
-
/* @__PURE__ */ (0,
|
|
2461
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2239
2462
|
"button",
|
|
2240
2463
|
{
|
|
2241
2464
|
type: "button",
|
|
@@ -2247,7 +2470,7 @@ var ImageEditor = ({
|
|
|
2247
2470
|
children: "Adjustments"
|
|
2248
2471
|
}
|
|
2249
2472
|
),
|
|
2250
|
-
/* @__PURE__ */ (0,
|
|
2473
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2251
2474
|
"button",
|
|
2252
2475
|
{
|
|
2253
2476
|
type: "button",
|
|
@@ -2259,7 +2482,7 @@ var ImageEditor = ({
|
|
|
2259
2482
|
children: "Layers"
|
|
2260
2483
|
}
|
|
2261
2484
|
),
|
|
2262
|
-
/* @__PURE__ */ (0,
|
|
2485
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2263
2486
|
"button",
|
|
2264
2487
|
{
|
|
2265
2488
|
type: "button",
|
|
@@ -2271,7 +2494,7 @@ var ImageEditor = ({
|
|
|
2271
2494
|
children: "Paint"
|
|
2272
2495
|
}
|
|
2273
2496
|
),
|
|
2274
|
-
/* @__PURE__ */ (0,
|
|
2497
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2275
2498
|
"button",
|
|
2276
2499
|
{
|
|
2277
2500
|
type: "button",
|
|
@@ -2283,7 +2506,7 @@ var ImageEditor = ({
|
|
|
2283
2506
|
children: "Select & Mask"
|
|
2284
2507
|
}
|
|
2285
2508
|
),
|
|
2286
|
-
/* @__PURE__ */ (0,
|
|
2509
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2287
2510
|
"button",
|
|
2288
2511
|
{
|
|
2289
2512
|
type: "button",
|
|
@@ -2295,7 +2518,7 @@ var ImageEditor = ({
|
|
|
2295
2518
|
children: "Annotations"
|
|
2296
2519
|
}
|
|
2297
2520
|
),
|
|
2298
|
-
/* @__PURE__ */ (0,
|
|
2521
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2299
2522
|
"button",
|
|
2300
2523
|
{
|
|
2301
2524
|
type: "button",
|
|
@@ -2307,7 +2530,7 @@ var ImageEditor = ({
|
|
|
2307
2530
|
children: "Depth Mask"
|
|
2308
2531
|
}
|
|
2309
2532
|
),
|
|
2310
|
-
/* @__PURE__ */ (0,
|
|
2533
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2311
2534
|
"button",
|
|
2312
2535
|
{
|
|
2313
2536
|
type: "button",
|
|
@@ -2317,14 +2540,14 @@ var ImageEditor = ({
|
|
|
2317
2540
|
},
|
|
2318
2541
|
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"}`,
|
|
2319
2542
|
children: [
|
|
2320
|
-
/* @__PURE__ */ (0,
|
|
2543
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.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" }) }),
|
|
2321
2544
|
"AI Tools"
|
|
2322
2545
|
]
|
|
2323
2546
|
}
|
|
2324
2547
|
)
|
|
2325
2548
|
] }),
|
|
2326
|
-
/* @__PURE__ */ (0,
|
|
2327
|
-
/* @__PURE__ */ (0,
|
|
2549
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2550
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2328
2551
|
"button",
|
|
2329
2552
|
{
|
|
2330
2553
|
type: "button",
|
|
@@ -2335,7 +2558,7 @@ var ImageEditor = ({
|
|
|
2335
2558
|
children: "\u21A9"
|
|
2336
2559
|
}
|
|
2337
2560
|
),
|
|
2338
|
-
/* @__PURE__ */ (0,
|
|
2561
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2339
2562
|
"button",
|
|
2340
2563
|
{
|
|
2341
2564
|
type: "button",
|
|
@@ -2346,7 +2569,7 @@ var ImageEditor = ({
|
|
|
2346
2569
|
children: "\u21AA"
|
|
2347
2570
|
}
|
|
2348
2571
|
),
|
|
2349
|
-
/* @__PURE__ */ (0,
|
|
2572
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2350
2573
|
"button",
|
|
2351
2574
|
{
|
|
2352
2575
|
type: "button",
|
|
@@ -2355,8 +2578,8 @@ var ImageEditor = ({
|
|
|
2355
2578
|
children: "Reset"
|
|
2356
2579
|
}
|
|
2357
2580
|
),
|
|
2358
|
-
/* @__PURE__ */ (0,
|
|
2359
|
-
/* @__PURE__ */ (0,
|
|
2581
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
2582
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2360
2583
|
"button",
|
|
2361
2584
|
{
|
|
2362
2585
|
type: "button",
|
|
@@ -2366,11 +2589,11 @@ var ImageEditor = ({
|
|
|
2366
2589
|
children: "-"
|
|
2367
2590
|
}
|
|
2368
2591
|
),
|
|
2369
|
-
/* @__PURE__ */ (0,
|
|
2592
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
2370
2593
|
Math.round(state.zoom * 100),
|
|
2371
2594
|
"%"
|
|
2372
2595
|
] }),
|
|
2373
|
-
/* @__PURE__ */ (0,
|
|
2596
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2374
2597
|
"button",
|
|
2375
2598
|
{
|
|
2376
2599
|
type: "button",
|
|
@@ -2380,8 +2603,8 @@ var ImageEditor = ({
|
|
|
2380
2603
|
children: "+"
|
|
2381
2604
|
}
|
|
2382
2605
|
),
|
|
2383
|
-
/* @__PURE__ */ (0,
|
|
2384
|
-
/* @__PURE__ */ (0,
|
|
2606
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
2607
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2385
2608
|
"button",
|
|
2386
2609
|
{
|
|
2387
2610
|
type: "button",
|
|
@@ -2392,7 +2615,7 @@ var ImageEditor = ({
|
|
|
2392
2615
|
children: "Hold Compare"
|
|
2393
2616
|
}
|
|
2394
2617
|
),
|
|
2395
|
-
/* @__PURE__ */ (0,
|
|
2618
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2396
2619
|
"button",
|
|
2397
2620
|
{
|
|
2398
2621
|
type: "button",
|
|
@@ -2403,13 +2626,15 @@ var ImageEditor = ({
|
|
|
2403
2626
|
)
|
|
2404
2627
|
] })
|
|
2405
2628
|
] }),
|
|
2406
|
-
/* @__PURE__ */ (0,
|
|
2407
|
-
|
|
2629
|
+
transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
|
|
2630
|
+
!transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime11.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 }),
|
|
2631
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
2632
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2408
2633
|
"div",
|
|
2409
2634
|
{
|
|
2410
2635
|
ref: containerRef,
|
|
2411
2636
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
2412
|
-
children: /* @__PURE__ */ (0,
|
|
2637
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2413
2638
|
"canvas",
|
|
2414
2639
|
{
|
|
2415
2640
|
ref: canvasRef,
|
|
@@ -2422,16 +2647,17 @@ var ImageEditor = ({
|
|
|
2422
2647
|
onPointerUp: handlePaintPointerUp,
|
|
2423
2648
|
onPointerCancel: () => paintGestureRef.current?.cancel(),
|
|
2424
2649
|
"data-testid": "image-editor-canvas",
|
|
2425
|
-
|
|
2650
|
+
style: transformTool.active ? { cursor: transformCursor } : void 0,
|
|
2651
|
+
className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : ""}`
|
|
2426
2652
|
}
|
|
2427
2653
|
)
|
|
2428
2654
|
}
|
|
2429
2655
|
),
|
|
2430
|
-
/* @__PURE__ */ (0,
|
|
2431
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
2432
|
-
/* @__PURE__ */ (0,
|
|
2433
|
-
/* @__PURE__ */ (0,
|
|
2434
|
-
/* @__PURE__ */ (0,
|
|
2656
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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: [
|
|
2657
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
2658
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
2659
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
2660
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2435
2661
|
"button",
|
|
2436
2662
|
{
|
|
2437
2663
|
type: "button",
|
|
@@ -2443,7 +2669,7 @@ var ImageEditor = ({
|
|
|
2443
2669
|
children: "Freeform"
|
|
2444
2670
|
}
|
|
2445
2671
|
),
|
|
2446
|
-
/* @__PURE__ */ (0,
|
|
2672
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2447
2673
|
"button",
|
|
2448
2674
|
{
|
|
2449
2675
|
type: "button",
|
|
@@ -2455,7 +2681,7 @@ var ImageEditor = ({
|
|
|
2455
2681
|
children: "1:1 Square"
|
|
2456
2682
|
}
|
|
2457
2683
|
),
|
|
2458
|
-
/* @__PURE__ */ (0,
|
|
2684
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2459
2685
|
"button",
|
|
2460
2686
|
{
|
|
2461
2687
|
type: "button",
|
|
@@ -2467,7 +2693,7 @@ var ImageEditor = ({
|
|
|
2467
2693
|
children: "4:3 Standard"
|
|
2468
2694
|
}
|
|
2469
2695
|
),
|
|
2470
|
-
/* @__PURE__ */ (0,
|
|
2696
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2471
2697
|
"button",
|
|
2472
2698
|
{
|
|
2473
2699
|
type: "button",
|
|
@@ -2479,7 +2705,7 @@ var ImageEditor = ({
|
|
|
2479
2705
|
children: "16:9 Wide"
|
|
2480
2706
|
}
|
|
2481
2707
|
),
|
|
2482
|
-
/* @__PURE__ */ (0,
|
|
2708
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2483
2709
|
"button",
|
|
2484
2710
|
{
|
|
2485
2711
|
type: "button",
|
|
@@ -2491,7 +2717,7 @@ var ImageEditor = ({
|
|
|
2491
2717
|
children: "3:2 Photo"
|
|
2492
2718
|
}
|
|
2493
2719
|
),
|
|
2494
|
-
/* @__PURE__ */ (0,
|
|
2720
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2495
2721
|
"button",
|
|
2496
2722
|
{
|
|
2497
2723
|
type: "button",
|
|
@@ -2504,10 +2730,10 @@ var ImageEditor = ({
|
|
|
2504
2730
|
}
|
|
2505
2731
|
)
|
|
2506
2732
|
] }),
|
|
2507
|
-
/* @__PURE__ */ (0,
|
|
2508
|
-
/* @__PURE__ */ (0,
|
|
2509
|
-
/* @__PURE__ */ (0,
|
|
2510
|
-
/* @__PURE__ */ (0,
|
|
2733
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
2734
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
2735
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
2736
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2511
2737
|
"button",
|
|
2512
2738
|
{
|
|
2513
2739
|
type: "button",
|
|
@@ -2516,7 +2742,7 @@ var ImageEditor = ({
|
|
|
2516
2742
|
children: "Rotate -90\xB0"
|
|
2517
2743
|
}
|
|
2518
2744
|
),
|
|
2519
|
-
/* @__PURE__ */ (0,
|
|
2745
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2520
2746
|
"button",
|
|
2521
2747
|
{
|
|
2522
2748
|
type: "button",
|
|
@@ -2525,7 +2751,7 @@ var ImageEditor = ({
|
|
|
2525
2751
|
children: "Rotate +90\xB0"
|
|
2526
2752
|
}
|
|
2527
2753
|
),
|
|
2528
|
-
/* @__PURE__ */ (0,
|
|
2754
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2529
2755
|
"button",
|
|
2530
2756
|
{
|
|
2531
2757
|
type: "button",
|
|
@@ -2534,7 +2760,7 @@ var ImageEditor = ({
|
|
|
2534
2760
|
children: "Flip Horizontal"
|
|
2535
2761
|
}
|
|
2536
2762
|
),
|
|
2537
|
-
/* @__PURE__ */ (0,
|
|
2763
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2538
2764
|
"button",
|
|
2539
2765
|
{
|
|
2540
2766
|
type: "button",
|
|
@@ -2545,10 +2771,10 @@ var ImageEditor = ({
|
|
|
2545
2771
|
)
|
|
2546
2772
|
] })
|
|
2547
2773
|
] }),
|
|
2548
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2550
|
-
/* @__PURE__ */ (0,
|
|
2551
|
-
/* @__PURE__ */ (0,
|
|
2774
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
2775
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2776
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
2777
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2552
2778
|
"button",
|
|
2553
2779
|
{
|
|
2554
2780
|
type: "button",
|
|
@@ -2558,25 +2784,25 @@ var ImageEditor = ({
|
|
|
2558
2784
|
}
|
|
2559
2785
|
)
|
|
2560
2786
|
] }),
|
|
2561
|
-
/* @__PURE__ */ (0,
|
|
2562
|
-
|
|
2563
|
-
/* @__PURE__ */ (0,
|
|
2787
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Histogram, { histogram: editor.histogram }),
|
|
2788
|
+
import_image_editor12.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react11.default.Fragment, { children: [
|
|
2789
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2564
2790
|
ControlSlider,
|
|
2565
2791
|
{
|
|
2566
2792
|
spec,
|
|
2567
|
-
value: (0,
|
|
2793
|
+
value: (0, import_image_editor12.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
2568
2794
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
2569
2795
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
2570
2796
|
}
|
|
2571
2797
|
),
|
|
2572
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
2798
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2573
2799
|
"div",
|
|
2574
2800
|
{
|
|
2575
2801
|
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",
|
|
2576
2802
|
"data-testid": "image-editor-process-notice",
|
|
2577
2803
|
children: [
|
|
2578
|
-
/* @__PURE__ */ (0,
|
|
2579
|
-
/* @__PURE__ */ (0,
|
|
2804
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
2805
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2580
2806
|
"button",
|
|
2581
2807
|
{
|
|
2582
2808
|
type: "button",
|
|
@@ -2589,7 +2815,7 @@ var ImageEditor = ({
|
|
|
2589
2815
|
}
|
|
2590
2816
|
)
|
|
2591
2817
|
] }, spec.id)),
|
|
2592
|
-
/* @__PURE__ */ (0,
|
|
2818
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2593
2819
|
AdjustmentLayersPanel,
|
|
2594
2820
|
{
|
|
2595
2821
|
controller,
|
|
@@ -2598,19 +2824,41 @@ var ImageEditor = ({
|
|
|
2598
2824
|
}
|
|
2599
2825
|
) })
|
|
2600
2826
|
] }),
|
|
2601
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
2602
|
-
/* @__PURE__ */ (0,
|
|
2603
|
-
/* @__PURE__ */ (0,
|
|
2827
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
2829
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2830
|
+
"button",
|
|
2831
|
+
{
|
|
2832
|
+
type: "button",
|
|
2833
|
+
title: "Edit \u203A Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer",
|
|
2834
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
|
|
2835
|
+
disabled: transformTool.active,
|
|
2836
|
+
onClick: () => transformTool.begin(),
|
|
2837
|
+
children: "Free Transform"
|
|
2838
|
+
}
|
|
2839
|
+
),
|
|
2840
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LayersPanel, { controller })
|
|
2604
2841
|
] }),
|
|
2605
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
2606
|
-
/* @__PURE__ */ (0,
|
|
2607
|
-
/* @__PURE__ */ (0,
|
|
2608
|
-
|
|
2609
|
-
|
|
2842
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
2844
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BrushOptionsBar, { controller }),
|
|
2845
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2846
|
+
"button",
|
|
2847
|
+
{
|
|
2848
|
+
type: "button",
|
|
2849
|
+
title: "Edit \u203A Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer",
|
|
2850
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start",
|
|
2851
|
+
disabled: transformTool.active,
|
|
2852
|
+
onClick: () => transformTool.begin(),
|
|
2853
|
+
children: "Free Transform"
|
|
2854
|
+
}
|
|
2855
|
+
),
|
|
2856
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
2857
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LayersPanel, { controller }) })
|
|
2610
2858
|
] }),
|
|
2611
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
2612
|
-
/* @__PURE__ */ (0,
|
|
2613
|
-
/* @__PURE__ */ (0,
|
|
2859
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
2860
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
2861
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2614
2862
|
"button",
|
|
2615
2863
|
{
|
|
2616
2864
|
type: "button",
|
|
@@ -2620,9 +2868,9 @@ var ImageEditor = ({
|
|
|
2620
2868
|
},
|
|
2621
2869
|
t
|
|
2622
2870
|
)) }),
|
|
2623
|
-
/* @__PURE__ */ (0,
|
|
2624
|
-
/* @__PURE__ */ (0,
|
|
2625
|
-
/* @__PURE__ */ (0,
|
|
2871
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
2872
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
2873
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2626
2874
|
"input",
|
|
2627
2875
|
{
|
|
2628
2876
|
type: "color",
|
|
@@ -2631,15 +2879,15 @@ var ImageEditor = ({
|
|
|
2631
2879
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
2632
2880
|
}
|
|
2633
2881
|
),
|
|
2634
|
-
/* @__PURE__ */ (0,
|
|
2635
|
-
/* @__PURE__ */ (0,
|
|
2636
|
-
/* @__PURE__ */ (0,
|
|
2637
|
-
/* @__PURE__ */ (0,
|
|
2882
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
2883
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
2884
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Width:" }),
|
|
2885
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-mono", children: [
|
|
2638
2886
|
strokeWidth,
|
|
2639
2887
|
"px"
|
|
2640
2888
|
] })
|
|
2641
2889
|
] }),
|
|
2642
|
-
/* @__PURE__ */ (0,
|
|
2890
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2643
2891
|
"input",
|
|
2644
2892
|
{
|
|
2645
2893
|
type: "range",
|
|
@@ -2652,10 +2900,10 @@ var ImageEditor = ({
|
|
|
2652
2900
|
)
|
|
2653
2901
|
] })
|
|
2654
2902
|
] }),
|
|
2655
|
-
/* @__PURE__ */ (0,
|
|
2656
|
-
/* @__PURE__ */ (0,
|
|
2657
|
-
/* @__PURE__ */ (0,
|
|
2658
|
-
/* @__PURE__ */ (0,
|
|
2903
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
2904
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
2905
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-2", children: [
|
|
2906
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2659
2907
|
"input",
|
|
2660
2908
|
{
|
|
2661
2909
|
type: "text",
|
|
@@ -2666,7 +2914,7 @@ var ImageEditor = ({
|
|
|
2666
2914
|
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"
|
|
2667
2915
|
}
|
|
2668
2916
|
),
|
|
2669
|
-
/* @__PURE__ */ (0,
|
|
2917
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2670
2918
|
"button",
|
|
2671
2919
|
{
|
|
2672
2920
|
type: "button",
|
|
@@ -2676,14 +2924,14 @@ var ImageEditor = ({
|
|
|
2676
2924
|
}
|
|
2677
2925
|
)
|
|
2678
2926
|
] }),
|
|
2679
|
-
/* @__PURE__ */ (0,
|
|
2680
|
-
/* @__PURE__ */ (0,
|
|
2681
|
-
/* @__PURE__ */ (0,
|
|
2927
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
2928
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Font Size:" }),
|
|
2929
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-mono", children: [
|
|
2682
2930
|
fontSize,
|
|
2683
2931
|
"px"
|
|
2684
2932
|
] })
|
|
2685
2933
|
] }),
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2934
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2687
2935
|
"input",
|
|
2688
2936
|
{
|
|
2689
2937
|
type: "range",
|
|
@@ -2694,14 +2942,14 @@ var ImageEditor = ({
|
|
|
2694
2942
|
className: "w-full accent-indigo-500"
|
|
2695
2943
|
}
|
|
2696
2944
|
),
|
|
2697
|
-
/* @__PURE__ */ (0,
|
|
2698
|
-
/* @__PURE__ */ (0,
|
|
2699
|
-
/* @__PURE__ */ (0,
|
|
2945
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
2946
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2947
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-slate-400", children: [
|
|
2700
2948
|
"Layers (",
|
|
2701
2949
|
state.annotations.length,
|
|
2702
2950
|
")"
|
|
2703
2951
|
] }),
|
|
2704
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
2952
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2705
2953
|
"button",
|
|
2706
2954
|
{
|
|
2707
2955
|
type: "button",
|
|
@@ -2710,7 +2958,7 @@ var ImageEditor = ({
|
|
|
2710
2958
|
children: "Delete Selected"
|
|
2711
2959
|
}
|
|
2712
2960
|
),
|
|
2713
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
2961
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2714
2962
|
"button",
|
|
2715
2963
|
{
|
|
2716
2964
|
type: "button",
|
|
@@ -2721,10 +2969,10 @@ var ImageEditor = ({
|
|
|
2721
2969
|
)
|
|
2722
2970
|
] })
|
|
2723
2971
|
] }),
|
|
2724
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
2725
|
-
/* @__PURE__ */ (0,
|
|
2726
|
-
/* @__PURE__ */ (0,
|
|
2727
|
-
/* @__PURE__ */ (0,
|
|
2972
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
2973
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2974
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
2975
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2728
2976
|
"button",
|
|
2729
2977
|
{
|
|
2730
2978
|
type: "button",
|
|
@@ -2734,8 +2982,8 @@ var ImageEditor = ({
|
|
|
2734
2982
|
}
|
|
2735
2983
|
)
|
|
2736
2984
|
] }),
|
|
2737
|
-
/* @__PURE__ */ (0,
|
|
2738
|
-
/* @__PURE__ */ (0,
|
|
2985
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
2986
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2739
2987
|
"input",
|
|
2740
2988
|
{
|
|
2741
2989
|
type: "checkbox",
|
|
@@ -2744,12 +2992,12 @@ var ImageEditor = ({
|
|
|
2744
2992
|
className: "rounded accent-indigo-500"
|
|
2745
2993
|
}
|
|
2746
2994
|
),
|
|
2747
|
-
/* @__PURE__ */ (0,
|
|
2995
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
2748
2996
|
] }),
|
|
2749
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
2750
|
-
/* @__PURE__ */ (0,
|
|
2751
|
-
/* @__PURE__ */ (0,
|
|
2752
|
-
/* @__PURE__ */ (0,
|
|
2997
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2998
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
2999
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
3000
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2753
3001
|
"input",
|
|
2754
3002
|
{
|
|
2755
3003
|
type: "text",
|
|
@@ -2760,8 +3008,8 @@ var ImageEditor = ({
|
|
|
2760
3008
|
}
|
|
2761
3009
|
)
|
|
2762
3010
|
] }),
|
|
2763
|
-
/* @__PURE__ */ (0,
|
|
2764
|
-
/* @__PURE__ */ (0,
|
|
3011
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-2", children: [
|
|
3012
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2765
3013
|
"button",
|
|
2766
3014
|
{
|
|
2767
3015
|
type: "button",
|
|
@@ -2770,7 +3018,7 @@ var ImageEditor = ({
|
|
|
2770
3018
|
children: "Threshold Mode"
|
|
2771
3019
|
}
|
|
2772
3020
|
),
|
|
2773
|
-
/* @__PURE__ */ (0,
|
|
3021
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2774
3022
|
"button",
|
|
2775
3023
|
{
|
|
2776
3024
|
type: "button",
|
|
@@ -2780,12 +3028,12 @@ var ImageEditor = ({
|
|
|
2780
3028
|
}
|
|
2781
3029
|
)
|
|
2782
3030
|
] }),
|
|
2783
|
-
/* @__PURE__ */ (0,
|
|
2784
|
-
/* @__PURE__ */ (0,
|
|
2785
|
-
/* @__PURE__ */ (0,
|
|
2786
|
-
/* @__PURE__ */ (0,
|
|
3031
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
3032
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3033
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
3034
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
2787
3035
|
] }),
|
|
2788
|
-
/* @__PURE__ */ (0,
|
|
3036
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2789
3037
|
"input",
|
|
2790
3038
|
{
|
|
2791
3039
|
type: "range",
|
|
@@ -2799,12 +3047,12 @@ var ImageEditor = ({
|
|
|
2799
3047
|
}
|
|
2800
3048
|
)
|
|
2801
3049
|
] }),
|
|
2802
|
-
/* @__PURE__ */ (0,
|
|
2803
|
-
/* @__PURE__ */ (0,
|
|
2804
|
-
/* @__PURE__ */ (0,
|
|
2805
|
-
/* @__PURE__ */ (0,
|
|
3050
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
3051
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3052
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
3053
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
2806
3054
|
] }),
|
|
2807
|
-
/* @__PURE__ */ (0,
|
|
3055
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2808
3056
|
"input",
|
|
2809
3057
|
{
|
|
2810
3058
|
type: "range",
|
|
@@ -2818,12 +3066,12 @@ var ImageEditor = ({
|
|
|
2818
3066
|
}
|
|
2819
3067
|
)
|
|
2820
3068
|
] }),
|
|
2821
|
-
/* @__PURE__ */ (0,
|
|
2822
|
-
/* @__PURE__ */ (0,
|
|
2823
|
-
/* @__PURE__ */ (0,
|
|
2824
|
-
/* @__PURE__ */ (0,
|
|
3069
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
3070
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3071
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Softness:" }),
|
|
3072
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
2825
3073
|
] }),
|
|
2826
|
-
/* @__PURE__ */ (0,
|
|
3074
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2827
3075
|
"input",
|
|
2828
3076
|
{
|
|
2829
3077
|
type: "range",
|
|
@@ -2835,8 +3083,8 @@ var ImageEditor = ({
|
|
|
2835
3083
|
}
|
|
2836
3084
|
)
|
|
2837
3085
|
] }),
|
|
2838
|
-
/* @__PURE__ */ (0,
|
|
2839
|
-
/* @__PURE__ */ (0,
|
|
3086
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
3087
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2840
3088
|
"input",
|
|
2841
3089
|
{
|
|
2842
3090
|
type: "checkbox",
|
|
@@ -2845,12 +3093,12 @@ var ImageEditor = ({
|
|
|
2845
3093
|
className: "rounded accent-indigo-500"
|
|
2846
3094
|
}
|
|
2847
3095
|
),
|
|
2848
|
-
/* @__PURE__ */ (0,
|
|
3096
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Invert Mask" })
|
|
2849
3097
|
] })
|
|
2850
3098
|
] })
|
|
2851
3099
|
] }),
|
|
2852
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
2853
|
-
/* @__PURE__ */ (0,
|
|
3100
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3101
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2854
3102
|
SelectionOptionsBar,
|
|
2855
3103
|
{
|
|
2856
3104
|
controller,
|
|
@@ -2860,13 +3108,37 @@ var ImageEditor = ({
|
|
|
2860
3108
|
quickMask: Boolean(state.quickMask)
|
|
2861
3109
|
}
|
|
2862
3110
|
),
|
|
2863
|
-
selectionError && /* @__PURE__ */ (0,
|
|
2864
|
-
/* @__PURE__ */ (0,
|
|
3111
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
3112
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-1", children: [
|
|
3113
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3114
|
+
"button",
|
|
3115
|
+
{
|
|
3116
|
+
type: "button",
|
|
3117
|
+
title: "Select \u203A Transform Selection: the outline only",
|
|
3118
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
|
|
3119
|
+
disabled: transformTool.active,
|
|
3120
|
+
onClick: () => transformTool.begin({ content: "selection-outline" }),
|
|
3121
|
+
children: "Transform Selection"
|
|
3122
|
+
}
|
|
3123
|
+
),
|
|
3124
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3125
|
+
"button",
|
|
3126
|
+
{
|
|
3127
|
+
type: "button",
|
|
3128
|
+
title: "Edit \u203A Free Transform: the selected pixels of the active layer",
|
|
3129
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
|
|
3130
|
+
disabled: transformTool.active,
|
|
3131
|
+
onClick: () => transformTool.begin({ content: "selection" }),
|
|
3132
|
+
children: "Free Transform Pixels"
|
|
3133
|
+
}
|
|
3134
|
+
)
|
|
3135
|
+
] }),
|
|
3136
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
2865
3137
|
] }),
|
|
2866
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
2867
|
-
/* @__PURE__ */ (0,
|
|
2868
|
-
/* @__PURE__ */ (0,
|
|
2869
|
-
/* @__PURE__ */ (0,
|
|
3138
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3139
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
3140
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Results go to" }),
|
|
3141
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2870
3142
|
"select",
|
|
2871
3143
|
{
|
|
2872
3144
|
"aria-label": "AI result target",
|
|
@@ -2874,54 +3146,54 @@ var ImageEditor = ({
|
|
|
2874
3146
|
onChange: (e) => setAiTarget(e.target.value),
|
|
2875
3147
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
2876
3148
|
children: [
|
|
2877
|
-
/* @__PURE__ */ (0,
|
|
2878
|
-
/* @__PURE__ */ (0,
|
|
2879
|
-
/* @__PURE__ */ (0,
|
|
3149
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
3150
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
3151
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "replace", children: "Replace image" })
|
|
2880
3152
|
]
|
|
2881
3153
|
}
|
|
2882
3154
|
)
|
|
2883
3155
|
] }),
|
|
2884
|
-
/* @__PURE__ */ (0,
|
|
2885
|
-
/* @__PURE__ */ (0,
|
|
2886
|
-
/* @__PURE__ */ (0,
|
|
2887
|
-
/* @__PURE__ */ (0,
|
|
3156
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3157
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3158
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3159
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.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" }) }),
|
|
2888
3160
|
"Background Removal"
|
|
2889
3161
|
] }),
|
|
2890
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
3162
|
+
isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime11.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..." })
|
|
2891
3163
|
] }),
|
|
2892
|
-
/* @__PURE__ */ (0,
|
|
2893
|
-
/* @__PURE__ */ (0,
|
|
3164
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
3165
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2894
3166
|
"button",
|
|
2895
3167
|
{
|
|
2896
3168
|
type: "button",
|
|
2897
3169
|
onClick: handleRemoveBackground,
|
|
2898
3170
|
disabled: isRemovingBg || isInpainting,
|
|
2899
3171
|
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",
|
|
2900
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
2901
|
-
/* @__PURE__ */ (0,
|
|
3172
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3173
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
2902
3174
|
"Removing Background..."
|
|
2903
|
-
] }) : /* @__PURE__ */ (0,
|
|
2904
|
-
/* @__PURE__ */ (0,
|
|
3175
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3176
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.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" }) }),
|
|
2905
3177
|
"Remove Background"
|
|
2906
3178
|
] })
|
|
2907
3179
|
}
|
|
2908
3180
|
)
|
|
2909
3181
|
] }),
|
|
2910
|
-
/* @__PURE__ */ (0,
|
|
2911
|
-
/* @__PURE__ */ (0,
|
|
2912
|
-
/* @__PURE__ */ (0,
|
|
2913
|
-
/* @__PURE__ */ (0,
|
|
2914
|
-
/* @__PURE__ */ (0,
|
|
2915
|
-
/* @__PURE__ */ (0,
|
|
3182
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3183
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3184
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3185
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
3186
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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" }),
|
|
3187
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m14 7 3 3" })
|
|
2916
3188
|
] }),
|
|
2917
3189
|
"Generative Inpainting"
|
|
2918
3190
|
] }),
|
|
2919
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
3191
|
+
isInpainting && /* @__PURE__ */ (0, import_jsx_runtime11.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..." })
|
|
2920
3192
|
] }),
|
|
2921
|
-
/* @__PURE__ */ (0,
|
|
2922
|
-
/* @__PURE__ */ (0,
|
|
2923
|
-
/* @__PURE__ */ (0,
|
|
2924
|
-
/* @__PURE__ */ (0,
|
|
3193
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
3194
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3195
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
3196
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2925
3197
|
"textarea",
|
|
2926
3198
|
{
|
|
2927
3199
|
id: "ai-inpaint-prompt-react",
|
|
@@ -2933,10 +3205,10 @@ var ImageEditor = ({
|
|
|
2933
3205
|
}
|
|
2934
3206
|
)
|
|
2935
3207
|
] }),
|
|
2936
|
-
/* @__PURE__ */ (0,
|
|
2937
|
-
/* @__PURE__ */ (0,
|
|
2938
|
-
/* @__PURE__ */ (0,
|
|
2939
|
-
/* @__PURE__ */ (0,
|
|
3208
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3209
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
3210
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
3211
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2940
3212
|
"button",
|
|
2941
3213
|
{
|
|
2942
3214
|
type: "button",
|
|
@@ -2949,7 +3221,7 @@ var ImageEditor = ({
|
|
|
2949
3221
|
]
|
|
2950
3222
|
}
|
|
2951
3223
|
),
|
|
2952
|
-
/* @__PURE__ */ (0,
|
|
3224
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2953
3225
|
"button",
|
|
2954
3226
|
{
|
|
2955
3227
|
type: "button",
|
|
@@ -2964,25 +3236,25 @@ var ImageEditor = ({
|
|
|
2964
3236
|
)
|
|
2965
3237
|
] })
|
|
2966
3238
|
] }),
|
|
2967
|
-
/* @__PURE__ */ (0,
|
|
3239
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2968
3240
|
"button",
|
|
2969
3241
|
{
|
|
2970
3242
|
type: "button",
|
|
2971
3243
|
onClick: handleInpaint,
|
|
2972
3244
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
2973
3245
|
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",
|
|
2974
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
2975
|
-
/* @__PURE__ */ (0,
|
|
3246
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3247
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
2976
3248
|
"Generating Inpaint..."
|
|
2977
|
-
] }) : /* @__PURE__ */ (0,
|
|
2978
|
-
/* @__PURE__ */ (0,
|
|
3249
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3250
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.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" }) }),
|
|
2979
3251
|
"Apply Inpainting"
|
|
2980
3252
|
] })
|
|
2981
3253
|
}
|
|
2982
3254
|
)
|
|
2983
3255
|
] }),
|
|
2984
|
-
aiError && /* @__PURE__ */ (0,
|
|
2985
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
3256
|
+
aiError && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
3257
|
+
aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
2986
3258
|
] })
|
|
2987
3259
|
] })
|
|
2988
3260
|
] })
|
|
@@ -2996,6 +3268,7 @@ var ImageEditor = ({
|
|
|
2996
3268
|
BrushOptionsBar,
|
|
2997
3269
|
ControlSlider,
|
|
2998
3270
|
CurvesEditor,
|
|
3271
|
+
FreeTransformOptionsBar,
|
|
2999
3272
|
Histogram,
|
|
3000
3273
|
ImageEditor,
|
|
3001
3274
|
LayerEffectsPanel,
|