@pixerate/editor-react 0.72.0 → 0.74.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-YAFNCBDA.js → chunk-LWMUV5TC.js} +477 -377
- package/dist/chunk-LWMUV5TC.js.map +1 -0
- package/dist/image-editor/index.cjs +540 -440
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +12 -1
- package/dist/image-editor/index.d.ts +12 -1
- package/dist/image-editor/index.js +3 -1
- package/dist/index.cjs +969 -869
- 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/dist/vector/index.cjs +910 -175
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +67 -3
- package/dist/vector/index.d.ts +67 -3
- package/dist/vector/index.js +915 -164
- package/dist/vector/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-YAFNCBDA.js.map +0 -1
|
@@ -32,6 +32,7 @@ var image_editor_exports = {};
|
|
|
32
32
|
__export(image_editor_exports, {
|
|
33
33
|
AdjustmentLayersPanel: () => AdjustmentLayersPanel,
|
|
34
34
|
BrushOptionsBar: () => BrushOptionsBar,
|
|
35
|
+
ColorProfilePanel: () => ColorProfilePanel,
|
|
35
36
|
ControlSlider: () => ControlSlider,
|
|
36
37
|
CurvesEditor: () => CurvesEditor,
|
|
37
38
|
FreeTransformOptionsBar: () => FreeTransformOptionsBar,
|
|
@@ -207,8 +208,8 @@ function useImageEditor(options = {}) {
|
|
|
207
208
|
}
|
|
208
209
|
|
|
209
210
|
// src/image-editor/ImageEditor.tsx
|
|
210
|
-
var
|
|
211
|
-
var
|
|
211
|
+
var import_react14 = __toESM(require("react"), 1);
|
|
212
|
+
var import_image_editor15 = require("@pixerate/editor/image-editor");
|
|
212
213
|
|
|
213
214
|
// src/image-editor/ControlSlider.tsx
|
|
214
215
|
var import_image_editor2 = require("@pixerate/editor/image-editor");
|
|
@@ -943,6 +944,17 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
943
944
|
children: "\u22EF"
|
|
944
945
|
}
|
|
945
946
|
),
|
|
947
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
948
|
+
"select",
|
|
949
|
+
{
|
|
950
|
+
"aria-label": "Bits per channel",
|
|
951
|
+
title: "Image \u203A Mode: bits per channel",
|
|
952
|
+
className: "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200",
|
|
953
|
+
value: controller.bitDepth,
|
|
954
|
+
onChange: (e) => attempt(() => controller.setBitDepth(Number(e.target.value))),
|
|
955
|
+
children: import_image_editor7.BIT_DEPTH_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: o.depth, title: o.title, children: o.label }, o.depth))
|
|
956
|
+
}
|
|
957
|
+
),
|
|
946
958
|
psd && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
947
959
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: iconButton, onClick: () => fileInput.current?.click(), children: "Open PSD\u2026" }),
|
|
948
960
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: iconButton, onClick: () => psdTask(async () => (await (0, import_image_editor7.downloadPsd)(controller, psdFileName)).warnings), children: "Export PSD" }),
|
|
@@ -1445,10 +1457,95 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1445
1457
|
] });
|
|
1446
1458
|
};
|
|
1447
1459
|
|
|
1448
|
-
// src/image-editor/
|
|
1460
|
+
// src/image-editor/ColorProfilePanel.tsx
|
|
1449
1461
|
var import_react8 = require("react");
|
|
1450
1462
|
var import_image_editor9 = require("@pixerate/editor/image-editor");
|
|
1451
1463
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1464
|
+
var chip2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white";
|
|
1465
|
+
var select = "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200";
|
|
1466
|
+
var ColorProfilePanel = ({ controller, className }) => {
|
|
1467
|
+
const [, setTick] = (0, import_react8.useState)(0);
|
|
1468
|
+
(0, import_react8.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1469
|
+
const [target, setTarget] = (0, import_react8.useState)("display-p3");
|
|
1470
|
+
const [intent, setIntent] = (0, import_react8.useState)("relative");
|
|
1471
|
+
const [bpc, setBpc] = (0, import_react8.useState)(true);
|
|
1472
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
1473
|
+
const view = (0, import_image_editor9.colorPanelView)(controller);
|
|
1474
|
+
const attempt = (fn) => {
|
|
1475
|
+
try {
|
|
1476
|
+
setError(null);
|
|
1477
|
+
fn();
|
|
1478
|
+
} catch (err) {
|
|
1479
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
1480
|
+
}
|
|
1481
|
+
};
|
|
1482
|
+
const proofWith = (patch) => {
|
|
1483
|
+
const cur = view.proof;
|
|
1484
|
+
const id = patch.id ?? cur?.id ?? "coated-cmyk";
|
|
1485
|
+
attempt(
|
|
1486
|
+
() => controller.setProofSetup({
|
|
1487
|
+
profile: id,
|
|
1488
|
+
intent: patch.intent ?? cur?.intent ?? "relative",
|
|
1489
|
+
simulatePaper: patch.simulatePaper ?? cur?.simulatePaper ?? false,
|
|
1490
|
+
gamutWarning: patch.gamutWarning ?? cur?.gamutWarning ?? false
|
|
1491
|
+
})
|
|
1492
|
+
);
|
|
1493
|
+
};
|
|
1494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "color-profile-panel", children: [
|
|
1495
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1496
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-slate-400", children: "Profile" }),
|
|
1497
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "data-testid": "color-profile-name", children: view.profileName })
|
|
1498
|
+
] }),
|
|
1499
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Colour mode", children: [
|
|
1500
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-slate-400", children: "Mode" }),
|
|
1501
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("select", { "aria-label": "Colour mode", className: select, value: view.mode, onChange: (e) => attempt(() => controller.setColorMode(e.target.value)), children: import_image_editor9.COLOR_MODE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
|
|
1502
|
+
view.cmykProfileName && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-slate-400", children: view.cmykProfileName })
|
|
1503
|
+
] }),
|
|
1504
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Assign or convert", children: [
|
|
1505
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("select", { "aria-label": "Target profile", className: select, value: target, onChange: (e) => setTarget(e.target.value), children: import_image_editor9.WORKING_SPACE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
|
|
1506
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("select", { "aria-label": "Rendering intent", className: select, value: intent, onChange: (e) => setIntent(e.target.value), children: import_image_editor9.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
|
|
1507
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1508
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", "aria-label": "Black point compensation", checked: bpc, onChange: (e) => setBpc(e.target.checked), className: "accent-indigo-500" }),
|
|
1509
|
+
"BPC"
|
|
1510
|
+
] }),
|
|
1511
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Assign Profile: keep the numbers", onClick: () => attempt(() => controller.assignProfile(target)), children: "Assign" }),
|
|
1512
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Convert to Profile: keep the look", onClick: () => attempt(() => controller.convertToProfile(target, { intent, bpc })), children: "Convert" })
|
|
1513
|
+
] }),
|
|
1514
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-slate-400", children: "Proof" }),
|
|
1516
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1517
|
+
"select",
|
|
1518
|
+
{
|
|
1519
|
+
"aria-label": "Proof profile",
|
|
1520
|
+
className: select,
|
|
1521
|
+
value: view.proof?.id ?? "",
|
|
1522
|
+
onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
|
|
1523
|
+
children: [
|
|
1524
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "", children: "Off" }),
|
|
1525
|
+
import_image_editor9.PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: o.id, children: o.label }, o.id))
|
|
1526
|
+
]
|
|
1527
|
+
}
|
|
1528
|
+
),
|
|
1529
|
+
view.proof && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
1530
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("select", { "aria-label": "Proof intent", className: select, value: view.proof.intent, onChange: (e) => proofWith({ intent: e.target.value }), children: import_image_editor9.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
|
|
1531
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1532
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", "aria-label": "Simulate paper colour", checked: view.proof.simulatePaper, onChange: (e) => proofWith({ simulatePaper: e.target.checked }), className: "accent-indigo-500" }),
|
|
1533
|
+
"Paper"
|
|
1534
|
+
] }),
|
|
1535
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1536
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", "aria-label": "Gamut warning", checked: view.proof.gamutWarning, onChange: (e) => proofWith({ gamutWarning: e.target.checked }), className: "accent-indigo-500" }),
|
|
1537
|
+
"Gamut warning"
|
|
1538
|
+
] })
|
|
1539
|
+
] })
|
|
1540
|
+
] }),
|
|
1541
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1542
|
+
] });
|
|
1543
|
+
};
|
|
1544
|
+
|
|
1545
|
+
// src/image-editor/SelectionOptionsBar.tsx
|
|
1546
|
+
var import_react9 = require("react");
|
|
1547
|
+
var import_image_editor10 = require("@pixerate/editor/image-editor");
|
|
1548
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1452
1549
|
var MODIFY_OPS = [
|
|
1453
1550
|
{ op: "grow", label: "Grow" },
|
|
1454
1551
|
{ op: "shrink", label: "Shrink" },
|
|
@@ -1465,20 +1562,20 @@ var SelectionOptionsBar = ({
|
|
|
1465
1562
|
quickMask,
|
|
1466
1563
|
className = ""
|
|
1467
1564
|
}) => {
|
|
1468
|
-
const [radius, setRadius] = (0,
|
|
1565
|
+
const [radius, setRadius] = (0, import_react9.useState)(2);
|
|
1469
1566
|
const set = (patch) => onOptionsChange({ ...options, ...patch });
|
|
1470
1567
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
1471
1568
|
const qm = quickMask ?? Boolean(controller.getState().quickMask);
|
|
1472
|
-
return /* @__PURE__ */ (0,
|
|
1473
|
-
/* @__PURE__ */ (0,
|
|
1474
|
-
/* @__PURE__ */ (0,
|
|
1475
|
-
options.tool === "wand" && /* @__PURE__ */ (0,
|
|
1476
|
-
/* @__PURE__ */ (0,
|
|
1477
|
-
/* @__PURE__ */ (0,
|
|
1478
|
-
/* @__PURE__ */ (0,
|
|
1479
|
-
/* @__PURE__ */ (0,
|
|
1569
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
1570
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: import_image_editor10.SELECTION_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", "aria-pressed": options.tool === t.id, className: btn(options.tool === t.id), onClick: () => set({ tool: t.id }), children: t.label }, t.id)) }),
|
|
1571
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: import_image_editor10.SELECTION_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: import_image_editor10.SELECTION_MODE_LABELS[m] }, m)) }),
|
|
1572
|
+
options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
1573
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1574
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1575
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Tolerance" }),
|
|
1576
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "font-mono", children: options.tolerance })
|
|
1480
1577
|
] }),
|
|
1481
|
-
/* @__PURE__ */ (0,
|
|
1578
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1482
1579
|
"input",
|
|
1483
1580
|
{
|
|
1484
1581
|
type: "range",
|
|
@@ -1492,17 +1589,17 @@ var SelectionOptionsBar = ({
|
|
|
1492
1589
|
}
|
|
1493
1590
|
)
|
|
1494
1591
|
] }),
|
|
1495
|
-
/* @__PURE__ */ (0,
|
|
1496
|
-
/* @__PURE__ */ (0,
|
|
1592
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1593
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
|
|
1497
1594
|
"Contiguous"
|
|
1498
1595
|
] }),
|
|
1499
|
-
/* @__PURE__ */ (0,
|
|
1500
|
-
/* @__PURE__ */ (0,
|
|
1596
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1597
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
|
|
1501
1598
|
"Sample adjusted image"
|
|
1502
1599
|
] }),
|
|
1503
|
-
/* @__PURE__ */ (0,
|
|
1600
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1504
1601
|
"Sample",
|
|
1505
|
-
/* @__PURE__ */ (0,
|
|
1602
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1506
1603
|
"select",
|
|
1507
1604
|
{
|
|
1508
1605
|
"aria-label": "Sample from",
|
|
@@ -1510,27 +1607,27 @@ var SelectionOptionsBar = ({
|
|
|
1510
1607
|
onChange: (e) => set({ sample: e.target.value }),
|
|
1511
1608
|
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
1512
1609
|
children: [
|
|
1513
|
-
/* @__PURE__ */ (0,
|
|
1514
|
-
/* @__PURE__ */ (0,
|
|
1610
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "composite", children: "All layers" }),
|
|
1611
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "active-layer", children: "Active layer" })
|
|
1515
1612
|
]
|
|
1516
1613
|
}
|
|
1517
1614
|
)
|
|
1518
1615
|
] })
|
|
1519
1616
|
] }),
|
|
1520
|
-
/* @__PURE__ */ (0,
|
|
1521
|
-
/* @__PURE__ */ (0,
|
|
1617
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1618
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
|
|
1522
1619
|
"Anti-alias"
|
|
1523
1620
|
] }),
|
|
1524
|
-
/* @__PURE__ */ (0,
|
|
1525
|
-
/* @__PURE__ */ (0,
|
|
1526
|
-
/* @__PURE__ */ (0,
|
|
1527
|
-
/* @__PURE__ */ (0,
|
|
1528
|
-
/* @__PURE__ */ (0,
|
|
1621
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
1622
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
|
|
1623
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
|
|
1624
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
|
|
1625
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
|
|
1529
1626
|
] }),
|
|
1530
|
-
/* @__PURE__ */ (0,
|
|
1531
|
-
/* @__PURE__ */ (0,
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
1628
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
|
|
1532
1629
|
"Radius",
|
|
1533
|
-
/* @__PURE__ */ (0,
|
|
1630
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1534
1631
|
"input",
|
|
1535
1632
|
{
|
|
1536
1633
|
type: "number",
|
|
@@ -1544,24 +1641,24 @@ var SelectionOptionsBar = ({
|
|
|
1544
1641
|
}
|
|
1545
1642
|
)
|
|
1546
1643
|
] }),
|
|
1547
|
-
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0,
|
|
1644
|
+
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
|
|
1548
1645
|
] }),
|
|
1549
|
-
/* @__PURE__ */ (0,
|
|
1646
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor10.describeSelection)(sel) })
|
|
1550
1647
|
] });
|
|
1551
1648
|
};
|
|
1552
1649
|
|
|
1553
1650
|
// src/image-editor/RefineEdgePanel.tsx
|
|
1554
|
-
var
|
|
1555
|
-
var
|
|
1556
|
-
var
|
|
1651
|
+
var import_react10 = require("react");
|
|
1652
|
+
var import_image_editor11 = require("@pixerate/editor/image-editor");
|
|
1653
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1557
1654
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
1558
1655
|
var button2 = "px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40";
|
|
1559
1656
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
1560
|
-
const [params, setParams] = (0,
|
|
1561
|
-
const [busy, setBusy] = (0,
|
|
1562
|
-
const [error, setError] = (0,
|
|
1563
|
-
const [layerId, setLayerId] = (0,
|
|
1564
|
-
const [newKind, setNewKind] = (0,
|
|
1657
|
+
const [params, setParams] = (0, import_react10.useState)(DEFAULT_PARAMS);
|
|
1658
|
+
const [busy, setBusy] = (0, import_react10.useState)(false);
|
|
1659
|
+
const [error, setError] = (0, import_react10.useState)(null);
|
|
1660
|
+
const [layerId, setLayerId] = (0, import_react10.useState)("");
|
|
1661
|
+
const [newKind, setNewKind] = (0, import_react10.useState)("hueSaturation");
|
|
1565
1662
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
1566
1663
|
const list = layers ?? controller.getAdjustmentLayers();
|
|
1567
1664
|
const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
|
|
@@ -1576,17 +1673,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1576
1673
|
setBusy(false);
|
|
1577
1674
|
}
|
|
1578
1675
|
};
|
|
1579
|
-
return /* @__PURE__ */ (0,
|
|
1580
|
-
/* @__PURE__ */ (0,
|
|
1581
|
-
|
|
1582
|
-
/* @__PURE__ */ (0,
|
|
1583
|
-
/* @__PURE__ */ (0,
|
|
1584
|
-
/* @__PURE__ */ (0,
|
|
1676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
1677
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
|
|
1678
|
+
import_image_editor11.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1679
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1680
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: c.label }),
|
|
1681
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
|
|
1585
1682
|
params[c.id],
|
|
1586
1683
|
c.unit
|
|
1587
1684
|
] })
|
|
1588
1685
|
] }),
|
|
1589
|
-
/* @__PURE__ */ (0,
|
|
1686
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1590
1687
|
"input",
|
|
1591
1688
|
{
|
|
1592
1689
|
type: "range",
|
|
@@ -1600,67 +1697,67 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1600
1697
|
}
|
|
1601
1698
|
)
|
|
1602
1699
|
] }, c.id)),
|
|
1603
|
-
/* @__PURE__ */ (0,
|
|
1604
|
-
/* @__PURE__ */ (0,
|
|
1700
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1701
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
|
|
1605
1702
|
"Smart Radius"
|
|
1606
1703
|
] }),
|
|
1607
|
-
/* @__PURE__ */ (0,
|
|
1608
|
-
/* @__PURE__ */ (0,
|
|
1609
|
-
/* @__PURE__ */ (0,
|
|
1704
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex gap-1", children: [
|
|
1705
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
|
|
1706
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
|
|
1610
1707
|
] }),
|
|
1611
|
-
error && /* @__PURE__ */ (0,
|
|
1612
|
-
/* @__PURE__ */ (0,
|
|
1613
|
-
/* @__PURE__ */ (0,
|
|
1614
|
-
/* @__PURE__ */ (0,
|
|
1708
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
|
|
1709
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
|
|
1710
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex gap-1 items-center", children: [
|
|
1711
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1615
1712
|
"select",
|
|
1616
1713
|
{
|
|
1617
1714
|
"aria-label": "New masked layer kind",
|
|
1618
1715
|
value: newKind,
|
|
1619
1716
|
onChange: (e) => setNewKind(e.target.value),
|
|
1620
1717
|
className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
1621
|
-
children:
|
|
1718
|
+
children: import_image_editor11.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: k.kind, children: k.label }, k.kind))
|
|
1622
1719
|
}
|
|
1623
1720
|
),
|
|
1624
|
-
/* @__PURE__ */ (0,
|
|
1721
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1625
1722
|
"button",
|
|
1626
1723
|
{
|
|
1627
1724
|
type: "button",
|
|
1628
1725
|
className: button2,
|
|
1629
1726
|
disabled: !sel,
|
|
1630
|
-
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0,
|
|
1727
|
+
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor11.layerMaskFromSelection)(sel) })),
|
|
1631
1728
|
children: "New Masked Layer"
|
|
1632
1729
|
}
|
|
1633
1730
|
)
|
|
1634
1731
|
] }),
|
|
1635
|
-
list.length > 0 && target && /* @__PURE__ */ (0,
|
|
1636
|
-
/* @__PURE__ */ (0,
|
|
1732
|
+
list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
1733
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1637
1734
|
"select",
|
|
1638
1735
|
{
|
|
1639
1736
|
"aria-label": "Mask layer",
|
|
1640
1737
|
value: target.id,
|
|
1641
1738
|
onChange: (e) => setLayerId(e.target.value),
|
|
1642
1739
|
className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
1643
|
-
children: list.map((l) => /* @__PURE__ */ (0,
|
|
1644
|
-
l.name || (0,
|
|
1740
|
+
children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("option", { value: l.id, children: [
|
|
1741
|
+
l.name || (0, import_image_editor11.adjustmentKindLabel)(l.kind),
|
|
1645
1742
|
l.mask ? " (masked)" : ""
|
|
1646
1743
|
] }, l.id))
|
|
1647
1744
|
}
|
|
1648
1745
|
),
|
|
1649
|
-
/* @__PURE__ */ (0,
|
|
1650
|
-
/* @__PURE__ */ (0,
|
|
1651
|
-
/* @__PURE__ */ (0,
|
|
1652
|
-
/* @__PURE__ */ (0,
|
|
1746
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
1747
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
|
|
1748
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
|
|
1749
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
|
|
1653
1750
|
] }),
|
|
1654
|
-
target.mask && /* @__PURE__ */ (0,
|
|
1655
|
-
/* @__PURE__ */ (0,
|
|
1656
|
-
/* @__PURE__ */ (0,
|
|
1657
|
-
/* @__PURE__ */ (0,
|
|
1658
|
-
/* @__PURE__ */ (0,
|
|
1751
|
+
target.mask && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1752
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1753
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1754
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Density" }),
|
|
1755
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
|
|
1659
1756
|
Math.round((target.mask.density ?? 1) * 100),
|
|
1660
1757
|
"%"
|
|
1661
1758
|
] })
|
|
1662
1759
|
] }),
|
|
1663
|
-
/* @__PURE__ */ (0,
|
|
1760
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1664
1761
|
"input",
|
|
1665
1762
|
{
|
|
1666
1763
|
type: "range",
|
|
@@ -1674,15 +1771,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1674
1771
|
}
|
|
1675
1772
|
)
|
|
1676
1773
|
] }),
|
|
1677
|
-
/* @__PURE__ */ (0,
|
|
1678
|
-
/* @__PURE__ */ (0,
|
|
1679
|
-
/* @__PURE__ */ (0,
|
|
1680
|
-
/* @__PURE__ */ (0,
|
|
1774
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1775
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1776
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Mask Feather" }),
|
|
1777
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
|
|
1681
1778
|
target.mask.feather ?? 0,
|
|
1682
1779
|
"px"
|
|
1683
1780
|
] })
|
|
1684
1781
|
] }),
|
|
1685
|
-
/* @__PURE__ */ (0,
|
|
1782
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1686
1783
|
"input",
|
|
1687
1784
|
{
|
|
1688
1785
|
type: "range",
|
|
@@ -1702,14 +1799,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1702
1799
|
};
|
|
1703
1800
|
|
|
1704
1801
|
// src/image-editor/FreeTransformOptionsBar.tsx
|
|
1705
|
-
var
|
|
1706
|
-
var
|
|
1707
|
-
var
|
|
1708
|
-
var
|
|
1802
|
+
var import_react11 = require("react");
|
|
1803
|
+
var import_image_editor12 = require("@pixerate/editor/image-editor");
|
|
1804
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1805
|
+
var chip3 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
1709
1806
|
var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
|
|
1710
1807
|
var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
1711
|
-
const [, setTick] = (0,
|
|
1712
|
-
(0,
|
|
1808
|
+
const [, setTick] = (0, import_react11.useState)(0);
|
|
1809
|
+
(0, import_react11.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
|
|
1713
1810
|
const bar = tool.bar();
|
|
1714
1811
|
if (!tool.active || !bar) return null;
|
|
1715
1812
|
const warp = tool.warpBar();
|
|
@@ -1721,17 +1818,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1721
1818
|
const v = Number(raw);
|
|
1722
1819
|
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
1723
1820
|
};
|
|
1724
|
-
return /* @__PURE__ */ (0,
|
|
1725
|
-
/* @__PURE__ */ (0,
|
|
1726
|
-
/* @__PURE__ */ (0,
|
|
1727
|
-
tool.mode === "warp" && /* @__PURE__ */ (0,
|
|
1728
|
-
/* @__PURE__ */ (0,
|
|
1729
|
-
/* @__PURE__ */ (0,
|
|
1730
|
-
/* @__PURE__ */ (0,
|
|
1821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.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: [
|
|
1822
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor12.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", title: m.title, "aria-pressed": tool.mode === m.id, className: chip3(tool.mode === m.id), onClick: () => tool.setMode(m.id), children: m.label }, m.id)) }),
|
|
1823
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor12.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime11.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)) }),
|
|
1824
|
+
tool.mode === "warp" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
|
|
1825
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1826
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: "Warp" }),
|
|
1827
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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_editor12.WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: o.id, children: o.label }, o.id)) })
|
|
1731
1828
|
] }),
|
|
1732
|
-
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0,
|
|
1733
|
-
/* @__PURE__ */ (0,
|
|
1734
|
-
/* @__PURE__ */ (0,
|
|
1829
|
+
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1830
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
|
|
1831
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1735
1832
|
"input",
|
|
1736
1833
|
{
|
|
1737
1834
|
type: "number",
|
|
@@ -1752,40 +1849,40 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1752
1849
|
},
|
|
1753
1850
|
`${k}:${warp[k]}`
|
|
1754
1851
|
),
|
|
1755
|
-
/* @__PURE__ */ (0,
|
|
1852
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-500", children: "%" })
|
|
1756
1853
|
] }, k)),
|
|
1757
|
-
/* @__PURE__ */ (0,
|
|
1854
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1758
1855
|
"button",
|
|
1759
1856
|
{
|
|
1760
1857
|
type: "button",
|
|
1761
1858
|
title: "Bend along the vertical axis",
|
|
1762
1859
|
"aria-pressed": warp.orientation === "vertical",
|
|
1763
1860
|
disabled: warp.style === "custom",
|
|
1764
|
-
className:
|
|
1861
|
+
className: chip3(warp.orientation === "vertical"),
|
|
1765
1862
|
onClick: () => tool.setWarp({ orientation: warp.orientation === "vertical" ? "horizontal" : "vertical" }),
|
|
1766
1863
|
children: "Vertical"
|
|
1767
1864
|
}
|
|
1768
1865
|
),
|
|
1769
|
-
/* @__PURE__ */ (0,
|
|
1770
|
-
/* @__PURE__ */ (0,
|
|
1771
|
-
/* @__PURE__ */ (0,
|
|
1866
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1867
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: "Grid" }),
|
|
1868
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1772
1869
|
"select",
|
|
1773
1870
|
{
|
|
1774
1871
|
"aria-label": "Warp grid",
|
|
1775
|
-
value:
|
|
1872
|
+
value: import_image_editor12.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
|
|
1776
1873
|
onChange: (e) => {
|
|
1777
|
-
const g =
|
|
1874
|
+
const g = import_image_editor12.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
|
|
1778
1875
|
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
1779
1876
|
},
|
|
1780
1877
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1781
|
-
children:
|
|
1878
|
+
children: import_image_editor12.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: g.id, children: g.label }, g.id))
|
|
1782
1879
|
}
|
|
1783
1880
|
)
|
|
1784
1881
|
] })
|
|
1785
1882
|
] }),
|
|
1786
|
-
tool.mode !== "warp" &&
|
|
1787
|
-
/* @__PURE__ */ (0,
|
|
1788
|
-
/* @__PURE__ */ (0,
|
|
1883
|
+
tool.mode !== "warp" && import_image_editor12.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
|
|
1884
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: f.label }),
|
|
1885
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1789
1886
|
"input",
|
|
1790
1887
|
{
|
|
1791
1888
|
type: "number",
|
|
@@ -1805,14 +1902,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1805
1902
|
},
|
|
1806
1903
|
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
1807
1904
|
),
|
|
1808
|
-
/* @__PURE__ */ (0,
|
|
1809
|
-
f.id === "scaleX" && /* @__PURE__ */ (0,
|
|
1905
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-500", children: f.unit }),
|
|
1906
|
+
f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1810
1907
|
"button",
|
|
1811
1908
|
{
|
|
1812
1909
|
type: "button",
|
|
1813
1910
|
"aria-label": "Keep width and height proportional",
|
|
1814
1911
|
"aria-pressed": tool.proportional,
|
|
1815
|
-
className:
|
|
1912
|
+
className: chip3(tool.proportional),
|
|
1816
1913
|
onClick: () => {
|
|
1817
1914
|
tool.proportional = !tool.proportional;
|
|
1818
1915
|
setTick((n) => n + 1);
|
|
@@ -1821,34 +1918,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1821
1918
|
}
|
|
1822
1919
|
)
|
|
1823
1920
|
] }, f.id)),
|
|
1824
|
-
/* @__PURE__ */ (0,
|
|
1825
|
-
/* @__PURE__ */ (0,
|
|
1826
|
-
/* @__PURE__ */ (0,
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1922
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
|
|
1923
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1827
1924
|
"select",
|
|
1828
1925
|
{
|
|
1829
1926
|
"aria-label": "Interpolation",
|
|
1830
1927
|
value: tool.interpolation,
|
|
1831
1928
|
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
1832
1929
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1833
|
-
children:
|
|
1930
|
+
children: import_image_editor12.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
1834
1931
|
}
|
|
1835
1932
|
)
|
|
1836
1933
|
] }),
|
|
1837
|
-
/* @__PURE__ */ (0,
|
|
1838
|
-
/* @__PURE__ */ (0,
|
|
1839
|
-
tool.error && /* @__PURE__ */ (0,
|
|
1934
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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" }),
|
|
1935
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
|
|
1936
|
+
tool.error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
|
|
1840
1937
|
] });
|
|
1841
1938
|
};
|
|
1842
1939
|
|
|
1843
1940
|
// src/image-editor/ShapeOptionsBar.tsx
|
|
1844
|
-
var
|
|
1845
|
-
var
|
|
1846
|
-
var
|
|
1847
|
-
var
|
|
1941
|
+
var import_react12 = require("react");
|
|
1942
|
+
var import_image_editor13 = require("@pixerate/editor/image-editor");
|
|
1943
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1944
|
+
var chip4 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
1848
1945
|
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
1849
|
-
const [, setTick] = (0,
|
|
1850
|
-
(0,
|
|
1851
|
-
const [error, setError] = (0,
|
|
1946
|
+
const [, setTick] = (0, import_react12.useState)(0);
|
|
1947
|
+
(0, import_react12.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1948
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
1852
1949
|
const active = controller.getActiveLayer();
|
|
1853
1950
|
const shapeId = active?.type === "shape" ? active.id : null;
|
|
1854
1951
|
const set = (change) => {
|
|
@@ -1856,19 +1953,19 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1856
1953
|
if (!shapeId) return;
|
|
1857
1954
|
try {
|
|
1858
1955
|
setError(null);
|
|
1859
|
-
(0,
|
|
1956
|
+
(0, import_image_editor13.applyShapeOptions)(controller, shapeId, change);
|
|
1860
1957
|
} catch (e) {
|
|
1861
1958
|
setError(e instanceof Error ? e.message : String(e));
|
|
1862
1959
|
}
|
|
1863
1960
|
};
|
|
1864
1961
|
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
1865
|
-
return /* @__PURE__ */ (0,
|
|
1866
|
-
/* @__PURE__ */ (0,
|
|
1867
|
-
/* @__PURE__ */ (0,
|
|
1868
|
-
/* @__PURE__ */ (0,
|
|
1869
|
-
/* @__PURE__ */ (0,
|
|
1962
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
|
|
1963
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: import_image_editor13.LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", "aria-pressed": options.kind === k, className: chip4(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: import_image_editor13.SHAPE_KIND_LABELS[k] }, k)) }),
|
|
1964
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
1965
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1966
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
|
|
1870
1967
|
"Fill",
|
|
1871
|
-
/* @__PURE__ */ (0,
|
|
1968
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1872
1969
|
"input",
|
|
1873
1970
|
{
|
|
1874
1971
|
type: "color",
|
|
@@ -1880,10 +1977,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1880
1977
|
}
|
|
1881
1978
|
)
|
|
1882
1979
|
] }),
|
|
1883
|
-
/* @__PURE__ */ (0,
|
|
1884
|
-
/* @__PURE__ */ (0,
|
|
1980
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1981
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
|
|
1885
1982
|
"Stroke",
|
|
1886
|
-
/* @__PURE__ */ (0,
|
|
1983
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1887
1984
|
"input",
|
|
1888
1985
|
{
|
|
1889
1986
|
type: "color",
|
|
@@ -1895,9 +1992,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1895
1992
|
}
|
|
1896
1993
|
)
|
|
1897
1994
|
] }),
|
|
1898
|
-
/* @__PURE__ */ (0,
|
|
1995
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1899
1996
|
"Width",
|
|
1900
|
-
/* @__PURE__ */ (0,
|
|
1997
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1901
1998
|
"input",
|
|
1902
1999
|
{
|
|
1903
2000
|
type: "number",
|
|
@@ -1911,23 +2008,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1911
2008
|
)
|
|
1912
2009
|
] })
|
|
1913
2010
|
] }),
|
|
1914
|
-
/* @__PURE__ */ (0,
|
|
1915
|
-
options.kind === "rect" && /* @__PURE__ */ (0,
|
|
2011
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
2012
|
+
options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1916
2013
|
"Radius",
|
|
1917
|
-
/* @__PURE__ */ (0,
|
|
2014
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "number", "aria-label": "Corner radius", min: 0, max: 1e3, value: options.radius, onChange: (e) => set({ radius: num(e.target.value, 0, 1e3) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1918
2015
|
] }),
|
|
1919
|
-
options.kind === "polygon" && /* @__PURE__ */ (0,
|
|
2016
|
+
options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1920
2017
|
"Sides",
|
|
1921
|
-
/* @__PURE__ */ (0,
|
|
2018
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "number", "aria-label": "Sides", min: 3, max: 100, value: options.sides, onChange: (e) => set({ sides: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1922
2019
|
] }),
|
|
1923
|
-
options.kind === "star" && /* @__PURE__ */ (0,
|
|
1924
|
-
/* @__PURE__ */ (0,
|
|
2020
|
+
options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
2021
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1925
2022
|
"Points",
|
|
1926
|
-
/* @__PURE__ */ (0,
|
|
2023
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "number", "aria-label": "Points", min: 3, max: 100, value: options.points, onChange: (e) => set({ points: num(e.target.value, 3, 100) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1927
2024
|
] }),
|
|
1928
|
-
/* @__PURE__ */ (0,
|
|
2025
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1929
2026
|
"Inner",
|
|
1930
|
-
/* @__PURE__ */ (0,
|
|
2027
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1931
2028
|
"input",
|
|
1932
2029
|
{
|
|
1933
2030
|
type: "range",
|
|
@@ -1942,33 +2039,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1942
2039
|
)
|
|
1943
2040
|
] })
|
|
1944
2041
|
] }),
|
|
1945
|
-
options.kind === "line" && /* @__PURE__ */ (0,
|
|
1946
|
-
/* @__PURE__ */ (0,
|
|
2042
|
+
options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
2043
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1947
2044
|
"Weight",
|
|
1948
|
-
/* @__PURE__ */ (0,
|
|
2045
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "number", "aria-label": "Line weight", min: 1, max: 200, value: options.weight, onChange: (e) => set({ weight: num(e.target.value, 1, 200) }), className: "w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5" })
|
|
1949
2046
|
] }),
|
|
1950
|
-
/* @__PURE__ */ (0,
|
|
1951
|
-
/* @__PURE__ */ (0,
|
|
2047
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2048
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
|
|
1952
2049
|
"Arrowhead"
|
|
1953
2050
|
] })
|
|
1954
2051
|
] })
|
|
1955
2052
|
] }),
|
|
1956
|
-
/* @__PURE__ */ (0,
|
|
1957
|
-
error && /* @__PURE__ */ (0,
|
|
2053
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-[10px] text-slate-500", children: "Drag on the image to draw. Shift: square, circle or 45\xB0 line. Alt: from the centre." }),
|
|
2054
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1958
2055
|
] });
|
|
1959
2056
|
};
|
|
1960
2057
|
|
|
1961
2058
|
// src/image-editor/TypeOptionsBar.tsx
|
|
1962
|
-
var
|
|
1963
|
-
var
|
|
1964
|
-
var
|
|
1965
|
-
var
|
|
2059
|
+
var import_react13 = require("react");
|
|
2060
|
+
var import_image_editor14 = require("@pixerate/editor/image-editor");
|
|
2061
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2062
|
+
var chip5 = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
1966
2063
|
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
1967
2064
|
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
1968
|
-
const [, setTick] = (0,
|
|
1969
|
-
(0,
|
|
1970
|
-
(0,
|
|
1971
|
-
const [error, setError] = (0,
|
|
2065
|
+
const [, setTick] = (0, import_react13.useState)(0);
|
|
2066
|
+
(0, import_react13.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
2067
|
+
(0, import_react13.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
|
|
2068
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1972
2069
|
const active = controller.getActiveLayer();
|
|
1973
2070
|
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
1974
2071
|
const here = session?.alive ? session.styleHere() : {};
|
|
@@ -2000,11 +2097,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2000
2097
|
setError(e instanceof Error ? e.message : String(e));
|
|
2001
2098
|
}
|
|
2002
2099
|
};
|
|
2003
|
-
return /* @__PURE__ */ (0,
|
|
2004
|
-
/* @__PURE__ */ (0,
|
|
2005
|
-
/* @__PURE__ */ (0,
|
|
2100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
|
|
2101
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2102
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2006
2103
|
"Font",
|
|
2007
|
-
/* @__PURE__ */ (0,
|
|
2104
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2008
2105
|
"input",
|
|
2009
2106
|
{
|
|
2010
2107
|
list: "pixerate-type-fonts",
|
|
@@ -2014,11 +2111,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2014
2111
|
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
2015
2112
|
}
|
|
2016
2113
|
),
|
|
2017
|
-
/* @__PURE__ */ (0,
|
|
2114
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: f }, f)) })
|
|
2018
2115
|
] }),
|
|
2019
|
-
/* @__PURE__ */ (0,
|
|
2116
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2020
2117
|
"Size",
|
|
2021
|
-
/* @__PURE__ */ (0,
|
|
2118
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2022
2119
|
"input",
|
|
2023
2120
|
{
|
|
2024
2121
|
type: "number",
|
|
@@ -2031,24 +2128,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2031
2128
|
}
|
|
2032
2129
|
)
|
|
2033
2130
|
] }),
|
|
2034
|
-
/* @__PURE__ */ (0,
|
|
2035
|
-
/* @__PURE__ */ (0,
|
|
2036
|
-
/* @__PURE__ */ (0,
|
|
2131
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", "aria-pressed": shown.fontWeight >= 600, className: `${chip5(shown.fontWeight >= 600)} font-bold`, onClick: () => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 }), children: "B" }),
|
|
2132
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", "aria-pressed": shown.italic, className: `${chip5(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
|
|
2133
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "color", "aria-label": "Text colour", value: shown.color, onChange: (e) => style({ color: e.target.value }), className: "h-6 w-8 rounded border border-slate-700 bg-transparent" })
|
|
2037
2134
|
] }),
|
|
2038
|
-
/* @__PURE__ */ (0,
|
|
2039
|
-
/* @__PURE__ */ (0,
|
|
2040
|
-
missing.length > 0 && /* @__PURE__ */ (0,
|
|
2135
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: import_image_editor14.TEXT_ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", "aria-pressed": options.align === a, className: chip5(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
|
|
2136
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-[10px] text-slate-500", children: "Click to type point text, drag for a paragraph box, click text to edit it. Esc finishes." }),
|
|
2137
|
+
missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
|
|
2041
2138
|
"Missing ",
|
|
2042
2139
|
missing.length === 1 ? "font" : "fonts",
|
|
2043
2140
|
": ",
|
|
2044
2141
|
missing.join(", ")
|
|
2045
2142
|
] }),
|
|
2046
|
-
error && /* @__PURE__ */ (0,
|
|
2143
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
2047
2144
|
] });
|
|
2048
2145
|
};
|
|
2049
2146
|
|
|
2050
2147
|
// src/image-editor/ImageEditor.tsx
|
|
2051
|
-
var
|
|
2148
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2052
2149
|
var ImageEditor = ({
|
|
2053
2150
|
editor: externalEditor,
|
|
2054
2151
|
src,
|
|
@@ -2063,65 +2160,65 @@ var ImageEditor = ({
|
|
|
2063
2160
|
const internalEditor = useImageEditor({ image: src });
|
|
2064
2161
|
const editor = externalEditor || internalEditor;
|
|
2065
2162
|
const { state, controller } = editor;
|
|
2066
|
-
const legacyProcess = (0,
|
|
2067
|
-
const canvasRef = (0,
|
|
2068
|
-
const containerRef = (0,
|
|
2069
|
-
const [activeTab, setActiveTab] = (0,
|
|
2070
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
2071
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
2072
|
-
const selectionOptionsRef = (0,
|
|
2163
|
+
const legacyProcess = (0, import_image_editor15.normalizeProcessVersion)(state.adjustments.process) < import_image_editor15.LATEST_PROCESS_VERSION;
|
|
2164
|
+
const canvasRef = (0, import_react14.useRef)(null);
|
|
2165
|
+
const containerRef = (0, import_react14.useRef)(null);
|
|
2166
|
+
const [activeTab, setActiveTab] = (0, import_react14.useState)("crop");
|
|
2167
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react14.useState)(null);
|
|
2168
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react14.useState)(import_image_editor15.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
2169
|
+
const selectionOptionsRef = (0, import_react14.useRef)(selectionOptions);
|
|
2073
2170
|
selectionOptionsRef.current = selectionOptions;
|
|
2074
|
-
const selectionGestureRef = (0,
|
|
2171
|
+
const selectionGestureRef = (0, import_react14.useRef)(null);
|
|
2075
2172
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
2076
|
-
selectionGestureRef.current = new
|
|
2173
|
+
selectionGestureRef.current = new import_image_editor15.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
2077
2174
|
}
|
|
2078
|
-
const selectionDraftRef = (0,
|
|
2079
|
-
const [selectionError, setSelectionError] = (0,
|
|
2080
|
-
const paintGestureRef = (0,
|
|
2081
|
-
const paintControllerRef = (0,
|
|
2175
|
+
const selectionDraftRef = (0, import_react14.useRef)(null);
|
|
2176
|
+
const [selectionError, setSelectionError] = (0, import_react14.useState)(null);
|
|
2177
|
+
const paintGestureRef = (0, import_react14.useRef)(null);
|
|
2178
|
+
const paintControllerRef = (0, import_react14.useRef)(controller);
|
|
2082
2179
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
2083
|
-
paintGestureRef.current = new
|
|
2180
|
+
paintGestureRef.current = new import_image_editor15.PaintGesture(controller);
|
|
2084
2181
|
paintControllerRef.current = controller;
|
|
2085
2182
|
}
|
|
2086
|
-
const brushCursorRef = (0,
|
|
2087
|
-
const [paintError, setPaintError] = (0,
|
|
2088
|
-
const transformToolRef = (0,
|
|
2089
|
-
const transformControllerRef = (0,
|
|
2183
|
+
const brushCursorRef = (0, import_react14.useRef)(null);
|
|
2184
|
+
const [paintError, setPaintError] = (0, import_react14.useState)(null);
|
|
2185
|
+
const transformToolRef = (0, import_react14.useRef)(null);
|
|
2186
|
+
const transformControllerRef = (0, import_react14.useRef)(controller);
|
|
2090
2187
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
2091
2188
|
transformToolRef.current?.cancel();
|
|
2092
|
-
transformToolRef.current = new
|
|
2189
|
+
transformToolRef.current = new import_image_editor15.FreeTransformTool(controller, {
|
|
2093
2190
|
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
2094
2191
|
});
|
|
2095
2192
|
transformControllerRef.current = controller;
|
|
2096
2193
|
}
|
|
2097
2194
|
const transformTool = transformToolRef.current;
|
|
2098
|
-
const [, setTransformTick] = (0,
|
|
2099
|
-
const [transformCursor, setTransformCursor] = (0,
|
|
2100
|
-
const [shapeOptions, setShapeOptions] = (0,
|
|
2101
|
-
const shapeOptionsRef = (0,
|
|
2195
|
+
const [, setTransformTick] = (0, import_react14.useState)(0);
|
|
2196
|
+
const [transformCursor, setTransformCursor] = (0, import_react14.useState)("default");
|
|
2197
|
+
const [shapeOptions, setShapeOptions] = (0, import_react14.useState)(import_image_editor15.DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
2198
|
+
const shapeOptionsRef = (0, import_react14.useRef)(shapeOptions);
|
|
2102
2199
|
shapeOptionsRef.current = shapeOptions;
|
|
2103
|
-
const [typeOptions, setTypeOptions] = (0,
|
|
2104
|
-
const typeOptionsRef = (0,
|
|
2200
|
+
const [typeOptions, setTypeOptions] = (0, import_react14.useState)(import_image_editor15.DEFAULT_TYPE_TOOL_OPTIONS);
|
|
2201
|
+
const typeOptionsRef = (0, import_react14.useRef)(typeOptions);
|
|
2105
2202
|
typeOptionsRef.current = typeOptions;
|
|
2106
|
-
const shapeGestureRef = (0,
|
|
2107
|
-
const typeToolRef = (0,
|
|
2108
|
-
const shapeTypeControllerRef = (0,
|
|
2203
|
+
const shapeGestureRef = (0, import_react14.useRef)(null);
|
|
2204
|
+
const typeToolRef = (0, import_react14.useRef)(null);
|
|
2205
|
+
const shapeTypeControllerRef = (0, import_react14.useRef)(controller);
|
|
2109
2206
|
if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
|
|
2110
2207
|
typeToolRef.current?.finish();
|
|
2111
|
-
shapeGestureRef.current = new
|
|
2112
|
-
typeToolRef.current = new
|
|
2208
|
+
shapeGestureRef.current = new import_image_editor15.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
|
|
2209
|
+
typeToolRef.current = new import_image_editor15.TypeToolGesture(controller, () => typeOptionsRef.current);
|
|
2113
2210
|
shapeTypeControllerRef.current = controller;
|
|
2114
2211
|
}
|
|
2115
|
-
const typeInputRef = (0,
|
|
2116
|
-
const [typeSession, setTypeSession] = (0,
|
|
2117
|
-
const [shapeTypeError, setShapeTypeError] = (0,
|
|
2118
|
-
const [inpaintPrompt, setInpaintPrompt] = (0,
|
|
2119
|
-
const [inpaintMaskMode, setInpaintMaskMode] = (0,
|
|
2120
|
-
const [isRemovingBg, setIsRemovingBg] = (0,
|
|
2121
|
-
const [isInpainting, setIsInpainting] = (0,
|
|
2122
|
-
const [aiError, setAiError] = (0,
|
|
2123
|
-
const [aiSuccess, setAiSuccess] = (0,
|
|
2124
|
-
const [aiTarget, setAiTarget] = (0,
|
|
2212
|
+
const typeInputRef = (0, import_react14.useRef)(null);
|
|
2213
|
+
const [typeSession, setTypeSession] = (0, import_react14.useState)(typeToolRef.current.session);
|
|
2214
|
+
const [shapeTypeError, setShapeTypeError] = (0, import_react14.useState)(null);
|
|
2215
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react14.useState)("");
|
|
2216
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react14.useState)("annotations");
|
|
2217
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react14.useState)(false);
|
|
2218
|
+
const [isInpainting, setIsInpainting] = (0, import_react14.useState)(false);
|
|
2219
|
+
const [aiError, setAiError] = (0, import_react14.useState)(null);
|
|
2220
|
+
const [aiSuccess, setAiSuccess] = (0, import_react14.useState)(null);
|
|
2221
|
+
const [aiTarget, setAiTarget] = (0, import_react14.useState)("auto");
|
|
2125
2222
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
2126
2223
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
2127
2224
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -2184,18 +2281,18 @@ var ImageEditor = ({
|
|
|
2184
2281
|
setIsInpainting(false);
|
|
2185
2282
|
}
|
|
2186
2283
|
};
|
|
2187
|
-
const [activeColor, setActiveColor] = (0,
|
|
2188
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
2189
|
-
const [fontSize, setFontSize] = (0,
|
|
2190
|
-
const [textInput, setTextInput] = (0,
|
|
2191
|
-
const draftAnnotationRef = (0,
|
|
2192
|
-
const draftCropRef = (0,
|
|
2193
|
-
const cropDragInfoRef = (0,
|
|
2194
|
-
const annotationDragInfoRef = (0,
|
|
2195
|
-
const isDrawingRef = (0,
|
|
2196
|
-
const currentPathRef = (0,
|
|
2197
|
-
const dragStartPointRef = (0,
|
|
2198
|
-
const renderCanvas = (0,
|
|
2284
|
+
const [activeColor, setActiveColor] = (0, import_react14.useState)("#ef4444");
|
|
2285
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react14.useState)(3);
|
|
2286
|
+
const [fontSize, setFontSize] = (0, import_react14.useState)(24);
|
|
2287
|
+
const [textInput, setTextInput] = (0, import_react14.useState)("");
|
|
2288
|
+
const draftAnnotationRef = (0, import_react14.useRef)(null);
|
|
2289
|
+
const draftCropRef = (0, import_react14.useRef)(null);
|
|
2290
|
+
const cropDragInfoRef = (0, import_react14.useRef)(null);
|
|
2291
|
+
const annotationDragInfoRef = (0, import_react14.useRef)(null);
|
|
2292
|
+
const isDrawingRef = (0, import_react14.useRef)(false);
|
|
2293
|
+
const currentPathRef = (0, import_react14.useRef)([]);
|
|
2294
|
+
const dragStartPointRef = (0, import_react14.useRef)(null);
|
|
2295
|
+
const renderCanvas = (0, import_react14.useCallback)(
|
|
2199
2296
|
async (draftAnnotation, draftCrop) => {
|
|
2200
2297
|
const canvas = canvasRef.current;
|
|
2201
2298
|
const container = containerRef.current;
|
|
@@ -2218,8 +2315,8 @@ var ImageEditor = ({
|
|
|
2218
2315
|
},
|
|
2219
2316
|
[controller, activeTab, transformTool]
|
|
2220
2317
|
);
|
|
2221
|
-
(0,
|
|
2222
|
-
(0,
|
|
2318
|
+
(0, import_react14.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
2319
|
+
(0, import_react14.useEffect)(() => {
|
|
2223
2320
|
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
2224
2321
|
if (typeToolRef.current?.session) {
|
|
2225
2322
|
typeToolRef.current.finish();
|
|
@@ -2254,7 +2351,7 @@ var ImageEditor = ({
|
|
|
2254
2351
|
el.value = "";
|
|
2255
2352
|
}
|
|
2256
2353
|
};
|
|
2257
|
-
(0,
|
|
2354
|
+
(0, import_react14.useEffect)(() => transformTool.subscribe(() => {
|
|
2258
2355
|
setTransformTick((n) => n + 1);
|
|
2259
2356
|
void renderCanvas();
|
|
2260
2357
|
}), [transformTool, renderCanvas]);
|
|
@@ -2265,8 +2362,8 @@ var ImageEditor = ({
|
|
|
2265
2362
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
2266
2363
|
const s = controller.getState();
|
|
2267
2364
|
const cropping = activeTab === "crop";
|
|
2268
|
-
const projection = (0,
|
|
2269
|
-
const pt = (0,
|
|
2365
|
+
const projection = (0, import_image_editor15.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
2366
|
+
const pt = (0, import_image_editor15.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
|
|
2270
2367
|
transformTool.setView(projection.scale);
|
|
2271
2368
|
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
2272
2369
|
};
|
|
@@ -2297,7 +2394,7 @@ var ImageEditor = ({
|
|
|
2297
2394
|
transformTool.up();
|
|
2298
2395
|
return true;
|
|
2299
2396
|
};
|
|
2300
|
-
(0,
|
|
2397
|
+
(0, import_react14.useEffect)(() => {
|
|
2301
2398
|
if (typeof window === "undefined") return;
|
|
2302
2399
|
const onKey = (e) => {
|
|
2303
2400
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -2305,7 +2402,7 @@ var ImageEditor = ({
|
|
|
2305
2402
|
window.addEventListener("keydown", onKey);
|
|
2306
2403
|
return () => window.removeEventListener("keydown", onKey);
|
|
2307
2404
|
}, [transformTool]);
|
|
2308
|
-
(0,
|
|
2405
|
+
(0, import_react14.useEffect)(() => {
|
|
2309
2406
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
2310
2407
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
2311
2408
|
const animId = raf(() => {
|
|
@@ -2313,12 +2410,12 @@ var ImageEditor = ({
|
|
|
2313
2410
|
});
|
|
2314
2411
|
return () => caf(animId);
|
|
2315
2412
|
}, [renderCanvas, state]);
|
|
2316
|
-
(0,
|
|
2413
|
+
(0, import_react14.useEffect)(() => {
|
|
2317
2414
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
2318
2415
|
editor.setTool("crop");
|
|
2319
2416
|
}
|
|
2320
2417
|
}, [activeTab, editor]);
|
|
2321
|
-
(0,
|
|
2418
|
+
(0, import_react14.useEffect)(() => {
|
|
2322
2419
|
const container = containerRef.current;
|
|
2323
2420
|
if (!container) return;
|
|
2324
2421
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -2354,8 +2451,8 @@ var ImageEditor = ({
|
|
|
2354
2451
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
2355
2452
|
const s = controller.getState();
|
|
2356
2453
|
return list.map((ev) => ({
|
|
2357
|
-
...(0,
|
|
2358
|
-
pressure: (0,
|
|
2454
|
+
...(0, import_image_editor15.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
2455
|
+
pressure: (0, import_image_editor15.pointerPressure)(ev)
|
|
2359
2456
|
}));
|
|
2360
2457
|
};
|
|
2361
2458
|
const handlePaintPointerDown = (e) => {
|
|
@@ -2386,10 +2483,10 @@ var ImageEditor = ({
|
|
|
2386
2483
|
if (g.error) setPaintError(g.error);
|
|
2387
2484
|
}
|
|
2388
2485
|
};
|
|
2389
|
-
(0,
|
|
2486
|
+
(0, import_react14.useEffect)(() => {
|
|
2390
2487
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
2391
2488
|
const onKey = (e) => {
|
|
2392
|
-
if ((0,
|
|
2489
|
+
if ((0, import_image_editor15.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
2393
2490
|
};
|
|
2394
2491
|
window.addEventListener("keydown", onKey);
|
|
2395
2492
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -2400,7 +2497,7 @@ var ImageEditor = ({
|
|
|
2400
2497
|
const canvasPt = getCanvasEventPoint(e);
|
|
2401
2498
|
if (activeTab === "select") {
|
|
2402
2499
|
const gesture = selectionGestureRef.current;
|
|
2403
|
-
const imgPt = (0,
|
|
2500
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2404
2501
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
2405
2502
|
return;
|
|
2406
2503
|
}
|
|
@@ -2411,8 +2508,8 @@ var ImageEditor = ({
|
|
|
2411
2508
|
width: state.imageDimensions.width,
|
|
2412
2509
|
height: state.imageDimensions.height
|
|
2413
2510
|
};
|
|
2414
|
-
const handle = (0,
|
|
2415
|
-
const startImgPt = (0,
|
|
2511
|
+
const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2512
|
+
const startImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
2416
2513
|
if (handle) {
|
|
2417
2514
|
cropDragInfoRef.current = {
|
|
2418
2515
|
handle,
|
|
@@ -2431,7 +2528,7 @@ var ImageEditor = ({
|
|
|
2431
2528
|
return;
|
|
2432
2529
|
}
|
|
2433
2530
|
if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
|
|
2434
|
-
const imgPt = (0,
|
|
2531
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2435
2532
|
setShapeTypeError(null);
|
|
2436
2533
|
if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
|
|
2437
2534
|
else {
|
|
@@ -2442,12 +2539,12 @@ var ImageEditor = ({
|
|
|
2442
2539
|
return;
|
|
2443
2540
|
}
|
|
2444
2541
|
if (activeTab === "annotate") {
|
|
2445
|
-
const imgPt = (0,
|
|
2542
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2446
2543
|
dragStartPointRef.current = imgPt;
|
|
2447
2544
|
if (state.activeTool === "select") {
|
|
2448
2545
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
2449
2546
|
const ann = state.annotations[i];
|
|
2450
|
-
if ((0,
|
|
2547
|
+
if ((0, import_image_editor15.hitTestAnnotation)(imgPt, ann)) {
|
|
2451
2548
|
editor.selectAnnotation(ann.id);
|
|
2452
2549
|
annotationDragInfoRef.current = {
|
|
2453
2550
|
annId: ann.id,
|
|
@@ -2483,7 +2580,7 @@ var ImageEditor = ({
|
|
|
2483
2580
|
const canvasPt = getCanvasEventPoint(e);
|
|
2484
2581
|
if (activeTab === "select") {
|
|
2485
2582
|
const gesture = selectionGestureRef.current;
|
|
2486
|
-
if (gesture.active && gesture.move((0,
|
|
2583
|
+
if (gesture.active && gesture.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
2487
2584
|
selectionDraftRef.current = gesture.draftPath;
|
|
2488
2585
|
renderCanvas();
|
|
2489
2586
|
}
|
|
@@ -2492,7 +2589,7 @@ var ImageEditor = ({
|
|
|
2492
2589
|
if (activeTab === "crop") {
|
|
2493
2590
|
const drag = cropDragInfoRef.current;
|
|
2494
2591
|
if (drag) {
|
|
2495
|
-
const currentImgPt = (0,
|
|
2592
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
2496
2593
|
let newCrop;
|
|
2497
2594
|
if (drag.handle === "new") {
|
|
2498
2595
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -2506,7 +2603,7 @@ var ImageEditor = ({
|
|
|
2506
2603
|
height: Math.round(Math.max(20, maxY - minY))
|
|
2507
2604
|
};
|
|
2508
2605
|
} else {
|
|
2509
|
-
newCrop = (0,
|
|
2606
|
+
newCrop = (0, import_image_editor15.calculateCropDrag)(
|
|
2510
2607
|
drag.startCrop,
|
|
2511
2608
|
drag.handle,
|
|
2512
2609
|
drag.startImgPt,
|
|
@@ -2526,15 +2623,15 @@ var ImageEditor = ({
|
|
|
2526
2623
|
width: state.imageDimensions.width,
|
|
2527
2624
|
height: state.imageDimensions.height
|
|
2528
2625
|
};
|
|
2529
|
-
const handle = (0,
|
|
2530
|
-
canvas.style.cursor = (0,
|
|
2626
|
+
const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2627
|
+
canvas.style.cursor = (0, import_image_editor15.getCropCursor)(handle, state.transform);
|
|
2531
2628
|
}
|
|
2532
2629
|
return;
|
|
2533
2630
|
}
|
|
2534
2631
|
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
2535
2632
|
const g = shapeGestureRef.current;
|
|
2536
2633
|
if (g.active) {
|
|
2537
|
-
g.move((0,
|
|
2634
|
+
g.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
|
|
2538
2635
|
if (g.error) setShapeTypeError(g.error);
|
|
2539
2636
|
}
|
|
2540
2637
|
return;
|
|
@@ -2542,7 +2639,7 @@ var ImageEditor = ({
|
|
|
2542
2639
|
if (activeTab === "annotate") {
|
|
2543
2640
|
if (annotationDragInfoRef.current) {
|
|
2544
2641
|
const drag = annotationDragInfoRef.current;
|
|
2545
|
-
const currentImgPt2 = (0,
|
|
2642
|
+
const currentImgPt2 = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2546
2643
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
2547
2644
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
2548
2645
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -2554,10 +2651,10 @@ var ImageEditor = ({
|
|
|
2554
2651
|
const startPt = dragStartPointRef.current;
|
|
2555
2652
|
if (!startPt) {
|
|
2556
2653
|
if (state.activeTool === "select") {
|
|
2557
|
-
const imgPt = (0,
|
|
2654
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2558
2655
|
let hovered = false;
|
|
2559
2656
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
2560
|
-
if ((0,
|
|
2657
|
+
if ((0, import_image_editor15.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
2561
2658
|
hovered = true;
|
|
2562
2659
|
break;
|
|
2563
2660
|
}
|
|
@@ -2568,7 +2665,7 @@ var ImageEditor = ({
|
|
|
2568
2665
|
}
|
|
2569
2666
|
return;
|
|
2570
2667
|
}
|
|
2571
|
-
const currentImgPt = (0,
|
|
2668
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2572
2669
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2573
2670
|
currentPathRef.current.push(currentImgPt);
|
|
2574
2671
|
const draft = {
|
|
@@ -2648,7 +2745,7 @@ var ImageEditor = ({
|
|
|
2648
2745
|
if (activeTab === "select") {
|
|
2649
2746
|
const gesture = selectionGestureRef.current;
|
|
2650
2747
|
if (gesture.active) {
|
|
2651
|
-
gesture.end((0,
|
|
2748
|
+
gesture.end((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
2652
2749
|
selectionDraftRef.current = null;
|
|
2653
2750
|
renderCanvas();
|
|
2654
2751
|
}
|
|
@@ -2671,7 +2768,7 @@ var ImageEditor = ({
|
|
|
2671
2768
|
}
|
|
2672
2769
|
if (activeTab === "annotate" && state.activeTool === "type") {
|
|
2673
2770
|
const tool = typeToolRef.current;
|
|
2674
|
-
tool.up((0,
|
|
2771
|
+
tool.up((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
|
|
2675
2772
|
setTypeSession(tool.session);
|
|
2676
2773
|
if (tool.error) setShapeTypeError(tool.error);
|
|
2677
2774
|
void renderCanvas();
|
|
@@ -2685,7 +2782,7 @@ var ImageEditor = ({
|
|
|
2685
2782
|
}
|
|
2686
2783
|
const startPt = dragStartPointRef.current;
|
|
2687
2784
|
if (startPt) {
|
|
2688
|
-
const currentImgPt = (0,
|
|
2785
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2689
2786
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2690
2787
|
if (currentPathRef.current.length > 1) {
|
|
2691
2788
|
editor.addAnnotation({
|
|
@@ -2781,15 +2878,15 @@ var ImageEditor = ({
|
|
|
2781
2878
|
link.click();
|
|
2782
2879
|
}
|
|
2783
2880
|
};
|
|
2784
|
-
return /* @__PURE__ */ (0,
|
|
2881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2785
2882
|
"div",
|
|
2786
2883
|
{
|
|
2787
2884
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
2788
2885
|
style,
|
|
2789
2886
|
children: [
|
|
2790
|
-
/* @__PURE__ */ (0,
|
|
2791
|
-
/* @__PURE__ */ (0,
|
|
2792
|
-
/* @__PURE__ */ (0,
|
|
2887
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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: [
|
|
2888
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
2889
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2793
2890
|
"button",
|
|
2794
2891
|
{
|
|
2795
2892
|
type: "button",
|
|
@@ -2801,7 +2898,7 @@ var ImageEditor = ({
|
|
|
2801
2898
|
children: "Transform & Crop"
|
|
2802
2899
|
}
|
|
2803
2900
|
),
|
|
2804
|
-
/* @__PURE__ */ (0,
|
|
2901
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2805
2902
|
"button",
|
|
2806
2903
|
{
|
|
2807
2904
|
type: "button",
|
|
@@ -2813,7 +2910,7 @@ var ImageEditor = ({
|
|
|
2813
2910
|
children: "Adjustments"
|
|
2814
2911
|
}
|
|
2815
2912
|
),
|
|
2816
|
-
/* @__PURE__ */ (0,
|
|
2913
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2817
2914
|
"button",
|
|
2818
2915
|
{
|
|
2819
2916
|
type: "button",
|
|
@@ -2825,7 +2922,7 @@ var ImageEditor = ({
|
|
|
2825
2922
|
children: "Layers"
|
|
2826
2923
|
}
|
|
2827
2924
|
),
|
|
2828
|
-
/* @__PURE__ */ (0,
|
|
2925
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2829
2926
|
"button",
|
|
2830
2927
|
{
|
|
2831
2928
|
type: "button",
|
|
@@ -2837,7 +2934,7 @@ var ImageEditor = ({
|
|
|
2837
2934
|
children: "Paint"
|
|
2838
2935
|
}
|
|
2839
2936
|
),
|
|
2840
|
-
/* @__PURE__ */ (0,
|
|
2937
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2841
2938
|
"button",
|
|
2842
2939
|
{
|
|
2843
2940
|
type: "button",
|
|
@@ -2849,7 +2946,7 @@ var ImageEditor = ({
|
|
|
2849
2946
|
children: "Select & Mask"
|
|
2850
2947
|
}
|
|
2851
2948
|
),
|
|
2852
|
-
/* @__PURE__ */ (0,
|
|
2949
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2853
2950
|
"button",
|
|
2854
2951
|
{
|
|
2855
2952
|
type: "button",
|
|
@@ -2861,7 +2958,7 @@ var ImageEditor = ({
|
|
|
2861
2958
|
children: "Annotations"
|
|
2862
2959
|
}
|
|
2863
2960
|
),
|
|
2864
|
-
/* @__PURE__ */ (0,
|
|
2961
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2865
2962
|
"button",
|
|
2866
2963
|
{
|
|
2867
2964
|
type: "button",
|
|
@@ -2873,7 +2970,7 @@ var ImageEditor = ({
|
|
|
2873
2970
|
children: "Depth Mask"
|
|
2874
2971
|
}
|
|
2875
2972
|
),
|
|
2876
|
-
/* @__PURE__ */ (0,
|
|
2973
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2877
2974
|
"button",
|
|
2878
2975
|
{
|
|
2879
2976
|
type: "button",
|
|
@@ -2883,14 +2980,14 @@ var ImageEditor = ({
|
|
|
2883
2980
|
},
|
|
2884
2981
|
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"}`,
|
|
2885
2982
|
children: [
|
|
2886
|
-
/* @__PURE__ */ (0,
|
|
2983
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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_runtime14.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" }) }),
|
|
2887
2984
|
"AI Tools"
|
|
2888
2985
|
]
|
|
2889
2986
|
}
|
|
2890
2987
|
)
|
|
2891
2988
|
] }),
|
|
2892
|
-
/* @__PURE__ */ (0,
|
|
2893
|
-
/* @__PURE__ */ (0,
|
|
2989
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2990
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2894
2991
|
"button",
|
|
2895
2992
|
{
|
|
2896
2993
|
type: "button",
|
|
@@ -2901,7 +2998,7 @@ var ImageEditor = ({
|
|
|
2901
2998
|
children: "\u21A9"
|
|
2902
2999
|
}
|
|
2903
3000
|
),
|
|
2904
|
-
/* @__PURE__ */ (0,
|
|
3001
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2905
3002
|
"button",
|
|
2906
3003
|
{
|
|
2907
3004
|
type: "button",
|
|
@@ -2912,7 +3009,7 @@ var ImageEditor = ({
|
|
|
2912
3009
|
children: "\u21AA"
|
|
2913
3010
|
}
|
|
2914
3011
|
),
|
|
2915
|
-
/* @__PURE__ */ (0,
|
|
3012
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2916
3013
|
"button",
|
|
2917
3014
|
{
|
|
2918
3015
|
type: "button",
|
|
@@ -2921,8 +3018,8 @@ var ImageEditor = ({
|
|
|
2921
3018
|
children: "Reset"
|
|
2922
3019
|
}
|
|
2923
3020
|
),
|
|
2924
|
-
/* @__PURE__ */ (0,
|
|
2925
|
-
/* @__PURE__ */ (0,
|
|
3021
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
3022
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2926
3023
|
"button",
|
|
2927
3024
|
{
|
|
2928
3025
|
type: "button",
|
|
@@ -2932,11 +3029,11 @@ var ImageEditor = ({
|
|
|
2932
3029
|
children: "-"
|
|
2933
3030
|
}
|
|
2934
3031
|
),
|
|
2935
|
-
/* @__PURE__ */ (0,
|
|
3032
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
2936
3033
|
Math.round(state.zoom * 100),
|
|
2937
3034
|
"%"
|
|
2938
3035
|
] }),
|
|
2939
|
-
/* @__PURE__ */ (0,
|
|
3036
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2940
3037
|
"button",
|
|
2941
3038
|
{
|
|
2942
3039
|
type: "button",
|
|
@@ -2946,8 +3043,8 @@ var ImageEditor = ({
|
|
|
2946
3043
|
children: "+"
|
|
2947
3044
|
}
|
|
2948
3045
|
),
|
|
2949
|
-
/* @__PURE__ */ (0,
|
|
2950
|
-
/* @__PURE__ */ (0,
|
|
3046
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
3047
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2951
3048
|
"button",
|
|
2952
3049
|
{
|
|
2953
3050
|
type: "button",
|
|
@@ -2958,7 +3055,7 @@ var ImageEditor = ({
|
|
|
2958
3055
|
children: "Hold Compare"
|
|
2959
3056
|
}
|
|
2960
3057
|
),
|
|
2961
|
-
/* @__PURE__ */ (0,
|
|
3058
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2962
3059
|
"button",
|
|
2963
3060
|
{
|
|
2964
3061
|
type: "button",
|
|
@@ -2969,16 +3066,16 @@ var ImageEditor = ({
|
|
|
2969
3066
|
)
|
|
2970
3067
|
] })
|
|
2971
3068
|
] }),
|
|
2972
|
-
transformTool.active && /* @__PURE__ */ (0,
|
|
2973
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */ (0,
|
|
2974
|
-
/* @__PURE__ */ (0,
|
|
2975
|
-
/* @__PURE__ */ (0,
|
|
3069
|
+
transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
|
|
3070
|
+
!transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime14.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 }),
|
|
3071
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
3072
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2976
3073
|
"div",
|
|
2977
3074
|
{
|
|
2978
3075
|
ref: containerRef,
|
|
2979
3076
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
2980
3077
|
children: [
|
|
2981
|
-
/* @__PURE__ */ (0,
|
|
3078
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2982
3079
|
"canvas",
|
|
2983
3080
|
{
|
|
2984
3081
|
ref: canvasRef,
|
|
@@ -2995,7 +3092,7 @@ var ImageEditor = ({
|
|
|
2995
3092
|
className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : activeTab === "annotate" && state.activeTool === "type" ? "cursor-text" : activeTab === "annotate" && state.activeTool === "shape" ? "cursor-crosshair" : ""}`
|
|
2996
3093
|
}
|
|
2997
3094
|
),
|
|
2998
|
-
typeSession && /* @__PURE__ */ (0,
|
|
3095
|
+
typeSession && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2999
3096
|
"textarea",
|
|
3000
3097
|
{
|
|
3001
3098
|
ref: typeInputRef,
|
|
@@ -3017,11 +3114,11 @@ var ImageEditor = ({
|
|
|
3017
3114
|
]
|
|
3018
3115
|
}
|
|
3019
3116
|
),
|
|
3020
|
-
/* @__PURE__ */ (0,
|
|
3021
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
3022
|
-
/* @__PURE__ */ (0,
|
|
3023
|
-
/* @__PURE__ */ (0,
|
|
3024
|
-
/* @__PURE__ */ (0,
|
|
3117
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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: [
|
|
3118
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3119
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
3120
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
3121
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3025
3122
|
"button",
|
|
3026
3123
|
{
|
|
3027
3124
|
type: "button",
|
|
@@ -3033,7 +3130,7 @@ var ImageEditor = ({
|
|
|
3033
3130
|
children: "Freeform"
|
|
3034
3131
|
}
|
|
3035
3132
|
),
|
|
3036
|
-
/* @__PURE__ */ (0,
|
|
3133
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3037
3134
|
"button",
|
|
3038
3135
|
{
|
|
3039
3136
|
type: "button",
|
|
@@ -3045,7 +3142,7 @@ var ImageEditor = ({
|
|
|
3045
3142
|
children: "1:1 Square"
|
|
3046
3143
|
}
|
|
3047
3144
|
),
|
|
3048
|
-
/* @__PURE__ */ (0,
|
|
3145
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3049
3146
|
"button",
|
|
3050
3147
|
{
|
|
3051
3148
|
type: "button",
|
|
@@ -3057,7 +3154,7 @@ var ImageEditor = ({
|
|
|
3057
3154
|
children: "4:3 Standard"
|
|
3058
3155
|
}
|
|
3059
3156
|
),
|
|
3060
|
-
/* @__PURE__ */ (0,
|
|
3157
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3061
3158
|
"button",
|
|
3062
3159
|
{
|
|
3063
3160
|
type: "button",
|
|
@@ -3069,7 +3166,7 @@ var ImageEditor = ({
|
|
|
3069
3166
|
children: "16:9 Wide"
|
|
3070
3167
|
}
|
|
3071
3168
|
),
|
|
3072
|
-
/* @__PURE__ */ (0,
|
|
3169
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3073
3170
|
"button",
|
|
3074
3171
|
{
|
|
3075
3172
|
type: "button",
|
|
@@ -3081,7 +3178,7 @@ var ImageEditor = ({
|
|
|
3081
3178
|
children: "3:2 Photo"
|
|
3082
3179
|
}
|
|
3083
3180
|
),
|
|
3084
|
-
/* @__PURE__ */ (0,
|
|
3181
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3085
3182
|
"button",
|
|
3086
3183
|
{
|
|
3087
3184
|
type: "button",
|
|
@@ -3094,10 +3191,10 @@ var ImageEditor = ({
|
|
|
3094
3191
|
}
|
|
3095
3192
|
)
|
|
3096
3193
|
] }),
|
|
3097
|
-
/* @__PURE__ */ (0,
|
|
3098
|
-
/* @__PURE__ */ (0,
|
|
3099
|
-
/* @__PURE__ */ (0,
|
|
3100
|
-
/* @__PURE__ */ (0,
|
|
3194
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3195
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
3196
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
3197
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3101
3198
|
"button",
|
|
3102
3199
|
{
|
|
3103
3200
|
type: "button",
|
|
@@ -3106,7 +3203,7 @@ var ImageEditor = ({
|
|
|
3106
3203
|
children: "Rotate -90\xB0"
|
|
3107
3204
|
}
|
|
3108
3205
|
),
|
|
3109
|
-
/* @__PURE__ */ (0,
|
|
3206
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3110
3207
|
"button",
|
|
3111
3208
|
{
|
|
3112
3209
|
type: "button",
|
|
@@ -3115,7 +3212,7 @@ var ImageEditor = ({
|
|
|
3115
3212
|
children: "Rotate +90\xB0"
|
|
3116
3213
|
}
|
|
3117
3214
|
),
|
|
3118
|
-
/* @__PURE__ */ (0,
|
|
3215
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3119
3216
|
"button",
|
|
3120
3217
|
{
|
|
3121
3218
|
type: "button",
|
|
@@ -3124,7 +3221,7 @@ var ImageEditor = ({
|
|
|
3124
3221
|
children: "Flip Horizontal"
|
|
3125
3222
|
}
|
|
3126
3223
|
),
|
|
3127
|
-
/* @__PURE__ */ (0,
|
|
3224
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3128
3225
|
"button",
|
|
3129
3226
|
{
|
|
3130
3227
|
type: "button",
|
|
@@ -3135,10 +3232,10 @@ var ImageEditor = ({
|
|
|
3135
3232
|
)
|
|
3136
3233
|
] })
|
|
3137
3234
|
] }),
|
|
3138
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
3139
|
-
/* @__PURE__ */ (0,
|
|
3140
|
-
/* @__PURE__ */ (0,
|
|
3141
|
-
/* @__PURE__ */ (0,
|
|
3235
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3236
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3237
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
3238
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3142
3239
|
"button",
|
|
3143
3240
|
{
|
|
3144
3241
|
type: "button",
|
|
@@ -3148,25 +3245,25 @@ var ImageEditor = ({
|
|
|
3148
3245
|
}
|
|
3149
3246
|
)
|
|
3150
3247
|
] }),
|
|
3151
|
-
/* @__PURE__ */ (0,
|
|
3152
|
-
|
|
3153
|
-
/* @__PURE__ */ (0,
|
|
3248
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Histogram, { histogram: editor.histogram }),
|
|
3249
|
+
import_image_editor15.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react14.default.Fragment, { children: [
|
|
3250
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3154
3251
|
ControlSlider,
|
|
3155
3252
|
{
|
|
3156
3253
|
spec,
|
|
3157
|
-
value: (0,
|
|
3254
|
+
value: (0, import_image_editor15.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
3158
3255
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
3159
3256
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
3160
3257
|
}
|
|
3161
3258
|
),
|
|
3162
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
3259
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3163
3260
|
"div",
|
|
3164
3261
|
{
|
|
3165
3262
|
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",
|
|
3166
3263
|
"data-testid": "image-editor-process-notice",
|
|
3167
3264
|
children: [
|
|
3168
|
-
/* @__PURE__ */ (0,
|
|
3169
|
-
/* @__PURE__ */ (0,
|
|
3265
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
3266
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3170
3267
|
"button",
|
|
3171
3268
|
{
|
|
3172
3269
|
type: "button",
|
|
@@ -3179,7 +3276,7 @@ var ImageEditor = ({
|
|
|
3179
3276
|
}
|
|
3180
3277
|
)
|
|
3181
3278
|
] }, spec.id)),
|
|
3182
|
-
/* @__PURE__ */ (0,
|
|
3279
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3183
3280
|
AdjustmentLayersPanel,
|
|
3184
3281
|
{
|
|
3185
3282
|
controller,
|
|
@@ -3188,9 +3285,9 @@ var ImageEditor = ({
|
|
|
3188
3285
|
}
|
|
3189
3286
|
) })
|
|
3190
3287
|
] }),
|
|
3191
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
3192
|
-
/* @__PURE__ */ (0,
|
|
3193
|
-
/* @__PURE__ */ (0,
|
|
3288
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3289
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
3290
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3194
3291
|
"button",
|
|
3195
3292
|
{
|
|
3196
3293
|
type: "button",
|
|
@@ -3201,12 +3298,14 @@ var ImageEditor = ({
|
|
|
3201
3298
|
children: "Free Transform"
|
|
3202
3299
|
}
|
|
3203
3300
|
),
|
|
3204
|
-
/* @__PURE__ */ (0,
|
|
3301
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LayersPanel, { controller }),
|
|
3302
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
|
|
3303
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ColorProfilePanel, { controller })
|
|
3205
3304
|
] }),
|
|
3206
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
3207
|
-
/* @__PURE__ */ (0,
|
|
3208
|
-
/* @__PURE__ */ (0,
|
|
3209
|
-
/* @__PURE__ */ (0,
|
|
3305
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3306
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
3307
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BrushOptionsBar, { controller }),
|
|
3308
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3210
3309
|
"button",
|
|
3211
3310
|
{
|
|
3212
3311
|
type: "button",
|
|
@@ -3217,12 +3316,12 @@ var ImageEditor = ({
|
|
|
3217
3316
|
children: "Free Transform"
|
|
3218
3317
|
}
|
|
3219
3318
|
),
|
|
3220
|
-
paintError && /* @__PURE__ */ (0,
|
|
3221
|
-
/* @__PURE__ */ (0,
|
|
3319
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
3320
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LayersPanel, { controller }) })
|
|
3222
3321
|
] }),
|
|
3223
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
3224
|
-
/* @__PURE__ */ (0,
|
|
3225
|
-
/* @__PURE__ */ (0,
|
|
3322
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3323
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
|
|
3324
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3226
3325
|
"button",
|
|
3227
3326
|
{
|
|
3228
3327
|
type: "button",
|
|
@@ -3233,13 +3332,13 @@ var ImageEditor = ({
|
|
|
3233
3332
|
},
|
|
3234
3333
|
t
|
|
3235
3334
|
)) }),
|
|
3236
|
-
state.activeTool === "shape" && /* @__PURE__ */ (0,
|
|
3237
|
-
state.activeTool === "type" && /* @__PURE__ */ (0,
|
|
3238
|
-
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0,
|
|
3239
|
-
shapeTypeError && /* @__PURE__ */ (0,
|
|
3240
|
-
/* @__PURE__ */ (0,
|
|
3241
|
-
/* @__PURE__ */ (0,
|
|
3242
|
-
/* @__PURE__ */ (0,
|
|
3335
|
+
state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
|
|
3336
|
+
state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
|
|
3337
|
+
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", onClick: finishTyping, className: "self-start rounded bg-slate-800 px-2 py-1 text-[11px] text-slate-200 hover:bg-slate-700", children: "Done editing text" }),
|
|
3338
|
+
shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
|
|
3339
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3340
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
3341
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3243
3342
|
"button",
|
|
3244
3343
|
{
|
|
3245
3344
|
type: "button",
|
|
@@ -3249,9 +3348,9 @@ var ImageEditor = ({
|
|
|
3249
3348
|
},
|
|
3250
3349
|
t
|
|
3251
3350
|
)) }),
|
|
3252
|
-
/* @__PURE__ */ (0,
|
|
3253
|
-
/* @__PURE__ */ (0,
|
|
3254
|
-
/* @__PURE__ */ (0,
|
|
3351
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
3352
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
3353
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3255
3354
|
"input",
|
|
3256
3355
|
{
|
|
3257
3356
|
type: "color",
|
|
@@ -3260,15 +3359,15 @@ var ImageEditor = ({
|
|
|
3260
3359
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
3261
3360
|
}
|
|
3262
3361
|
),
|
|
3263
|
-
/* @__PURE__ */ (0,
|
|
3264
|
-
/* @__PURE__ */ (0,
|
|
3265
|
-
/* @__PURE__ */ (0,
|
|
3266
|
-
/* @__PURE__ */ (0,
|
|
3362
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
3363
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
3364
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Width:" }),
|
|
3365
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-mono", children: [
|
|
3267
3366
|
strokeWidth,
|
|
3268
3367
|
"px"
|
|
3269
3368
|
] })
|
|
3270
3369
|
] }),
|
|
3271
|
-
/* @__PURE__ */ (0,
|
|
3370
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3272
3371
|
"input",
|
|
3273
3372
|
{
|
|
3274
3373
|
type: "range",
|
|
@@ -3281,10 +3380,10 @@ var ImageEditor = ({
|
|
|
3281
3380
|
)
|
|
3282
3381
|
] })
|
|
3283
3382
|
] }),
|
|
3284
|
-
/* @__PURE__ */ (0,
|
|
3285
|
-
/* @__PURE__ */ (0,
|
|
3286
|
-
/* @__PURE__ */ (0,
|
|
3287
|
-
/* @__PURE__ */ (0,
|
|
3383
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3384
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
3385
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-2", children: [
|
|
3386
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3288
3387
|
"input",
|
|
3289
3388
|
{
|
|
3290
3389
|
type: "text",
|
|
@@ -3295,7 +3394,7 @@ var ImageEditor = ({
|
|
|
3295
3394
|
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"
|
|
3296
3395
|
}
|
|
3297
3396
|
),
|
|
3298
|
-
/* @__PURE__ */ (0,
|
|
3397
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3299
3398
|
"button",
|
|
3300
3399
|
{
|
|
3301
3400
|
type: "button",
|
|
@@ -3305,14 +3404,14 @@ var ImageEditor = ({
|
|
|
3305
3404
|
}
|
|
3306
3405
|
)
|
|
3307
3406
|
] }),
|
|
3308
|
-
/* @__PURE__ */ (0,
|
|
3309
|
-
/* @__PURE__ */ (0,
|
|
3310
|
-
/* @__PURE__ */ (0,
|
|
3407
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
3408
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Font Size:" }),
|
|
3409
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-mono", children: [
|
|
3311
3410
|
fontSize,
|
|
3312
3411
|
"px"
|
|
3313
3412
|
] })
|
|
3314
3413
|
] }),
|
|
3315
|
-
/* @__PURE__ */ (0,
|
|
3414
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3316
3415
|
"input",
|
|
3317
3416
|
{
|
|
3318
3417
|
type: "range",
|
|
@@ -3323,14 +3422,14 @@ var ImageEditor = ({
|
|
|
3323
3422
|
className: "w-full accent-indigo-500"
|
|
3324
3423
|
}
|
|
3325
3424
|
),
|
|
3326
|
-
/* @__PURE__ */ (0,
|
|
3327
|
-
/* @__PURE__ */ (0,
|
|
3328
|
-
/* @__PURE__ */ (0,
|
|
3425
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3426
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3427
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-slate-400", children: [
|
|
3329
3428
|
"Layers (",
|
|
3330
3429
|
state.annotations.length,
|
|
3331
3430
|
")"
|
|
3332
3431
|
] }),
|
|
3333
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
3432
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3334
3433
|
"button",
|
|
3335
3434
|
{
|
|
3336
3435
|
type: "button",
|
|
@@ -3339,7 +3438,7 @@ var ImageEditor = ({
|
|
|
3339
3438
|
children: "Delete Selected"
|
|
3340
3439
|
}
|
|
3341
3440
|
),
|
|
3342
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
3441
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3343
3442
|
"button",
|
|
3344
3443
|
{
|
|
3345
3444
|
type: "button",
|
|
@@ -3350,10 +3449,10 @@ var ImageEditor = ({
|
|
|
3350
3449
|
)
|
|
3351
3450
|
] })
|
|
3352
3451
|
] }),
|
|
3353
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
3354
|
-
/* @__PURE__ */ (0,
|
|
3355
|
-
/* @__PURE__ */ (0,
|
|
3356
|
-
/* @__PURE__ */ (0,
|
|
3452
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3453
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3454
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
3455
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3357
3456
|
"button",
|
|
3358
3457
|
{
|
|
3359
3458
|
type: "button",
|
|
@@ -3363,8 +3462,8 @@ var ImageEditor = ({
|
|
|
3363
3462
|
}
|
|
3364
3463
|
)
|
|
3365
3464
|
] }),
|
|
3366
|
-
/* @__PURE__ */ (0,
|
|
3367
|
-
/* @__PURE__ */ (0,
|
|
3465
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
3466
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3368
3467
|
"input",
|
|
3369
3468
|
{
|
|
3370
3469
|
type: "checkbox",
|
|
@@ -3373,12 +3472,12 @@ var ImageEditor = ({
|
|
|
3373
3472
|
className: "rounded accent-indigo-500"
|
|
3374
3473
|
}
|
|
3375
3474
|
),
|
|
3376
|
-
/* @__PURE__ */ (0,
|
|
3475
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
3377
3476
|
] }),
|
|
3378
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
3379
|
-
/* @__PURE__ */ (0,
|
|
3380
|
-
/* @__PURE__ */ (0,
|
|
3381
|
-
/* @__PURE__ */ (0,
|
|
3477
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3478
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3479
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
3480
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3382
3481
|
"input",
|
|
3383
3482
|
{
|
|
3384
3483
|
type: "text",
|
|
@@ -3389,8 +3488,8 @@ var ImageEditor = ({
|
|
|
3389
3488
|
}
|
|
3390
3489
|
)
|
|
3391
3490
|
] }),
|
|
3392
|
-
/* @__PURE__ */ (0,
|
|
3393
|
-
/* @__PURE__ */ (0,
|
|
3491
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-2", children: [
|
|
3492
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3394
3493
|
"button",
|
|
3395
3494
|
{
|
|
3396
3495
|
type: "button",
|
|
@@ -3399,7 +3498,7 @@ var ImageEditor = ({
|
|
|
3399
3498
|
children: "Threshold Mode"
|
|
3400
3499
|
}
|
|
3401
3500
|
),
|
|
3402
|
-
/* @__PURE__ */ (0,
|
|
3501
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3403
3502
|
"button",
|
|
3404
3503
|
{
|
|
3405
3504
|
type: "button",
|
|
@@ -3409,12 +3508,12 @@ var ImageEditor = ({
|
|
|
3409
3508
|
}
|
|
3410
3509
|
)
|
|
3411
3510
|
] }),
|
|
3412
|
-
/* @__PURE__ */ (0,
|
|
3413
|
-
/* @__PURE__ */ (0,
|
|
3414
|
-
/* @__PURE__ */ (0,
|
|
3415
|
-
/* @__PURE__ */ (0,
|
|
3511
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3512
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3513
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
3514
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
3416
3515
|
] }),
|
|
3417
|
-
/* @__PURE__ */ (0,
|
|
3516
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3418
3517
|
"input",
|
|
3419
3518
|
{
|
|
3420
3519
|
type: "range",
|
|
@@ -3428,12 +3527,12 @@ var ImageEditor = ({
|
|
|
3428
3527
|
}
|
|
3429
3528
|
)
|
|
3430
3529
|
] }),
|
|
3431
|
-
/* @__PURE__ */ (0,
|
|
3432
|
-
/* @__PURE__ */ (0,
|
|
3433
|
-
/* @__PURE__ */ (0,
|
|
3434
|
-
/* @__PURE__ */ (0,
|
|
3530
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3531
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3532
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
3533
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
3435
3534
|
] }),
|
|
3436
|
-
/* @__PURE__ */ (0,
|
|
3535
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3437
3536
|
"input",
|
|
3438
3537
|
{
|
|
3439
3538
|
type: "range",
|
|
@@ -3447,12 +3546,12 @@ var ImageEditor = ({
|
|
|
3447
3546
|
}
|
|
3448
3547
|
)
|
|
3449
3548
|
] }),
|
|
3450
|
-
/* @__PURE__ */ (0,
|
|
3451
|
-
/* @__PURE__ */ (0,
|
|
3452
|
-
/* @__PURE__ */ (0,
|
|
3453
|
-
/* @__PURE__ */ (0,
|
|
3549
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3550
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3551
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Softness:" }),
|
|
3552
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
3454
3553
|
] }),
|
|
3455
|
-
/* @__PURE__ */ (0,
|
|
3554
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3456
3555
|
"input",
|
|
3457
3556
|
{
|
|
3458
3557
|
type: "range",
|
|
@@ -3464,8 +3563,8 @@ var ImageEditor = ({
|
|
|
3464
3563
|
}
|
|
3465
3564
|
)
|
|
3466
3565
|
] }),
|
|
3467
|
-
/* @__PURE__ */ (0,
|
|
3468
|
-
/* @__PURE__ */ (0,
|
|
3566
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
3567
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3469
3568
|
"input",
|
|
3470
3569
|
{
|
|
3471
3570
|
type: "checkbox",
|
|
@@ -3474,12 +3573,12 @@ var ImageEditor = ({
|
|
|
3474
3573
|
className: "rounded accent-indigo-500"
|
|
3475
3574
|
}
|
|
3476
3575
|
),
|
|
3477
|
-
/* @__PURE__ */ (0,
|
|
3576
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Invert Mask" })
|
|
3478
3577
|
] })
|
|
3479
3578
|
] })
|
|
3480
3579
|
] }),
|
|
3481
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
3482
|
-
/* @__PURE__ */ (0,
|
|
3580
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3581
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3483
3582
|
SelectionOptionsBar,
|
|
3484
3583
|
{
|
|
3485
3584
|
controller,
|
|
@@ -3489,9 +3588,9 @@ var ImageEditor = ({
|
|
|
3489
3588
|
quickMask: Boolean(state.quickMask)
|
|
3490
3589
|
}
|
|
3491
3590
|
),
|
|
3492
|
-
selectionError && /* @__PURE__ */ (0,
|
|
3493
|
-
/* @__PURE__ */ (0,
|
|
3494
|
-
/* @__PURE__ */ (0,
|
|
3591
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
3592
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-1", children: [
|
|
3593
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3495
3594
|
"button",
|
|
3496
3595
|
{
|
|
3497
3596
|
type: "button",
|
|
@@ -3502,7 +3601,7 @@ var ImageEditor = ({
|
|
|
3502
3601
|
children: "Transform Selection"
|
|
3503
3602
|
}
|
|
3504
3603
|
),
|
|
3505
|
-
/* @__PURE__ */ (0,
|
|
3604
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3506
3605
|
"button",
|
|
3507
3606
|
{
|
|
3508
3607
|
type: "button",
|
|
@@ -3514,12 +3613,12 @@ var ImageEditor = ({
|
|
|
3514
3613
|
}
|
|
3515
3614
|
)
|
|
3516
3615
|
] }),
|
|
3517
|
-
/* @__PURE__ */ (0,
|
|
3616
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
3518
3617
|
] }),
|
|
3519
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
3520
|
-
/* @__PURE__ */ (0,
|
|
3521
|
-
/* @__PURE__ */ (0,
|
|
3522
|
-
/* @__PURE__ */ (0,
|
|
3618
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3619
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
3620
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Results go to" }),
|
|
3621
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3523
3622
|
"select",
|
|
3524
3623
|
{
|
|
3525
3624
|
"aria-label": "AI result target",
|
|
@@ -3527,54 +3626,54 @@ var ImageEditor = ({
|
|
|
3527
3626
|
onChange: (e) => setAiTarget(e.target.value),
|
|
3528
3627
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
3529
3628
|
children: [
|
|
3530
|
-
/* @__PURE__ */ (0,
|
|
3531
|
-
/* @__PURE__ */ (0,
|
|
3532
|
-
/* @__PURE__ */ (0,
|
|
3629
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
3630
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
3631
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "replace", children: "Replace image" })
|
|
3533
3632
|
]
|
|
3534
3633
|
}
|
|
3535
3634
|
)
|
|
3536
3635
|
] }),
|
|
3537
|
-
/* @__PURE__ */ (0,
|
|
3538
|
-
/* @__PURE__ */ (0,
|
|
3539
|
-
/* @__PURE__ */ (0,
|
|
3540
|
-
/* @__PURE__ */ (0,
|
|
3636
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3637
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3638
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3639
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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_runtime14.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" }) }),
|
|
3541
3640
|
"Background Removal"
|
|
3542
3641
|
] }),
|
|
3543
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
3642
|
+
isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime14.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..." })
|
|
3544
3643
|
] }),
|
|
3545
|
-
/* @__PURE__ */ (0,
|
|
3546
|
-
/* @__PURE__ */ (0,
|
|
3644
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
3645
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3547
3646
|
"button",
|
|
3548
3647
|
{
|
|
3549
3648
|
type: "button",
|
|
3550
3649
|
onClick: handleRemoveBackground,
|
|
3551
3650
|
disabled: isRemovingBg || isInpainting,
|
|
3552
3651
|
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",
|
|
3553
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
3554
|
-
/* @__PURE__ */ (0,
|
|
3652
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3653
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
3555
3654
|
"Removing Background..."
|
|
3556
|
-
] }) : /* @__PURE__ */ (0,
|
|
3557
|
-
/* @__PURE__ */ (0,
|
|
3655
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3656
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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_runtime14.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" }) }),
|
|
3558
3657
|
"Remove Background"
|
|
3559
3658
|
] })
|
|
3560
3659
|
}
|
|
3561
3660
|
)
|
|
3562
3661
|
] }),
|
|
3563
|
-
/* @__PURE__ */ (0,
|
|
3564
|
-
/* @__PURE__ */ (0,
|
|
3565
|
-
/* @__PURE__ */ (0,
|
|
3566
|
-
/* @__PURE__ */ (0,
|
|
3567
|
-
/* @__PURE__ */ (0,
|
|
3568
|
-
/* @__PURE__ */ (0,
|
|
3662
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3663
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3664
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3665
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
3666
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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" }),
|
|
3667
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "m14 7 3 3" })
|
|
3569
3668
|
] }),
|
|
3570
3669
|
"Generative Inpainting"
|
|
3571
3670
|
] }),
|
|
3572
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
3671
|
+
isInpainting && /* @__PURE__ */ (0, import_jsx_runtime14.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..." })
|
|
3573
3672
|
] }),
|
|
3574
|
-
/* @__PURE__ */ (0,
|
|
3575
|
-
/* @__PURE__ */ (0,
|
|
3576
|
-
/* @__PURE__ */ (0,
|
|
3577
|
-
/* @__PURE__ */ (0,
|
|
3673
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
3674
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3675
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
3676
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3578
3677
|
"textarea",
|
|
3579
3678
|
{
|
|
3580
3679
|
id: "ai-inpaint-prompt-react",
|
|
@@ -3586,10 +3685,10 @@ var ImageEditor = ({
|
|
|
3586
3685
|
}
|
|
3587
3686
|
)
|
|
3588
3687
|
] }),
|
|
3589
|
-
/* @__PURE__ */ (0,
|
|
3590
|
-
/* @__PURE__ */ (0,
|
|
3591
|
-
/* @__PURE__ */ (0,
|
|
3592
|
-
/* @__PURE__ */ (0,
|
|
3688
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3689
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
3690
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
3691
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3593
3692
|
"button",
|
|
3594
3693
|
{
|
|
3595
3694
|
type: "button",
|
|
@@ -3602,7 +3701,7 @@ var ImageEditor = ({
|
|
|
3602
3701
|
]
|
|
3603
3702
|
}
|
|
3604
3703
|
),
|
|
3605
|
-
/* @__PURE__ */ (0,
|
|
3704
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3606
3705
|
"button",
|
|
3607
3706
|
{
|
|
3608
3707
|
type: "button",
|
|
@@ -3617,25 +3716,25 @@ var ImageEditor = ({
|
|
|
3617
3716
|
)
|
|
3618
3717
|
] })
|
|
3619
3718
|
] }),
|
|
3620
|
-
/* @__PURE__ */ (0,
|
|
3719
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3621
3720
|
"button",
|
|
3622
3721
|
{
|
|
3623
3722
|
type: "button",
|
|
3624
3723
|
onClick: handleInpaint,
|
|
3625
3724
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
3626
3725
|
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",
|
|
3627
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
3628
|
-
/* @__PURE__ */ (0,
|
|
3726
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3727
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
3629
3728
|
"Generating Inpaint..."
|
|
3630
|
-
] }) : /* @__PURE__ */ (0,
|
|
3631
|
-
/* @__PURE__ */ (0,
|
|
3729
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3730
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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_runtime14.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" }) }),
|
|
3632
3731
|
"Apply Inpainting"
|
|
3633
3732
|
] })
|
|
3634
3733
|
}
|
|
3635
3734
|
)
|
|
3636
3735
|
] }),
|
|
3637
|
-
aiError && /* @__PURE__ */ (0,
|
|
3638
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
3736
|
+
aiError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
3737
|
+
aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
3639
3738
|
] })
|
|
3640
3739
|
] })
|
|
3641
3740
|
] })
|
|
@@ -3647,6 +3746,7 @@ var ImageEditor = ({
|
|
|
3647
3746
|
0 && (module.exports = {
|
|
3648
3747
|
AdjustmentLayersPanel,
|
|
3649
3748
|
BrushOptionsBar,
|
|
3749
|
+
ColorProfilePanel,
|
|
3650
3750
|
ControlSlider,
|
|
3651
3751
|
CurvesEditor,
|
|
3652
3752
|
FreeTransformOptionsBar,
|