@pixerate/editor-react 0.64.0 → 0.65.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-OSBDCFF4.js} +404 -194
- package/dist/chunk-OSBDCFF4.js.map +1 -0
- package/dist/image-editor/index.cjs +441 -232
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +14 -2
- package/dist/image-editor/index.d.ts +14 -2
- package/dist/image-editor/index.js +3 -1
- package/dist/index.cjs +870 -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,83 @@ 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 apply = (field, raw) => {
|
|
1667
|
+
const v = Number(raw);
|
|
1668
|
+
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
1669
|
+
};
|
|
1670
|
+
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: [
|
|
1671
|
+
/* @__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)) }),
|
|
1672
|
+
/* @__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)) }),
|
|
1673
|
+
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: [
|
|
1674
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: f.label }),
|
|
1675
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1676
|
+
"input",
|
|
1677
|
+
{
|
|
1678
|
+
type: "number",
|
|
1679
|
+
"aria-label": f.title,
|
|
1680
|
+
defaultValue: round(bar[f.id], f.unit),
|
|
1681
|
+
disabled: !bar.affine,
|
|
1682
|
+
step: f.unit === "px" ? 1 : 0.1,
|
|
1683
|
+
className: "w-16 rounded border border-slate-700 bg-slate-900 px-1 py-0.5 text-right disabled:opacity-40",
|
|
1684
|
+
onBlur: (e) => apply(f.id, e.currentTarget.value),
|
|
1685
|
+
onKeyDown: (e) => {
|
|
1686
|
+
if (e.key === "Enter") {
|
|
1687
|
+
e.preventDefault();
|
|
1688
|
+
e.stopPropagation();
|
|
1689
|
+
apply(f.id, e.currentTarget.value);
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
},
|
|
1693
|
+
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
1694
|
+
),
|
|
1695
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-500", children: f.unit }),
|
|
1696
|
+
f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1697
|
+
"button",
|
|
1698
|
+
{
|
|
1699
|
+
type: "button",
|
|
1700
|
+
"aria-label": "Keep width and height proportional",
|
|
1701
|
+
"aria-pressed": tool.proportional,
|
|
1702
|
+
className: chip2(tool.proportional),
|
|
1703
|
+
onClick: () => {
|
|
1704
|
+
tool.proportional = !tool.proportional;
|
|
1705
|
+
setTick((n) => n + 1);
|
|
1706
|
+
},
|
|
1707
|
+
children: "\u26D3\uFE0E"
|
|
1708
|
+
}
|
|
1709
|
+
)
|
|
1710
|
+
] }, f.id)),
|
|
1711
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1712
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
|
|
1713
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1714
|
+
"select",
|
|
1715
|
+
{
|
|
1716
|
+
"aria-label": "Interpolation",
|
|
1717
|
+
value: tool.interpolation,
|
|
1718
|
+
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
1719
|
+
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1720
|
+
children: import_image_editor11.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
1721
|
+
}
|
|
1722
|
+
)
|
|
1723
|
+
] }),
|
|
1724
|
+
/* @__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" }),
|
|
1725
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip2(false), onClick: () => tool.cancel(), children: "Cancel" }),
|
|
1726
|
+
tool.error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
|
|
1727
|
+
] });
|
|
1728
|
+
};
|
|
1729
|
+
|
|
1730
|
+
// src/image-editor/ImageEditor.tsx
|
|
1731
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1640
1732
|
var ImageEditor = ({
|
|
1641
1733
|
editor: externalEditor,
|
|
1642
1734
|
src,
|
|
@@ -1651,35 +1743,47 @@ var ImageEditor = ({
|
|
|
1651
1743
|
const internalEditor = useImageEditor({ image: src });
|
|
1652
1744
|
const editor = externalEditor || internalEditor;
|
|
1653
1745
|
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,
|
|
1746
|
+
const legacyProcess = (0, import_image_editor12.normalizeProcessVersion)(state.adjustments.process) < import_image_editor12.LATEST_PROCESS_VERSION;
|
|
1747
|
+
const canvasRef = (0, import_react11.useRef)(null);
|
|
1748
|
+
const containerRef = (0, import_react11.useRef)(null);
|
|
1749
|
+
const [activeTab, setActiveTab] = (0, import_react11.useState)("crop");
|
|
1750
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react11.useState)(null);
|
|
1751
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react11.useState)(import_image_editor12.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
1752
|
+
const selectionOptionsRef = (0, import_react11.useRef)(selectionOptions);
|
|
1661
1753
|
selectionOptionsRef.current = selectionOptions;
|
|
1662
|
-
const selectionGestureRef = (0,
|
|
1754
|
+
const selectionGestureRef = (0, import_react11.useRef)(null);
|
|
1663
1755
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
1664
|
-
selectionGestureRef.current = new
|
|
1756
|
+
selectionGestureRef.current = new import_image_editor12.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
1665
1757
|
}
|
|
1666
|
-
const selectionDraftRef = (0,
|
|
1667
|
-
const [selectionError, setSelectionError] = (0,
|
|
1668
|
-
const paintGestureRef = (0,
|
|
1669
|
-
const paintControllerRef = (0,
|
|
1758
|
+
const selectionDraftRef = (0, import_react11.useRef)(null);
|
|
1759
|
+
const [selectionError, setSelectionError] = (0, import_react11.useState)(null);
|
|
1760
|
+
const paintGestureRef = (0, import_react11.useRef)(null);
|
|
1761
|
+
const paintControllerRef = (0, import_react11.useRef)(controller);
|
|
1670
1762
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
1671
|
-
paintGestureRef.current = new
|
|
1763
|
+
paintGestureRef.current = new import_image_editor12.PaintGesture(controller);
|
|
1672
1764
|
paintControllerRef.current = controller;
|
|
1673
1765
|
}
|
|
1674
|
-
const brushCursorRef = (0,
|
|
1675
|
-
const [paintError, setPaintError] = (0,
|
|
1676
|
-
const
|
|
1677
|
-
const
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1766
|
+
const brushCursorRef = (0, import_react11.useRef)(null);
|
|
1767
|
+
const [paintError, setPaintError] = (0, import_react11.useState)(null);
|
|
1768
|
+
const transformToolRef = (0, import_react11.useRef)(null);
|
|
1769
|
+
const transformControllerRef = (0, import_react11.useRef)(controller);
|
|
1770
|
+
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
1771
|
+
transformToolRef.current?.cancel();
|
|
1772
|
+
transformToolRef.current = new import_image_editor12.FreeTransformTool(controller, {
|
|
1773
|
+
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
1774
|
+
});
|
|
1775
|
+
transformControllerRef.current = controller;
|
|
1776
|
+
}
|
|
1777
|
+
const transformTool = transformToolRef.current;
|
|
1778
|
+
const [, setTransformTick] = (0, import_react11.useState)(0);
|
|
1779
|
+
const [transformCursor, setTransformCursor] = (0, import_react11.useState)("default");
|
|
1780
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react11.useState)("");
|
|
1781
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react11.useState)("annotations");
|
|
1782
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react11.useState)(false);
|
|
1783
|
+
const [isInpainting, setIsInpainting] = (0, import_react11.useState)(false);
|
|
1784
|
+
const [aiError, setAiError] = (0, import_react11.useState)(null);
|
|
1785
|
+
const [aiSuccess, setAiSuccess] = (0, import_react11.useState)(null);
|
|
1786
|
+
const [aiTarget, setAiTarget] = (0, import_react11.useState)("auto");
|
|
1683
1787
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
1684
1788
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
1685
1789
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -1742,18 +1846,18 @@ var ImageEditor = ({
|
|
|
1742
1846
|
setIsInpainting(false);
|
|
1743
1847
|
}
|
|
1744
1848
|
};
|
|
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,
|
|
1849
|
+
const [activeColor, setActiveColor] = (0, import_react11.useState)("#ef4444");
|
|
1850
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react11.useState)(3);
|
|
1851
|
+
const [fontSize, setFontSize] = (0, import_react11.useState)(24);
|
|
1852
|
+
const [textInput, setTextInput] = (0, import_react11.useState)("");
|
|
1853
|
+
const draftAnnotationRef = (0, import_react11.useRef)(null);
|
|
1854
|
+
const draftCropRef = (0, import_react11.useRef)(null);
|
|
1855
|
+
const cropDragInfoRef = (0, import_react11.useRef)(null);
|
|
1856
|
+
const annotationDragInfoRef = (0, import_react11.useRef)(null);
|
|
1857
|
+
const isDrawingRef = (0, import_react11.useRef)(false);
|
|
1858
|
+
const currentPathRef = (0, import_react11.useRef)([]);
|
|
1859
|
+
const dragStartPointRef = (0, import_react11.useRef)(null);
|
|
1860
|
+
const renderCanvas = (0, import_react11.useCallback)(
|
|
1757
1861
|
async (draftAnnotation, draftCrop) => {
|
|
1758
1862
|
const canvas = canvasRef.current;
|
|
1759
1863
|
const container = containerRef.current;
|
|
@@ -1769,12 +1873,64 @@ var ImageEditor = ({
|
|
|
1769
1873
|
draftAnnotation: draftAnnotation !== void 0 ? draftAnnotation : draftAnnotationRef.current,
|
|
1770
1874
|
draftCrop: draftCrop !== void 0 ? draftCrop : draftCropRef.current,
|
|
1771
1875
|
draftSelectionPath: selectionDraftRef.current,
|
|
1772
|
-
brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null
|
|
1876
|
+
brushCursor: activeTab === "paint" && brushCursorRef.current && controller.getState().activeTool !== "move" && !transformTool.active ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size } : null,
|
|
1877
|
+
freeTransform: transformTool.overlay()
|
|
1773
1878
|
});
|
|
1774
1879
|
},
|
|
1775
|
-
[controller, activeTab]
|
|
1880
|
+
[controller, activeTab, transformTool]
|
|
1776
1881
|
);
|
|
1777
|
-
(0,
|
|
1882
|
+
(0, import_react11.useEffect)(() => transformTool.subscribe(() => {
|
|
1883
|
+
setTransformTick((n) => n + 1);
|
|
1884
|
+
void renderCanvas();
|
|
1885
|
+
}), [transformTool, renderCanvas]);
|
|
1886
|
+
const transformPoint = (e) => {
|
|
1887
|
+
const canvas = canvasRef.current;
|
|
1888
|
+
const rect = canvas.getBoundingClientRect();
|
|
1889
|
+
const sx = rect.width > 0 ? canvas.width / rect.width : 1;
|
|
1890
|
+
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
1891
|
+
const s = controller.getState();
|
|
1892
|
+
const cropping = activeTab === "crop";
|
|
1893
|
+
const projection = (0, import_image_editor12.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
1894
|
+
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);
|
|
1895
|
+
transformTool.setView(projection.scale);
|
|
1896
|
+
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
1897
|
+
};
|
|
1898
|
+
const handleTransformPointerDown = (e) => {
|
|
1899
|
+
if (!transformTool.active) return false;
|
|
1900
|
+
if (e.button !== 0) return true;
|
|
1901
|
+
e.preventDefault();
|
|
1902
|
+
try {
|
|
1903
|
+
e.currentTarget.setPointerCapture?.(e.pointerId);
|
|
1904
|
+
} catch {
|
|
1905
|
+
}
|
|
1906
|
+
const { pt, tolerance } = transformPoint(e);
|
|
1907
|
+
transformTool.down(pt, tolerance);
|
|
1908
|
+
return true;
|
|
1909
|
+
};
|
|
1910
|
+
const handleTransformPointerMove = (e) => {
|
|
1911
|
+
if (!transformTool.active) return false;
|
|
1912
|
+
const { pt, tolerance } = transformPoint(e);
|
|
1913
|
+
if (e.buttons & 1) transformTool.move(pt, e);
|
|
1914
|
+
else {
|
|
1915
|
+
const over = transformTool.hit(pt, tolerance);
|
|
1916
|
+
setTransformCursor(transformTool.cursor(over));
|
|
1917
|
+
}
|
|
1918
|
+
return true;
|
|
1919
|
+
};
|
|
1920
|
+
const handleTransformPointerUp = () => {
|
|
1921
|
+
if (!transformTool.active) return false;
|
|
1922
|
+
transformTool.up();
|
|
1923
|
+
return true;
|
|
1924
|
+
};
|
|
1925
|
+
(0, import_react11.useEffect)(() => {
|
|
1926
|
+
if (typeof window === "undefined") return;
|
|
1927
|
+
const onKey = (e) => {
|
|
1928
|
+
if (transformTool.key(e)) e.preventDefault();
|
|
1929
|
+
};
|
|
1930
|
+
window.addEventListener("keydown", onKey);
|
|
1931
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
1932
|
+
}, [transformTool]);
|
|
1933
|
+
(0, import_react11.useEffect)(() => {
|
|
1778
1934
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
1779
1935
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
1780
1936
|
const animId = raf(() => {
|
|
@@ -1782,12 +1938,12 @@ var ImageEditor = ({
|
|
|
1782
1938
|
});
|
|
1783
1939
|
return () => caf(animId);
|
|
1784
1940
|
}, [renderCanvas, state]);
|
|
1785
|
-
(0,
|
|
1941
|
+
(0, import_react11.useEffect)(() => {
|
|
1786
1942
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
1787
1943
|
editor.setTool("crop");
|
|
1788
1944
|
}
|
|
1789
1945
|
}, [activeTab, editor]);
|
|
1790
|
-
(0,
|
|
1946
|
+
(0, import_react11.useEffect)(() => {
|
|
1791
1947
|
const container = containerRef.current;
|
|
1792
1948
|
if (!container) return;
|
|
1793
1949
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -1823,11 +1979,12 @@ var ImageEditor = ({
|
|
|
1823
1979
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
1824
1980
|
const s = controller.getState();
|
|
1825
1981
|
return list.map((ev) => ({
|
|
1826
|
-
...(0,
|
|
1827
|
-
pressure: (0,
|
|
1982
|
+
...(0, import_image_editor12.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
1983
|
+
pressure: (0, import_image_editor12.pointerPressure)(ev)
|
|
1828
1984
|
}));
|
|
1829
1985
|
};
|
|
1830
1986
|
const handlePaintPointerDown = (e) => {
|
|
1987
|
+
if (handleTransformPointerDown(e)) return;
|
|
1831
1988
|
if (activeTab !== "paint" || e.button !== 0) return;
|
|
1832
1989
|
e.preventDefault();
|
|
1833
1990
|
try {
|
|
@@ -1838,6 +1995,7 @@ var ImageEditor = ({
|
|
|
1838
1995
|
setPaintError(paintGestureRef.current.down(first));
|
|
1839
1996
|
};
|
|
1840
1997
|
const handlePaintPointerMove = (e) => {
|
|
1998
|
+
if (handleTransformPointerMove(e)) return;
|
|
1841
1999
|
if (activeTab !== "paint") return;
|
|
1842
2000
|
const samples = paintSamples(e);
|
|
1843
2001
|
brushCursorRef.current = samples[samples.length - 1] ?? null;
|
|
@@ -1845,6 +2003,7 @@ var ImageEditor = ({
|
|
|
1845
2003
|
else void renderCanvas();
|
|
1846
2004
|
};
|
|
1847
2005
|
const handlePaintPointerUp = () => {
|
|
2006
|
+
if (handleTransformPointerUp()) return;
|
|
1848
2007
|
if (activeTab !== "paint") return;
|
|
1849
2008
|
const g = paintGestureRef.current;
|
|
1850
2009
|
if (g.active) {
|
|
@@ -1852,21 +2011,21 @@ var ImageEditor = ({
|
|
|
1852
2011
|
if (g.error) setPaintError(g.error);
|
|
1853
2012
|
}
|
|
1854
2013
|
};
|
|
1855
|
-
(0,
|
|
2014
|
+
(0, import_react11.useEffect)(() => {
|
|
1856
2015
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
1857
2016
|
const onKey = (e) => {
|
|
1858
|
-
if ((0,
|
|
2017
|
+
if ((0, import_image_editor12.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
1859
2018
|
};
|
|
1860
2019
|
window.addEventListener("keydown", onKey);
|
|
1861
2020
|
return () => window.removeEventListener("keydown", onKey);
|
|
1862
2021
|
}, [activeTab, controller]);
|
|
1863
2022
|
const handleMouseDown = (e) => {
|
|
1864
2023
|
const canvas = canvasRef.current;
|
|
1865
|
-
if (!canvas) return;
|
|
2024
|
+
if (!canvas || transformTool.active) return;
|
|
1866
2025
|
const canvasPt = getCanvasEventPoint(e);
|
|
1867
2026
|
if (activeTab === "select") {
|
|
1868
2027
|
const gesture = selectionGestureRef.current;
|
|
1869
|
-
const imgPt = (0,
|
|
2028
|
+
const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
1870
2029
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
1871
2030
|
return;
|
|
1872
2031
|
}
|
|
@@ -1877,8 +2036,8 @@ var ImageEditor = ({
|
|
|
1877
2036
|
width: state.imageDimensions.width,
|
|
1878
2037
|
height: state.imageDimensions.height
|
|
1879
2038
|
};
|
|
1880
|
-
const handle = (0,
|
|
1881
|
-
const startImgPt = (0,
|
|
2039
|
+
const handle = (0, import_image_editor12.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2040
|
+
const startImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
1882
2041
|
if (handle) {
|
|
1883
2042
|
cropDragInfoRef.current = {
|
|
1884
2043
|
handle,
|
|
@@ -1897,12 +2056,12 @@ var ImageEditor = ({
|
|
|
1897
2056
|
return;
|
|
1898
2057
|
}
|
|
1899
2058
|
if (activeTab === "annotate") {
|
|
1900
|
-
const imgPt = (0,
|
|
2059
|
+
const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
1901
2060
|
dragStartPointRef.current = imgPt;
|
|
1902
2061
|
if (state.activeTool === "select") {
|
|
1903
2062
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
1904
2063
|
const ann = state.annotations[i];
|
|
1905
|
-
if ((0,
|
|
2064
|
+
if ((0, import_image_editor12.hitTestAnnotation)(imgPt, ann)) {
|
|
1906
2065
|
editor.selectAnnotation(ann.id);
|
|
1907
2066
|
annotationDragInfoRef.current = {
|
|
1908
2067
|
annId: ann.id,
|
|
@@ -1934,11 +2093,11 @@ var ImageEditor = ({
|
|
|
1934
2093
|
};
|
|
1935
2094
|
const handleMouseMove = (e) => {
|
|
1936
2095
|
const canvas = canvasRef.current;
|
|
1937
|
-
if (!canvas) return;
|
|
2096
|
+
if (!canvas || transformTool.active) return;
|
|
1938
2097
|
const canvasPt = getCanvasEventPoint(e);
|
|
1939
2098
|
if (activeTab === "select") {
|
|
1940
2099
|
const gesture = selectionGestureRef.current;
|
|
1941
|
-
if (gesture.active && gesture.move((0,
|
|
2100
|
+
if (gesture.active && gesture.move((0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
1942
2101
|
selectionDraftRef.current = gesture.draftPath;
|
|
1943
2102
|
renderCanvas();
|
|
1944
2103
|
}
|
|
@@ -1947,7 +2106,7 @@ var ImageEditor = ({
|
|
|
1947
2106
|
if (activeTab === "crop") {
|
|
1948
2107
|
const drag = cropDragInfoRef.current;
|
|
1949
2108
|
if (drag) {
|
|
1950
|
-
const currentImgPt = (0,
|
|
2109
|
+
const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
1951
2110
|
let newCrop;
|
|
1952
2111
|
if (drag.handle === "new") {
|
|
1953
2112
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -1961,7 +2120,7 @@ var ImageEditor = ({
|
|
|
1961
2120
|
height: Math.round(Math.max(20, maxY - minY))
|
|
1962
2121
|
};
|
|
1963
2122
|
} else {
|
|
1964
|
-
newCrop = (0,
|
|
2123
|
+
newCrop = (0, import_image_editor12.calculateCropDrag)(
|
|
1965
2124
|
drag.startCrop,
|
|
1966
2125
|
drag.handle,
|
|
1967
2126
|
drag.startImgPt,
|
|
@@ -1981,15 +2140,15 @@ var ImageEditor = ({
|
|
|
1981
2140
|
width: state.imageDimensions.width,
|
|
1982
2141
|
height: state.imageDimensions.height
|
|
1983
2142
|
};
|
|
1984
|
-
const handle = (0,
|
|
1985
|
-
canvas.style.cursor = (0,
|
|
2143
|
+
const handle = (0, import_image_editor12.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2144
|
+
canvas.style.cursor = (0, import_image_editor12.getCropCursor)(handle, state.transform);
|
|
1986
2145
|
}
|
|
1987
2146
|
return;
|
|
1988
2147
|
}
|
|
1989
2148
|
if (activeTab === "annotate") {
|
|
1990
2149
|
if (annotationDragInfoRef.current) {
|
|
1991
2150
|
const drag = annotationDragInfoRef.current;
|
|
1992
|
-
const currentImgPt2 = (0,
|
|
2151
|
+
const currentImgPt2 = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
1993
2152
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
1994
2153
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
1995
2154
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -2001,10 +2160,10 @@ var ImageEditor = ({
|
|
|
2001
2160
|
const startPt = dragStartPointRef.current;
|
|
2002
2161
|
if (!startPt) {
|
|
2003
2162
|
if (state.activeTool === "select") {
|
|
2004
|
-
const imgPt = (0,
|
|
2163
|
+
const imgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2005
2164
|
let hovered = false;
|
|
2006
2165
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
2007
|
-
if ((0,
|
|
2166
|
+
if ((0, import_image_editor12.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
2008
2167
|
hovered = true;
|
|
2009
2168
|
break;
|
|
2010
2169
|
}
|
|
@@ -2015,7 +2174,7 @@ var ImageEditor = ({
|
|
|
2015
2174
|
}
|
|
2016
2175
|
return;
|
|
2017
2176
|
}
|
|
2018
|
-
const currentImgPt = (0,
|
|
2177
|
+
const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2019
2178
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2020
2179
|
currentPathRef.current.push(currentImgPt);
|
|
2021
2180
|
const draft = {
|
|
@@ -2090,12 +2249,12 @@ var ImageEditor = ({
|
|
|
2090
2249
|
};
|
|
2091
2250
|
const handleMouseUp = (e) => {
|
|
2092
2251
|
const canvas = canvasRef.current;
|
|
2093
|
-
if (!canvas) return;
|
|
2252
|
+
if (!canvas || transformTool.active) return;
|
|
2094
2253
|
const canvasPt = getCanvasEventPoint(e);
|
|
2095
2254
|
if (activeTab === "select") {
|
|
2096
2255
|
const gesture = selectionGestureRef.current;
|
|
2097
2256
|
if (gesture.active) {
|
|
2098
|
-
gesture.end((0,
|
|
2257
|
+
gesture.end((0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
2099
2258
|
selectionDraftRef.current = null;
|
|
2100
2259
|
renderCanvas();
|
|
2101
2260
|
}
|
|
@@ -2119,7 +2278,7 @@ var ImageEditor = ({
|
|
|
2119
2278
|
}
|
|
2120
2279
|
const startPt = dragStartPointRef.current;
|
|
2121
2280
|
if (startPt) {
|
|
2122
|
-
const currentImgPt = (0,
|
|
2281
|
+
const currentImgPt = (0, import_image_editor12.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2123
2282
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2124
2283
|
if (currentPathRef.current.length > 1) {
|
|
2125
2284
|
editor.addAnnotation({
|
|
@@ -2215,15 +2374,15 @@ var ImageEditor = ({
|
|
|
2215
2374
|
link.click();
|
|
2216
2375
|
}
|
|
2217
2376
|
};
|
|
2218
|
-
return /* @__PURE__ */ (0,
|
|
2377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2219
2378
|
"div",
|
|
2220
2379
|
{
|
|
2221
2380
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
2222
2381
|
style,
|
|
2223
2382
|
children: [
|
|
2224
|
-
/* @__PURE__ */ (0,
|
|
2225
|
-
/* @__PURE__ */ (0,
|
|
2226
|
-
/* @__PURE__ */ (0,
|
|
2383
|
+
/* @__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: [
|
|
2384
|
+
/* @__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: [
|
|
2385
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2227
2386
|
"button",
|
|
2228
2387
|
{
|
|
2229
2388
|
type: "button",
|
|
@@ -2235,7 +2394,7 @@ var ImageEditor = ({
|
|
|
2235
2394
|
children: "Transform & Crop"
|
|
2236
2395
|
}
|
|
2237
2396
|
),
|
|
2238
|
-
/* @__PURE__ */ (0,
|
|
2397
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2239
2398
|
"button",
|
|
2240
2399
|
{
|
|
2241
2400
|
type: "button",
|
|
@@ -2247,7 +2406,7 @@ var ImageEditor = ({
|
|
|
2247
2406
|
children: "Adjustments"
|
|
2248
2407
|
}
|
|
2249
2408
|
),
|
|
2250
|
-
/* @__PURE__ */ (0,
|
|
2409
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2251
2410
|
"button",
|
|
2252
2411
|
{
|
|
2253
2412
|
type: "button",
|
|
@@ -2259,7 +2418,7 @@ var ImageEditor = ({
|
|
|
2259
2418
|
children: "Layers"
|
|
2260
2419
|
}
|
|
2261
2420
|
),
|
|
2262
|
-
/* @__PURE__ */ (0,
|
|
2421
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2263
2422
|
"button",
|
|
2264
2423
|
{
|
|
2265
2424
|
type: "button",
|
|
@@ -2271,7 +2430,7 @@ var ImageEditor = ({
|
|
|
2271
2430
|
children: "Paint"
|
|
2272
2431
|
}
|
|
2273
2432
|
),
|
|
2274
|
-
/* @__PURE__ */ (0,
|
|
2433
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2275
2434
|
"button",
|
|
2276
2435
|
{
|
|
2277
2436
|
type: "button",
|
|
@@ -2283,7 +2442,7 @@ var ImageEditor = ({
|
|
|
2283
2442
|
children: "Select & Mask"
|
|
2284
2443
|
}
|
|
2285
2444
|
),
|
|
2286
|
-
/* @__PURE__ */ (0,
|
|
2445
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2287
2446
|
"button",
|
|
2288
2447
|
{
|
|
2289
2448
|
type: "button",
|
|
@@ -2295,7 +2454,7 @@ var ImageEditor = ({
|
|
|
2295
2454
|
children: "Annotations"
|
|
2296
2455
|
}
|
|
2297
2456
|
),
|
|
2298
|
-
/* @__PURE__ */ (0,
|
|
2457
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2299
2458
|
"button",
|
|
2300
2459
|
{
|
|
2301
2460
|
type: "button",
|
|
@@ -2307,7 +2466,7 @@ var ImageEditor = ({
|
|
|
2307
2466
|
children: "Depth Mask"
|
|
2308
2467
|
}
|
|
2309
2468
|
),
|
|
2310
|
-
/* @__PURE__ */ (0,
|
|
2469
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2311
2470
|
"button",
|
|
2312
2471
|
{
|
|
2313
2472
|
type: "button",
|
|
@@ -2317,14 +2476,14 @@ var ImageEditor = ({
|
|
|
2317
2476
|
},
|
|
2318
2477
|
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
2478
|
children: [
|
|
2320
|
-
/* @__PURE__ */ (0,
|
|
2479
|
+
/* @__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
2480
|
"AI Tools"
|
|
2322
2481
|
]
|
|
2323
2482
|
}
|
|
2324
2483
|
)
|
|
2325
2484
|
] }),
|
|
2326
|
-
/* @__PURE__ */ (0,
|
|
2327
|
-
/* @__PURE__ */ (0,
|
|
2485
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2486
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2328
2487
|
"button",
|
|
2329
2488
|
{
|
|
2330
2489
|
type: "button",
|
|
@@ -2335,7 +2494,7 @@ var ImageEditor = ({
|
|
|
2335
2494
|
children: "\u21A9"
|
|
2336
2495
|
}
|
|
2337
2496
|
),
|
|
2338
|
-
/* @__PURE__ */ (0,
|
|
2497
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2339
2498
|
"button",
|
|
2340
2499
|
{
|
|
2341
2500
|
type: "button",
|
|
@@ -2346,7 +2505,7 @@ var ImageEditor = ({
|
|
|
2346
2505
|
children: "\u21AA"
|
|
2347
2506
|
}
|
|
2348
2507
|
),
|
|
2349
|
-
/* @__PURE__ */ (0,
|
|
2508
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2350
2509
|
"button",
|
|
2351
2510
|
{
|
|
2352
2511
|
type: "button",
|
|
@@ -2355,8 +2514,8 @@ var ImageEditor = ({
|
|
|
2355
2514
|
children: "Reset"
|
|
2356
2515
|
}
|
|
2357
2516
|
),
|
|
2358
|
-
/* @__PURE__ */ (0,
|
|
2359
|
-
/* @__PURE__ */ (0,
|
|
2517
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
2518
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2360
2519
|
"button",
|
|
2361
2520
|
{
|
|
2362
2521
|
type: "button",
|
|
@@ -2366,11 +2525,11 @@ var ImageEditor = ({
|
|
|
2366
2525
|
children: "-"
|
|
2367
2526
|
}
|
|
2368
2527
|
),
|
|
2369
|
-
/* @__PURE__ */ (0,
|
|
2528
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
2370
2529
|
Math.round(state.zoom * 100),
|
|
2371
2530
|
"%"
|
|
2372
2531
|
] }),
|
|
2373
|
-
/* @__PURE__ */ (0,
|
|
2532
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2374
2533
|
"button",
|
|
2375
2534
|
{
|
|
2376
2535
|
type: "button",
|
|
@@ -2380,8 +2539,8 @@ var ImageEditor = ({
|
|
|
2380
2539
|
children: "+"
|
|
2381
2540
|
}
|
|
2382
2541
|
),
|
|
2383
|
-
/* @__PURE__ */ (0,
|
|
2384
|
-
/* @__PURE__ */ (0,
|
|
2542
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
2543
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2385
2544
|
"button",
|
|
2386
2545
|
{
|
|
2387
2546
|
type: "button",
|
|
@@ -2392,7 +2551,7 @@ var ImageEditor = ({
|
|
|
2392
2551
|
children: "Hold Compare"
|
|
2393
2552
|
}
|
|
2394
2553
|
),
|
|
2395
|
-
/* @__PURE__ */ (0,
|
|
2554
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2396
2555
|
"button",
|
|
2397
2556
|
{
|
|
2398
2557
|
type: "button",
|
|
@@ -2403,13 +2562,15 @@ var ImageEditor = ({
|
|
|
2403
2562
|
)
|
|
2404
2563
|
] })
|
|
2405
2564
|
] }),
|
|
2406
|
-
/* @__PURE__ */ (0,
|
|
2407
|
-
|
|
2565
|
+
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" }),
|
|
2566
|
+
!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 }),
|
|
2567
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
2568
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2408
2569
|
"div",
|
|
2409
2570
|
{
|
|
2410
2571
|
ref: containerRef,
|
|
2411
2572
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
2412
|
-
children: /* @__PURE__ */ (0,
|
|
2573
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2413
2574
|
"canvas",
|
|
2414
2575
|
{
|
|
2415
2576
|
ref: canvasRef,
|
|
@@ -2422,16 +2583,17 @@ var ImageEditor = ({
|
|
|
2422
2583
|
onPointerUp: handlePaintPointerUp,
|
|
2423
2584
|
onPointerCancel: () => paintGestureRef.current?.cancel(),
|
|
2424
2585
|
"data-testid": "image-editor-canvas",
|
|
2425
|
-
|
|
2586
|
+
style: transformTool.active ? { cursor: transformCursor } : void 0,
|
|
2587
|
+
className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : ""}`
|
|
2426
2588
|
}
|
|
2427
2589
|
)
|
|
2428
2590
|
}
|
|
2429
2591
|
),
|
|
2430
|
-
/* @__PURE__ */ (0,
|
|
2431
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
2432
|
-
/* @__PURE__ */ (0,
|
|
2433
|
-
/* @__PURE__ */ (0,
|
|
2434
|
-
/* @__PURE__ */ (0,
|
|
2592
|
+
/* @__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: [
|
|
2593
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
2594
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
2595
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
2596
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2435
2597
|
"button",
|
|
2436
2598
|
{
|
|
2437
2599
|
type: "button",
|
|
@@ -2443,7 +2605,7 @@ var ImageEditor = ({
|
|
|
2443
2605
|
children: "Freeform"
|
|
2444
2606
|
}
|
|
2445
2607
|
),
|
|
2446
|
-
/* @__PURE__ */ (0,
|
|
2608
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2447
2609
|
"button",
|
|
2448
2610
|
{
|
|
2449
2611
|
type: "button",
|
|
@@ -2455,7 +2617,7 @@ var ImageEditor = ({
|
|
|
2455
2617
|
children: "1:1 Square"
|
|
2456
2618
|
}
|
|
2457
2619
|
),
|
|
2458
|
-
/* @__PURE__ */ (0,
|
|
2620
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2459
2621
|
"button",
|
|
2460
2622
|
{
|
|
2461
2623
|
type: "button",
|
|
@@ -2467,7 +2629,7 @@ var ImageEditor = ({
|
|
|
2467
2629
|
children: "4:3 Standard"
|
|
2468
2630
|
}
|
|
2469
2631
|
),
|
|
2470
|
-
/* @__PURE__ */ (0,
|
|
2632
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2471
2633
|
"button",
|
|
2472
2634
|
{
|
|
2473
2635
|
type: "button",
|
|
@@ -2479,7 +2641,7 @@ var ImageEditor = ({
|
|
|
2479
2641
|
children: "16:9 Wide"
|
|
2480
2642
|
}
|
|
2481
2643
|
),
|
|
2482
|
-
/* @__PURE__ */ (0,
|
|
2644
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2483
2645
|
"button",
|
|
2484
2646
|
{
|
|
2485
2647
|
type: "button",
|
|
@@ -2491,7 +2653,7 @@ var ImageEditor = ({
|
|
|
2491
2653
|
children: "3:2 Photo"
|
|
2492
2654
|
}
|
|
2493
2655
|
),
|
|
2494
|
-
/* @__PURE__ */ (0,
|
|
2656
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2495
2657
|
"button",
|
|
2496
2658
|
{
|
|
2497
2659
|
type: "button",
|
|
@@ -2504,10 +2666,10 @@ var ImageEditor = ({
|
|
|
2504
2666
|
}
|
|
2505
2667
|
)
|
|
2506
2668
|
] }),
|
|
2507
|
-
/* @__PURE__ */ (0,
|
|
2508
|
-
/* @__PURE__ */ (0,
|
|
2509
|
-
/* @__PURE__ */ (0,
|
|
2510
|
-
/* @__PURE__ */ (0,
|
|
2669
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
2670
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
2671
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
2672
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2511
2673
|
"button",
|
|
2512
2674
|
{
|
|
2513
2675
|
type: "button",
|
|
@@ -2516,7 +2678,7 @@ var ImageEditor = ({
|
|
|
2516
2678
|
children: "Rotate -90\xB0"
|
|
2517
2679
|
}
|
|
2518
2680
|
),
|
|
2519
|
-
/* @__PURE__ */ (0,
|
|
2681
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2520
2682
|
"button",
|
|
2521
2683
|
{
|
|
2522
2684
|
type: "button",
|
|
@@ -2525,7 +2687,7 @@ var ImageEditor = ({
|
|
|
2525
2687
|
children: "Rotate +90\xB0"
|
|
2526
2688
|
}
|
|
2527
2689
|
),
|
|
2528
|
-
/* @__PURE__ */ (0,
|
|
2690
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2529
2691
|
"button",
|
|
2530
2692
|
{
|
|
2531
2693
|
type: "button",
|
|
@@ -2534,7 +2696,7 @@ var ImageEditor = ({
|
|
|
2534
2696
|
children: "Flip Horizontal"
|
|
2535
2697
|
}
|
|
2536
2698
|
),
|
|
2537
|
-
/* @__PURE__ */ (0,
|
|
2699
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2538
2700
|
"button",
|
|
2539
2701
|
{
|
|
2540
2702
|
type: "button",
|
|
@@ -2545,10 +2707,10 @@ var ImageEditor = ({
|
|
|
2545
2707
|
)
|
|
2546
2708
|
] })
|
|
2547
2709
|
] }),
|
|
2548
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2550
|
-
/* @__PURE__ */ (0,
|
|
2551
|
-
/* @__PURE__ */ (0,
|
|
2710
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
2711
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2712
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
2713
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2552
2714
|
"button",
|
|
2553
2715
|
{
|
|
2554
2716
|
type: "button",
|
|
@@ -2558,25 +2720,25 @@ var ImageEditor = ({
|
|
|
2558
2720
|
}
|
|
2559
2721
|
)
|
|
2560
2722
|
] }),
|
|
2561
|
-
/* @__PURE__ */ (0,
|
|
2562
|
-
|
|
2563
|
-
/* @__PURE__ */ (0,
|
|
2723
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Histogram, { histogram: editor.histogram }),
|
|
2724
|
+
import_image_editor12.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react11.default.Fragment, { children: [
|
|
2725
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2564
2726
|
ControlSlider,
|
|
2565
2727
|
{
|
|
2566
2728
|
spec,
|
|
2567
|
-
value: (0,
|
|
2729
|
+
value: (0, import_image_editor12.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
2568
2730
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
2569
2731
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
2570
2732
|
}
|
|
2571
2733
|
),
|
|
2572
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
2734
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2573
2735
|
"div",
|
|
2574
2736
|
{
|
|
2575
2737
|
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
2738
|
"data-testid": "image-editor-process-notice",
|
|
2577
2739
|
children: [
|
|
2578
|
-
/* @__PURE__ */ (0,
|
|
2579
|
-
/* @__PURE__ */ (0,
|
|
2740
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
2741
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2580
2742
|
"button",
|
|
2581
2743
|
{
|
|
2582
2744
|
type: "button",
|
|
@@ -2589,7 +2751,7 @@ var ImageEditor = ({
|
|
|
2589
2751
|
}
|
|
2590
2752
|
)
|
|
2591
2753
|
] }, spec.id)),
|
|
2592
|
-
/* @__PURE__ */ (0,
|
|
2754
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2593
2755
|
AdjustmentLayersPanel,
|
|
2594
2756
|
{
|
|
2595
2757
|
controller,
|
|
@@ -2598,19 +2760,41 @@ var ImageEditor = ({
|
|
|
2598
2760
|
}
|
|
2599
2761
|
) })
|
|
2600
2762
|
] }),
|
|
2601
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
2602
|
-
/* @__PURE__ */ (0,
|
|
2603
|
-
/* @__PURE__ */ (0,
|
|
2763
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
2764
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
2765
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2766
|
+
"button",
|
|
2767
|
+
{
|
|
2768
|
+
type: "button",
|
|
2769
|
+
title: "Edit \u203A Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer",
|
|
2770
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
|
|
2771
|
+
disabled: transformTool.active,
|
|
2772
|
+
onClick: () => transformTool.begin(),
|
|
2773
|
+
children: "Free Transform"
|
|
2774
|
+
}
|
|
2775
|
+
),
|
|
2776
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LayersPanel, { controller })
|
|
2604
2777
|
] }),
|
|
2605
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
2606
|
-
/* @__PURE__ */ (0,
|
|
2607
|
-
/* @__PURE__ */ (0,
|
|
2608
|
-
|
|
2609
|
-
|
|
2778
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
2779
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
2780
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(BrushOptionsBar, { controller }),
|
|
2781
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2782
|
+
"button",
|
|
2783
|
+
{
|
|
2784
|
+
type: "button",
|
|
2785
|
+
title: "Edit \u203A Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer",
|
|
2786
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start",
|
|
2787
|
+
disabled: transformTool.active,
|
|
2788
|
+
onClick: () => transformTool.begin(),
|
|
2789
|
+
children: "Free Transform"
|
|
2790
|
+
}
|
|
2791
|
+
),
|
|
2792
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
2793
|
+
/* @__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
2794
|
] }),
|
|
2611
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
2612
|
-
/* @__PURE__ */ (0,
|
|
2613
|
-
/* @__PURE__ */ (0,
|
|
2795
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
2796
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
2797
|
+
/* @__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
2798
|
"button",
|
|
2615
2799
|
{
|
|
2616
2800
|
type: "button",
|
|
@@ -2620,9 +2804,9 @@ var ImageEditor = ({
|
|
|
2620
2804
|
},
|
|
2621
2805
|
t
|
|
2622
2806
|
)) }),
|
|
2623
|
-
/* @__PURE__ */ (0,
|
|
2624
|
-
/* @__PURE__ */ (0,
|
|
2625
|
-
/* @__PURE__ */ (0,
|
|
2807
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
2808
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
2809
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2626
2810
|
"input",
|
|
2627
2811
|
{
|
|
2628
2812
|
type: "color",
|
|
@@ -2631,15 +2815,15 @@ var ImageEditor = ({
|
|
|
2631
2815
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
2632
2816
|
}
|
|
2633
2817
|
),
|
|
2634
|
-
/* @__PURE__ */ (0,
|
|
2635
|
-
/* @__PURE__ */ (0,
|
|
2636
|
-
/* @__PURE__ */ (0,
|
|
2637
|
-
/* @__PURE__ */ (0,
|
|
2818
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
2819
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
2820
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Width:" }),
|
|
2821
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-mono", children: [
|
|
2638
2822
|
strokeWidth,
|
|
2639
2823
|
"px"
|
|
2640
2824
|
] })
|
|
2641
2825
|
] }),
|
|
2642
|
-
/* @__PURE__ */ (0,
|
|
2826
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2643
2827
|
"input",
|
|
2644
2828
|
{
|
|
2645
2829
|
type: "range",
|
|
@@ -2652,10 +2836,10 @@ var ImageEditor = ({
|
|
|
2652
2836
|
)
|
|
2653
2837
|
] })
|
|
2654
2838
|
] }),
|
|
2655
|
-
/* @__PURE__ */ (0,
|
|
2656
|
-
/* @__PURE__ */ (0,
|
|
2657
|
-
/* @__PURE__ */ (0,
|
|
2658
|
-
/* @__PURE__ */ (0,
|
|
2839
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
2840
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
2841
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-2", children: [
|
|
2842
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2659
2843
|
"input",
|
|
2660
2844
|
{
|
|
2661
2845
|
type: "text",
|
|
@@ -2666,7 +2850,7 @@ var ImageEditor = ({
|
|
|
2666
2850
|
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
2851
|
}
|
|
2668
2852
|
),
|
|
2669
|
-
/* @__PURE__ */ (0,
|
|
2853
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2670
2854
|
"button",
|
|
2671
2855
|
{
|
|
2672
2856
|
type: "button",
|
|
@@ -2676,14 +2860,14 @@ var ImageEditor = ({
|
|
|
2676
2860
|
}
|
|
2677
2861
|
)
|
|
2678
2862
|
] }),
|
|
2679
|
-
/* @__PURE__ */ (0,
|
|
2680
|
-
/* @__PURE__ */ (0,
|
|
2681
|
-
/* @__PURE__ */ (0,
|
|
2863
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
2864
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Font Size:" }),
|
|
2865
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "font-mono", children: [
|
|
2682
2866
|
fontSize,
|
|
2683
2867
|
"px"
|
|
2684
2868
|
] })
|
|
2685
2869
|
] }),
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2870
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2687
2871
|
"input",
|
|
2688
2872
|
{
|
|
2689
2873
|
type: "range",
|
|
@@ -2694,14 +2878,14 @@ var ImageEditor = ({
|
|
|
2694
2878
|
className: "w-full accent-indigo-500"
|
|
2695
2879
|
}
|
|
2696
2880
|
),
|
|
2697
|
-
/* @__PURE__ */ (0,
|
|
2698
|
-
/* @__PURE__ */ (0,
|
|
2699
|
-
/* @__PURE__ */ (0,
|
|
2881
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
2882
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2883
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-slate-400", children: [
|
|
2700
2884
|
"Layers (",
|
|
2701
2885
|
state.annotations.length,
|
|
2702
2886
|
")"
|
|
2703
2887
|
] }),
|
|
2704
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
2888
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2705
2889
|
"button",
|
|
2706
2890
|
{
|
|
2707
2891
|
type: "button",
|
|
@@ -2710,7 +2894,7 @@ var ImageEditor = ({
|
|
|
2710
2894
|
children: "Delete Selected"
|
|
2711
2895
|
}
|
|
2712
2896
|
),
|
|
2713
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
2897
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2714
2898
|
"button",
|
|
2715
2899
|
{
|
|
2716
2900
|
type: "button",
|
|
@@ -2721,10 +2905,10 @@ var ImageEditor = ({
|
|
|
2721
2905
|
)
|
|
2722
2906
|
] })
|
|
2723
2907
|
] }),
|
|
2724
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
2725
|
-
/* @__PURE__ */ (0,
|
|
2726
|
-
/* @__PURE__ */ (0,
|
|
2727
|
-
/* @__PURE__ */ (0,
|
|
2908
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
2909
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
2910
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
2911
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2728
2912
|
"button",
|
|
2729
2913
|
{
|
|
2730
2914
|
type: "button",
|
|
@@ -2734,8 +2918,8 @@ var ImageEditor = ({
|
|
|
2734
2918
|
}
|
|
2735
2919
|
)
|
|
2736
2920
|
] }),
|
|
2737
|
-
/* @__PURE__ */ (0,
|
|
2738
|
-
/* @__PURE__ */ (0,
|
|
2921
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
2922
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2739
2923
|
"input",
|
|
2740
2924
|
{
|
|
2741
2925
|
type: "checkbox",
|
|
@@ -2744,12 +2928,12 @@ var ImageEditor = ({
|
|
|
2744
2928
|
className: "rounded accent-indigo-500"
|
|
2745
2929
|
}
|
|
2746
2930
|
),
|
|
2747
|
-
/* @__PURE__ */ (0,
|
|
2931
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
2748
2932
|
] }),
|
|
2749
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
2750
|
-
/* @__PURE__ */ (0,
|
|
2751
|
-
/* @__PURE__ */ (0,
|
|
2752
|
-
/* @__PURE__ */ (0,
|
|
2933
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2934
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
2935
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
2936
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2753
2937
|
"input",
|
|
2754
2938
|
{
|
|
2755
2939
|
type: "text",
|
|
@@ -2760,8 +2944,8 @@ var ImageEditor = ({
|
|
|
2760
2944
|
}
|
|
2761
2945
|
)
|
|
2762
2946
|
] }),
|
|
2763
|
-
/* @__PURE__ */ (0,
|
|
2764
|
-
/* @__PURE__ */ (0,
|
|
2947
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-2", children: [
|
|
2948
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2765
2949
|
"button",
|
|
2766
2950
|
{
|
|
2767
2951
|
type: "button",
|
|
@@ -2770,7 +2954,7 @@ var ImageEditor = ({
|
|
|
2770
2954
|
children: "Threshold Mode"
|
|
2771
2955
|
}
|
|
2772
2956
|
),
|
|
2773
|
-
/* @__PURE__ */ (0,
|
|
2957
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2774
2958
|
"button",
|
|
2775
2959
|
{
|
|
2776
2960
|
type: "button",
|
|
@@ -2780,12 +2964,12 @@ var ImageEditor = ({
|
|
|
2780
2964
|
}
|
|
2781
2965
|
)
|
|
2782
2966
|
] }),
|
|
2783
|
-
/* @__PURE__ */ (0,
|
|
2784
|
-
/* @__PURE__ */ (0,
|
|
2785
|
-
/* @__PURE__ */ (0,
|
|
2786
|
-
/* @__PURE__ */ (0,
|
|
2967
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
2968
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
2969
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
2970
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
2787
2971
|
] }),
|
|
2788
|
-
/* @__PURE__ */ (0,
|
|
2972
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2789
2973
|
"input",
|
|
2790
2974
|
{
|
|
2791
2975
|
type: "range",
|
|
@@ -2799,12 +2983,12 @@ var ImageEditor = ({
|
|
|
2799
2983
|
}
|
|
2800
2984
|
)
|
|
2801
2985
|
] }),
|
|
2802
|
-
/* @__PURE__ */ (0,
|
|
2803
|
-
/* @__PURE__ */ (0,
|
|
2804
|
-
/* @__PURE__ */ (0,
|
|
2805
|
-
/* @__PURE__ */ (0,
|
|
2986
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
2987
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
2988
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
2989
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
2806
2990
|
] }),
|
|
2807
|
-
/* @__PURE__ */ (0,
|
|
2991
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2808
2992
|
"input",
|
|
2809
2993
|
{
|
|
2810
2994
|
type: "range",
|
|
@@ -2818,12 +3002,12 @@ var ImageEditor = ({
|
|
|
2818
3002
|
}
|
|
2819
3003
|
)
|
|
2820
3004
|
] }),
|
|
2821
|
-
/* @__PURE__ */ (0,
|
|
2822
|
-
/* @__PURE__ */ (0,
|
|
2823
|
-
/* @__PURE__ */ (0,
|
|
2824
|
-
/* @__PURE__ */ (0,
|
|
3005
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
|
|
3006
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3007
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Softness:" }),
|
|
3008
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
2825
3009
|
] }),
|
|
2826
|
-
/* @__PURE__ */ (0,
|
|
3010
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2827
3011
|
"input",
|
|
2828
3012
|
{
|
|
2829
3013
|
type: "range",
|
|
@@ -2835,8 +3019,8 @@ var ImageEditor = ({
|
|
|
2835
3019
|
}
|
|
2836
3020
|
)
|
|
2837
3021
|
] }),
|
|
2838
|
-
/* @__PURE__ */ (0,
|
|
2839
|
-
/* @__PURE__ */ (0,
|
|
3022
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
3023
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2840
3024
|
"input",
|
|
2841
3025
|
{
|
|
2842
3026
|
type: "checkbox",
|
|
@@ -2845,12 +3029,12 @@ var ImageEditor = ({
|
|
|
2845
3029
|
className: "rounded accent-indigo-500"
|
|
2846
3030
|
}
|
|
2847
3031
|
),
|
|
2848
|
-
/* @__PURE__ */ (0,
|
|
3032
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Invert Mask" })
|
|
2849
3033
|
] })
|
|
2850
3034
|
] })
|
|
2851
3035
|
] }),
|
|
2852
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
2853
|
-
/* @__PURE__ */ (0,
|
|
3036
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3037
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2854
3038
|
SelectionOptionsBar,
|
|
2855
3039
|
{
|
|
2856
3040
|
controller,
|
|
@@ -2860,13 +3044,37 @@ var ImageEditor = ({
|
|
|
2860
3044
|
quickMask: Boolean(state.quickMask)
|
|
2861
3045
|
}
|
|
2862
3046
|
),
|
|
2863
|
-
selectionError && /* @__PURE__ */ (0,
|
|
2864
|
-
/* @__PURE__ */ (0,
|
|
3047
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
3048
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex gap-1", children: [
|
|
3049
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3050
|
+
"button",
|
|
3051
|
+
{
|
|
3052
|
+
type: "button",
|
|
3053
|
+
title: "Select \u203A Transform Selection: the outline only",
|
|
3054
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
|
|
3055
|
+
disabled: transformTool.active,
|
|
3056
|
+
onClick: () => transformTool.begin({ content: "selection-outline" }),
|
|
3057
|
+
children: "Transform Selection"
|
|
3058
|
+
}
|
|
3059
|
+
),
|
|
3060
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3061
|
+
"button",
|
|
3062
|
+
{
|
|
3063
|
+
type: "button",
|
|
3064
|
+
title: "Edit \u203A Free Transform: the selected pixels of the active layer",
|
|
3065
|
+
className: "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40",
|
|
3066
|
+
disabled: transformTool.active,
|
|
3067
|
+
onClick: () => transformTool.begin({ content: "selection" }),
|
|
3068
|
+
children: "Free Transform Pixels"
|
|
3069
|
+
}
|
|
3070
|
+
)
|
|
3071
|
+
] }),
|
|
3072
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
2865
3073
|
] }),
|
|
2866
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
2867
|
-
/* @__PURE__ */ (0,
|
|
2868
|
-
/* @__PURE__ */ (0,
|
|
2869
|
-
/* @__PURE__ */ (0,
|
|
3074
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3075
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
3076
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Results go to" }),
|
|
3077
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2870
3078
|
"select",
|
|
2871
3079
|
{
|
|
2872
3080
|
"aria-label": "AI result target",
|
|
@@ -2874,54 +3082,54 @@ var ImageEditor = ({
|
|
|
2874
3082
|
onChange: (e) => setAiTarget(e.target.value),
|
|
2875
3083
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
2876
3084
|
children: [
|
|
2877
|
-
/* @__PURE__ */ (0,
|
|
2878
|
-
/* @__PURE__ */ (0,
|
|
2879
|
-
/* @__PURE__ */ (0,
|
|
3085
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
3086
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
3087
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "replace", children: "Replace image" })
|
|
2880
3088
|
]
|
|
2881
3089
|
}
|
|
2882
3090
|
)
|
|
2883
3091
|
] }),
|
|
2884
|
-
/* @__PURE__ */ (0,
|
|
2885
|
-
/* @__PURE__ */ (0,
|
|
2886
|
-
/* @__PURE__ */ (0,
|
|
2887
|
-
/* @__PURE__ */ (0,
|
|
3092
|
+
/* @__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: [
|
|
3093
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3094
|
+
/* @__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: [
|
|
3095
|
+
/* @__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
3096
|
"Background Removal"
|
|
2889
3097
|
] }),
|
|
2890
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
3098
|
+
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
3099
|
] }),
|
|
2892
|
-
/* @__PURE__ */ (0,
|
|
2893
|
-
/* @__PURE__ */ (0,
|
|
3100
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
3101
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2894
3102
|
"button",
|
|
2895
3103
|
{
|
|
2896
3104
|
type: "button",
|
|
2897
3105
|
onClick: handleRemoveBackground,
|
|
2898
3106
|
disabled: isRemovingBg || isInpainting,
|
|
2899
3107
|
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,
|
|
3108
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3109
|
+
/* @__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
3110
|
"Removing Background..."
|
|
2903
|
-
] }) : /* @__PURE__ */ (0,
|
|
2904
|
-
/* @__PURE__ */ (0,
|
|
3111
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3112
|
+
/* @__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
3113
|
"Remove Background"
|
|
2906
3114
|
] })
|
|
2907
3115
|
}
|
|
2908
3116
|
)
|
|
2909
3117
|
] }),
|
|
2910
|
-
/* @__PURE__ */ (0,
|
|
2911
|
-
/* @__PURE__ */ (0,
|
|
2912
|
-
/* @__PURE__ */ (0,
|
|
2913
|
-
/* @__PURE__ */ (0,
|
|
2914
|
-
/* @__PURE__ */ (0,
|
|
2915
|
-
/* @__PURE__ */ (0,
|
|
3118
|
+
/* @__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: [
|
|
3119
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3120
|
+
/* @__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: [
|
|
3121
|
+
/* @__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: [
|
|
3122
|
+
/* @__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" }),
|
|
3123
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m14 7 3 3" })
|
|
2916
3124
|
] }),
|
|
2917
3125
|
"Generative Inpainting"
|
|
2918
3126
|
] }),
|
|
2919
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
3127
|
+
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
3128
|
] }),
|
|
2921
|
-
/* @__PURE__ */ (0,
|
|
2922
|
-
/* @__PURE__ */ (0,
|
|
2923
|
-
/* @__PURE__ */ (0,
|
|
2924
|
-
/* @__PURE__ */ (0,
|
|
3129
|
+
/* @__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." }),
|
|
3130
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3131
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
3132
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2925
3133
|
"textarea",
|
|
2926
3134
|
{
|
|
2927
3135
|
id: "ai-inpaint-prompt-react",
|
|
@@ -2933,10 +3141,10 @@ var ImageEditor = ({
|
|
|
2933
3141
|
}
|
|
2934
3142
|
)
|
|
2935
3143
|
] }),
|
|
2936
|
-
/* @__PURE__ */ (0,
|
|
2937
|
-
/* @__PURE__ */ (0,
|
|
2938
|
-
/* @__PURE__ */ (0,
|
|
2939
|
-
/* @__PURE__ */ (0,
|
|
3144
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3145
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
3146
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
3147
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2940
3148
|
"button",
|
|
2941
3149
|
{
|
|
2942
3150
|
type: "button",
|
|
@@ -2949,7 +3157,7 @@ var ImageEditor = ({
|
|
|
2949
3157
|
]
|
|
2950
3158
|
}
|
|
2951
3159
|
),
|
|
2952
|
-
/* @__PURE__ */ (0,
|
|
3160
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2953
3161
|
"button",
|
|
2954
3162
|
{
|
|
2955
3163
|
type: "button",
|
|
@@ -2964,25 +3172,25 @@ var ImageEditor = ({
|
|
|
2964
3172
|
)
|
|
2965
3173
|
] })
|
|
2966
3174
|
] }),
|
|
2967
|
-
/* @__PURE__ */ (0,
|
|
3175
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2968
3176
|
"button",
|
|
2969
3177
|
{
|
|
2970
3178
|
type: "button",
|
|
2971
3179
|
onClick: handleInpaint,
|
|
2972
3180
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
2973
3181
|
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,
|
|
3182
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3183
|
+
/* @__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
3184
|
"Generating Inpaint..."
|
|
2977
|
-
] }) : /* @__PURE__ */ (0,
|
|
2978
|
-
/* @__PURE__ */ (0,
|
|
3185
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3186
|
+
/* @__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
3187
|
"Apply Inpainting"
|
|
2980
3188
|
] })
|
|
2981
3189
|
}
|
|
2982
3190
|
)
|
|
2983
3191
|
] }),
|
|
2984
|
-
aiError && /* @__PURE__ */ (0,
|
|
2985
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
3192
|
+
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 }),
|
|
3193
|
+
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
3194
|
] })
|
|
2987
3195
|
] })
|
|
2988
3196
|
] })
|
|
@@ -2996,6 +3204,7 @@ var ImageEditor = ({
|
|
|
2996
3204
|
BrushOptionsBar,
|
|
2997
3205
|
ControlSlider,
|
|
2998
3206
|
CurvesEditor,
|
|
3207
|
+
FreeTransformOptionsBar,
|
|
2999
3208
|
Histogram,
|
|
3000
3209
|
ImageEditor,
|
|
3001
3210
|
LayerEffectsPanel,
|