@pixerate/editor-react 0.71.0 → 0.73.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-63FQB5BT.js → chunk-VNZKHFEM.js} +525 -382
- package/dist/chunk-VNZKHFEM.js.map +1 -0
- package/dist/image-editor/index.cjs +575 -444
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +15 -1
- package/dist/image-editor/index.d.ts +15 -1
- package/dist/image-editor/index.js +3 -1
- package/dist/index.cjs +1004 -873
- 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-63FQB5BT.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" }),
|
|
@@ -1256,7 +1268,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1256
1268
|
(0, import_react7.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1257
1269
|
const [error, setError] = (0, import_react7.useState)(null);
|
|
1258
1270
|
const state = controller.getState();
|
|
1259
|
-
const { brush, foreground, background, mixer, mixerLoad } = state.paint;
|
|
1271
|
+
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource } = state.paint;
|
|
1272
|
+
const tool = state.activeTool;
|
|
1260
1273
|
const attempt = (fn) => {
|
|
1261
1274
|
try {
|
|
1262
1275
|
setError(null);
|
|
@@ -1266,12 +1279,12 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1266
1279
|
}
|
|
1267
1280
|
};
|
|
1268
1281
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "brush-options", children: [
|
|
1269
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Paint tools", children: import_image_editor8.PAINT_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1282
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Paint tools", children: import_image_editor8.PAINT_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1270
1283
|
"button",
|
|
1271
1284
|
{
|
|
1272
1285
|
type: "button",
|
|
1273
1286
|
"aria-pressed": state.activeTool === t.id,
|
|
1274
|
-
title: `${t.label} (${t.shortcut})
|
|
1287
|
+
title: t.shortcut ? `${t.label} (${t.shortcut})` : t.label,
|
|
1275
1288
|
className: chip(state.activeTool === t.id),
|
|
1276
1289
|
onClick: () => controller.setTool(t.id),
|
|
1277
1290
|
children: t.label
|
|
@@ -1373,6 +1386,41 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1373
1386
|
] })
|
|
1374
1387
|
] })
|
|
1375
1388
|
] }),
|
|
1389
|
+
(0, import_image_editor8.isRetouchPaintTool)(tool) && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Retouch options", "data-testid": "retouch-options", children: [
|
|
1390
|
+
(tool === "clone" || tool === "heal") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1391
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-slate-400", "data-testid": "clone-source", children: (0, import_image_editor8.cloneSourceLabel)(controller) }),
|
|
1392
|
+
cloneSource && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", title: "Forget the source point", className: chip(false), onClick: () => controller.setCloneSource(null), children: "Clear source" })
|
|
1393
|
+
] }),
|
|
1394
|
+
import_image_editor8.RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": choice.label, children: [
|
|
1395
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-slate-400", children: choice.label }),
|
|
1396
|
+
choice.options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1397
|
+
"button",
|
|
1398
|
+
{
|
|
1399
|
+
type: "button",
|
|
1400
|
+
"aria-pressed": retouch[choice.id] === o.id,
|
|
1401
|
+
title: o.title,
|
|
1402
|
+
className: chip(retouch[choice.id] === o.id),
|
|
1403
|
+
onClick: () => (0, import_image_editor8.setRetouchChoice)(controller, choice.id, o.id),
|
|
1404
|
+
children: o.label
|
|
1405
|
+
},
|
|
1406
|
+
o.id
|
|
1407
|
+
))
|
|
1408
|
+
] }, choice.id)),
|
|
1409
|
+
import_image_editor8.RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ControlSlider, { spec, value: retouch[spec.id], onChange: (v) => controller.setPaintOptions({ retouch: { [spec.id]: v } }) }, spec.id)),
|
|
1410
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex flex-wrap gap-3 text-slate-300", children: import_image_editor8.RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
1411
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1412
|
+
"input",
|
|
1413
|
+
{
|
|
1414
|
+
type: "checkbox",
|
|
1415
|
+
"aria-label": t.label,
|
|
1416
|
+
checked: retouch[t.id],
|
|
1417
|
+
onChange: (e) => controller.setPaintOptions({ retouch: { [t.id]: e.target.checked } }),
|
|
1418
|
+
className: "accent-indigo-500"
|
|
1419
|
+
}
|
|
1420
|
+
),
|
|
1421
|
+
t.label
|
|
1422
|
+
] }, t.id)) })
|
|
1423
|
+
] }),
|
|
1376
1424
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap gap-3 text-slate-300", role: "group", "aria-label": "Pressure", children: [
|
|
1377
1425
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
1378
1426
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
@@ -1409,10 +1457,90 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1409
1457
|
] });
|
|
1410
1458
|
};
|
|
1411
1459
|
|
|
1412
|
-
// src/image-editor/
|
|
1460
|
+
// src/image-editor/ColorProfilePanel.tsx
|
|
1413
1461
|
var import_react8 = require("react");
|
|
1414
1462
|
var import_image_editor9 = require("@pixerate/editor/image-editor");
|
|
1415
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": "Assign or convert", children: [
|
|
1500
|
+
/* @__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)) }),
|
|
1501
|
+
/* @__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)) }),
|
|
1502
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1503
|
+
/* @__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" }),
|
|
1504
|
+
"BPC"
|
|
1505
|
+
] }),
|
|
1506
|
+
/* @__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" }),
|
|
1507
|
+
/* @__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" })
|
|
1508
|
+
] }),
|
|
1509
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
|
|
1510
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-slate-400", children: "Proof" }),
|
|
1511
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1512
|
+
"select",
|
|
1513
|
+
{
|
|
1514
|
+
"aria-label": "Proof profile",
|
|
1515
|
+
className: select,
|
|
1516
|
+
value: view.proof?.id ?? "",
|
|
1517
|
+
onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
|
|
1518
|
+
children: [
|
|
1519
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "", children: "Off" }),
|
|
1520
|
+
import_image_editor9.PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: o.id, children: o.label }, o.id))
|
|
1521
|
+
]
|
|
1522
|
+
}
|
|
1523
|
+
),
|
|
1524
|
+
view.proof && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
1525
|
+
/* @__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)) }),
|
|
1526
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1527
|
+
/* @__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" }),
|
|
1528
|
+
"Paper"
|
|
1529
|
+
] }),
|
|
1530
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1531
|
+
/* @__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" }),
|
|
1532
|
+
"Gamut warning"
|
|
1533
|
+
] })
|
|
1534
|
+
] })
|
|
1535
|
+
] }),
|
|
1536
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1537
|
+
] });
|
|
1538
|
+
};
|
|
1539
|
+
|
|
1540
|
+
// src/image-editor/SelectionOptionsBar.tsx
|
|
1541
|
+
var import_react9 = require("react");
|
|
1542
|
+
var import_image_editor10 = require("@pixerate/editor/image-editor");
|
|
1543
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1416
1544
|
var MODIFY_OPS = [
|
|
1417
1545
|
{ op: "grow", label: "Grow" },
|
|
1418
1546
|
{ op: "shrink", label: "Shrink" },
|
|
@@ -1429,20 +1557,20 @@ var SelectionOptionsBar = ({
|
|
|
1429
1557
|
quickMask,
|
|
1430
1558
|
className = ""
|
|
1431
1559
|
}) => {
|
|
1432
|
-
const [radius, setRadius] = (0,
|
|
1560
|
+
const [radius, setRadius] = (0, import_react9.useState)(2);
|
|
1433
1561
|
const set = (patch) => onOptionsChange({ ...options, ...patch });
|
|
1434
1562
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
1435
1563
|
const qm = quickMask ?? Boolean(controller.getState().quickMask);
|
|
1436
|
-
return /* @__PURE__ */ (0,
|
|
1437
|
-
/* @__PURE__ */ (0,
|
|
1438
|
-
/* @__PURE__ */ (0,
|
|
1439
|
-
options.tool === "wand" && /* @__PURE__ */ (0,
|
|
1440
|
-
/* @__PURE__ */ (0,
|
|
1441
|
-
/* @__PURE__ */ (0,
|
|
1442
|
-
/* @__PURE__ */ (0,
|
|
1443
|
-
/* @__PURE__ */ (0,
|
|
1564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
1565
|
+
/* @__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)) }),
|
|
1566
|
+
/* @__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)) }),
|
|
1567
|
+
options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
1568
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1569
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1570
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Tolerance" }),
|
|
1571
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "font-mono", children: options.tolerance })
|
|
1444
1572
|
] }),
|
|
1445
|
-
/* @__PURE__ */ (0,
|
|
1573
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1446
1574
|
"input",
|
|
1447
1575
|
{
|
|
1448
1576
|
type: "range",
|
|
@@ -1456,17 +1584,17 @@ var SelectionOptionsBar = ({
|
|
|
1456
1584
|
}
|
|
1457
1585
|
)
|
|
1458
1586
|
] }),
|
|
1459
|
-
/* @__PURE__ */ (0,
|
|
1460
|
-
/* @__PURE__ */ (0,
|
|
1587
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1588
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
|
|
1461
1589
|
"Contiguous"
|
|
1462
1590
|
] }),
|
|
1463
|
-
/* @__PURE__ */ (0,
|
|
1464
|
-
/* @__PURE__ */ (0,
|
|
1591
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1592
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
|
|
1465
1593
|
"Sample adjusted image"
|
|
1466
1594
|
] }),
|
|
1467
|
-
/* @__PURE__ */ (0,
|
|
1595
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1468
1596
|
"Sample",
|
|
1469
|
-
/* @__PURE__ */ (0,
|
|
1597
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1470
1598
|
"select",
|
|
1471
1599
|
{
|
|
1472
1600
|
"aria-label": "Sample from",
|
|
@@ -1474,27 +1602,27 @@ var SelectionOptionsBar = ({
|
|
|
1474
1602
|
onChange: (e) => set({ sample: e.target.value }),
|
|
1475
1603
|
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
1476
1604
|
children: [
|
|
1477
|
-
/* @__PURE__ */ (0,
|
|
1478
|
-
/* @__PURE__ */ (0,
|
|
1605
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "composite", children: "All layers" }),
|
|
1606
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "active-layer", children: "Active layer" })
|
|
1479
1607
|
]
|
|
1480
1608
|
}
|
|
1481
1609
|
)
|
|
1482
1610
|
] })
|
|
1483
1611
|
] }),
|
|
1484
|
-
/* @__PURE__ */ (0,
|
|
1485
|
-
/* @__PURE__ */ (0,
|
|
1612
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1613
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
|
|
1486
1614
|
"Anti-alias"
|
|
1487
1615
|
] }),
|
|
1488
|
-
/* @__PURE__ */ (0,
|
|
1489
|
-
/* @__PURE__ */ (0,
|
|
1490
|
-
/* @__PURE__ */ (0,
|
|
1491
|
-
/* @__PURE__ */ (0,
|
|
1492
|
-
/* @__PURE__ */ (0,
|
|
1616
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
1617
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
|
|
1618
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
|
|
1619
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
|
|
1620
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
|
|
1493
1621
|
] }),
|
|
1494
|
-
/* @__PURE__ */ (0,
|
|
1495
|
-
/* @__PURE__ */ (0,
|
|
1622
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
1623
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
|
|
1496
1624
|
"Radius",
|
|
1497
|
-
/* @__PURE__ */ (0,
|
|
1625
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1498
1626
|
"input",
|
|
1499
1627
|
{
|
|
1500
1628
|
type: "number",
|
|
@@ -1508,24 +1636,24 @@ var SelectionOptionsBar = ({
|
|
|
1508
1636
|
}
|
|
1509
1637
|
)
|
|
1510
1638
|
] }),
|
|
1511
|
-
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0,
|
|
1639
|
+
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))
|
|
1512
1640
|
] }),
|
|
1513
|
-
/* @__PURE__ */ (0,
|
|
1641
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor10.describeSelection)(sel) })
|
|
1514
1642
|
] });
|
|
1515
1643
|
};
|
|
1516
1644
|
|
|
1517
1645
|
// src/image-editor/RefineEdgePanel.tsx
|
|
1518
|
-
var
|
|
1519
|
-
var
|
|
1520
|
-
var
|
|
1646
|
+
var import_react10 = require("react");
|
|
1647
|
+
var import_image_editor11 = require("@pixerate/editor/image-editor");
|
|
1648
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1521
1649
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
1522
1650
|
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";
|
|
1523
1651
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
1524
|
-
const [params, setParams] = (0,
|
|
1525
|
-
const [busy, setBusy] = (0,
|
|
1526
|
-
const [error, setError] = (0,
|
|
1527
|
-
const [layerId, setLayerId] = (0,
|
|
1528
|
-
const [newKind, setNewKind] = (0,
|
|
1652
|
+
const [params, setParams] = (0, import_react10.useState)(DEFAULT_PARAMS);
|
|
1653
|
+
const [busy, setBusy] = (0, import_react10.useState)(false);
|
|
1654
|
+
const [error, setError] = (0, import_react10.useState)(null);
|
|
1655
|
+
const [layerId, setLayerId] = (0, import_react10.useState)("");
|
|
1656
|
+
const [newKind, setNewKind] = (0, import_react10.useState)("hueSaturation");
|
|
1529
1657
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
1530
1658
|
const list = layers ?? controller.getAdjustmentLayers();
|
|
1531
1659
|
const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
|
|
@@ -1540,17 +1668,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1540
1668
|
setBusy(false);
|
|
1541
1669
|
}
|
|
1542
1670
|
};
|
|
1543
|
-
return /* @__PURE__ */ (0,
|
|
1544
|
-
/* @__PURE__ */ (0,
|
|
1545
|
-
|
|
1546
|
-
/* @__PURE__ */ (0,
|
|
1547
|
-
/* @__PURE__ */ (0,
|
|
1548
|
-
/* @__PURE__ */ (0,
|
|
1671
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
1672
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
|
|
1673
|
+
import_image_editor11.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1674
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1675
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: c.label }),
|
|
1676
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
|
|
1549
1677
|
params[c.id],
|
|
1550
1678
|
c.unit
|
|
1551
1679
|
] })
|
|
1552
1680
|
] }),
|
|
1553
|
-
/* @__PURE__ */ (0,
|
|
1681
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1554
1682
|
"input",
|
|
1555
1683
|
{
|
|
1556
1684
|
type: "range",
|
|
@@ -1564,67 +1692,67 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1564
1692
|
}
|
|
1565
1693
|
)
|
|
1566
1694
|
] }, c.id)),
|
|
1567
|
-
/* @__PURE__ */ (0,
|
|
1568
|
-
/* @__PURE__ */ (0,
|
|
1695
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1696
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
|
|
1569
1697
|
"Smart Radius"
|
|
1570
1698
|
] }),
|
|
1571
|
-
/* @__PURE__ */ (0,
|
|
1572
|
-
/* @__PURE__ */ (0,
|
|
1573
|
-
/* @__PURE__ */ (0,
|
|
1699
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex gap-1", children: [
|
|
1700
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
|
|
1701
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
|
|
1574
1702
|
] }),
|
|
1575
|
-
error && /* @__PURE__ */ (0,
|
|
1576
|
-
/* @__PURE__ */ (0,
|
|
1577
|
-
/* @__PURE__ */ (0,
|
|
1578
|
-
/* @__PURE__ */ (0,
|
|
1703
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
|
|
1704
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
|
|
1705
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex gap-1 items-center", children: [
|
|
1706
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1579
1707
|
"select",
|
|
1580
1708
|
{
|
|
1581
1709
|
"aria-label": "New masked layer kind",
|
|
1582
1710
|
value: newKind,
|
|
1583
1711
|
onChange: (e) => setNewKind(e.target.value),
|
|
1584
1712
|
className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
1585
|
-
children:
|
|
1713
|
+
children: import_image_editor11.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: k.kind, children: k.label }, k.kind))
|
|
1586
1714
|
}
|
|
1587
1715
|
),
|
|
1588
|
-
/* @__PURE__ */ (0,
|
|
1716
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1589
1717
|
"button",
|
|
1590
1718
|
{
|
|
1591
1719
|
type: "button",
|
|
1592
1720
|
className: button2,
|
|
1593
1721
|
disabled: !sel,
|
|
1594
|
-
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0,
|
|
1722
|
+
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor11.layerMaskFromSelection)(sel) })),
|
|
1595
1723
|
children: "New Masked Layer"
|
|
1596
1724
|
}
|
|
1597
1725
|
)
|
|
1598
1726
|
] }),
|
|
1599
|
-
list.length > 0 && target && /* @__PURE__ */ (0,
|
|
1600
|
-
/* @__PURE__ */ (0,
|
|
1727
|
+
list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
1728
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1601
1729
|
"select",
|
|
1602
1730
|
{
|
|
1603
1731
|
"aria-label": "Mask layer",
|
|
1604
1732
|
value: target.id,
|
|
1605
1733
|
onChange: (e) => setLayerId(e.target.value),
|
|
1606
1734
|
className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
1607
|
-
children: list.map((l) => /* @__PURE__ */ (0,
|
|
1608
|
-
l.name || (0,
|
|
1735
|
+
children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("option", { value: l.id, children: [
|
|
1736
|
+
l.name || (0, import_image_editor11.adjustmentKindLabel)(l.kind),
|
|
1609
1737
|
l.mask ? " (masked)" : ""
|
|
1610
1738
|
] }, l.id))
|
|
1611
1739
|
}
|
|
1612
1740
|
),
|
|
1613
|
-
/* @__PURE__ */ (0,
|
|
1614
|
-
/* @__PURE__ */ (0,
|
|
1615
|
-
/* @__PURE__ */ (0,
|
|
1616
|
-
/* @__PURE__ */ (0,
|
|
1741
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
1742
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
|
|
1743
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
|
|
1744
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
|
|
1617
1745
|
] }),
|
|
1618
|
-
target.mask && /* @__PURE__ */ (0,
|
|
1619
|
-
/* @__PURE__ */ (0,
|
|
1620
|
-
/* @__PURE__ */ (0,
|
|
1621
|
-
/* @__PURE__ */ (0,
|
|
1622
|
-
/* @__PURE__ */ (0,
|
|
1746
|
+
target.mask && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1747
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1748
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1749
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Density" }),
|
|
1750
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
|
|
1623
1751
|
Math.round((target.mask.density ?? 1) * 100),
|
|
1624
1752
|
"%"
|
|
1625
1753
|
] })
|
|
1626
1754
|
] }),
|
|
1627
|
-
/* @__PURE__ */ (0,
|
|
1755
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1628
1756
|
"input",
|
|
1629
1757
|
{
|
|
1630
1758
|
type: "range",
|
|
@@ -1638,15 +1766,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1638
1766
|
}
|
|
1639
1767
|
)
|
|
1640
1768
|
] }),
|
|
1641
|
-
/* @__PURE__ */ (0,
|
|
1642
|
-
/* @__PURE__ */ (0,
|
|
1643
|
-
/* @__PURE__ */ (0,
|
|
1644
|
-
/* @__PURE__ */ (0,
|
|
1769
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1770
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1771
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Mask Feather" }),
|
|
1772
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "font-mono", children: [
|
|
1645
1773
|
target.mask.feather ?? 0,
|
|
1646
1774
|
"px"
|
|
1647
1775
|
] })
|
|
1648
1776
|
] }),
|
|
1649
|
-
/* @__PURE__ */ (0,
|
|
1777
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1650
1778
|
"input",
|
|
1651
1779
|
{
|
|
1652
1780
|
type: "range",
|
|
@@ -1666,14 +1794,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1666
1794
|
};
|
|
1667
1795
|
|
|
1668
1796
|
// src/image-editor/FreeTransformOptionsBar.tsx
|
|
1669
|
-
var
|
|
1670
|
-
var
|
|
1671
|
-
var
|
|
1672
|
-
var
|
|
1797
|
+
var import_react11 = require("react");
|
|
1798
|
+
var import_image_editor12 = require("@pixerate/editor/image-editor");
|
|
1799
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1800
|
+
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"}`;
|
|
1673
1801
|
var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
|
|
1674
1802
|
var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
1675
|
-
const [, setTick] = (0,
|
|
1676
|
-
(0,
|
|
1803
|
+
const [, setTick] = (0, import_react11.useState)(0);
|
|
1804
|
+
(0, import_react11.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
|
|
1677
1805
|
const bar = tool.bar();
|
|
1678
1806
|
if (!tool.active || !bar) return null;
|
|
1679
1807
|
const warp = tool.warpBar();
|
|
@@ -1685,17 +1813,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1685
1813
|
const v = Number(raw);
|
|
1686
1814
|
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
1687
1815
|
};
|
|
1688
|
-
return /* @__PURE__ */ (0,
|
|
1689
|
-
/* @__PURE__ */ (0,
|
|
1690
|
-
/* @__PURE__ */ (0,
|
|
1691
|
-
tool.mode === "warp" && /* @__PURE__ */ (0,
|
|
1692
|
-
/* @__PURE__ */ (0,
|
|
1693
|
-
/* @__PURE__ */ (0,
|
|
1694
|
-
/* @__PURE__ */ (0,
|
|
1816
|
+
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: [
|
|
1817
|
+
/* @__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)) }),
|
|
1818
|
+
/* @__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)) }),
|
|
1819
|
+
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: [
|
|
1820
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1821
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: "Warp" }),
|
|
1822
|
+
/* @__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)) })
|
|
1695
1823
|
] }),
|
|
1696
|
-
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0,
|
|
1697
|
-
/* @__PURE__ */ (0,
|
|
1698
|
-
/* @__PURE__ */ (0,
|
|
1824
|
+
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1825
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
|
|
1826
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1699
1827
|
"input",
|
|
1700
1828
|
{
|
|
1701
1829
|
type: "number",
|
|
@@ -1716,40 +1844,40 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1716
1844
|
},
|
|
1717
1845
|
`${k}:${warp[k]}`
|
|
1718
1846
|
),
|
|
1719
|
-
/* @__PURE__ */ (0,
|
|
1847
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-500", children: "%" })
|
|
1720
1848
|
] }, k)),
|
|
1721
|
-
/* @__PURE__ */ (0,
|
|
1849
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1722
1850
|
"button",
|
|
1723
1851
|
{
|
|
1724
1852
|
type: "button",
|
|
1725
1853
|
title: "Bend along the vertical axis",
|
|
1726
1854
|
"aria-pressed": warp.orientation === "vertical",
|
|
1727
1855
|
disabled: warp.style === "custom",
|
|
1728
|
-
className:
|
|
1856
|
+
className: chip3(warp.orientation === "vertical"),
|
|
1729
1857
|
onClick: () => tool.setWarp({ orientation: warp.orientation === "vertical" ? "horizontal" : "vertical" }),
|
|
1730
1858
|
children: "Vertical"
|
|
1731
1859
|
}
|
|
1732
1860
|
),
|
|
1733
|
-
/* @__PURE__ */ (0,
|
|
1734
|
-
/* @__PURE__ */ (0,
|
|
1735
|
-
/* @__PURE__ */ (0,
|
|
1861
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1862
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: "Grid" }),
|
|
1863
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1736
1864
|
"select",
|
|
1737
1865
|
{
|
|
1738
1866
|
"aria-label": "Warp grid",
|
|
1739
|
-
value:
|
|
1867
|
+
value: import_image_editor12.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
|
|
1740
1868
|
onChange: (e) => {
|
|
1741
|
-
const g =
|
|
1869
|
+
const g = import_image_editor12.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
|
|
1742
1870
|
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
1743
1871
|
},
|
|
1744
1872
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1745
|
-
children:
|
|
1873
|
+
children: import_image_editor12.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: g.id, children: g.label }, g.id))
|
|
1746
1874
|
}
|
|
1747
1875
|
)
|
|
1748
1876
|
] })
|
|
1749
1877
|
] }),
|
|
1750
|
-
tool.mode !== "warp" &&
|
|
1751
|
-
/* @__PURE__ */ (0,
|
|
1752
|
-
/* @__PURE__ */ (0,
|
|
1878
|
+
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: [
|
|
1879
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: f.label }),
|
|
1880
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1753
1881
|
"input",
|
|
1754
1882
|
{
|
|
1755
1883
|
type: "number",
|
|
@@ -1769,14 +1897,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1769
1897
|
},
|
|
1770
1898
|
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
1771
1899
|
),
|
|
1772
|
-
/* @__PURE__ */ (0,
|
|
1773
|
-
f.id === "scaleX" && /* @__PURE__ */ (0,
|
|
1900
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-500", children: f.unit }),
|
|
1901
|
+
f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1774
1902
|
"button",
|
|
1775
1903
|
{
|
|
1776
1904
|
type: "button",
|
|
1777
1905
|
"aria-label": "Keep width and height proportional",
|
|
1778
1906
|
"aria-pressed": tool.proportional,
|
|
1779
|
-
className:
|
|
1907
|
+
className: chip3(tool.proportional),
|
|
1780
1908
|
onClick: () => {
|
|
1781
1909
|
tool.proportional = !tool.proportional;
|
|
1782
1910
|
setTick((n) => n + 1);
|
|
@@ -1785,34 +1913,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1785
1913
|
}
|
|
1786
1914
|
)
|
|
1787
1915
|
] }, f.id)),
|
|
1788
|
-
/* @__PURE__ */ (0,
|
|
1789
|
-
/* @__PURE__ */ (0,
|
|
1790
|
-
/* @__PURE__ */ (0,
|
|
1916
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1917
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
|
|
1918
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1791
1919
|
"select",
|
|
1792
1920
|
{
|
|
1793
1921
|
"aria-label": "Interpolation",
|
|
1794
1922
|
value: tool.interpolation,
|
|
1795
1923
|
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
1796
1924
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1797
|
-
children:
|
|
1925
|
+
children: import_image_editor12.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
1798
1926
|
}
|
|
1799
1927
|
)
|
|
1800
1928
|
] }),
|
|
1801
|
-
/* @__PURE__ */ (0,
|
|
1802
|
-
/* @__PURE__ */ (0,
|
|
1803
|
-
tool.error && /* @__PURE__ */ (0,
|
|
1929
|
+
/* @__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" }),
|
|
1930
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
|
|
1931
|
+
tool.error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
|
|
1804
1932
|
] });
|
|
1805
1933
|
};
|
|
1806
1934
|
|
|
1807
1935
|
// src/image-editor/ShapeOptionsBar.tsx
|
|
1808
|
-
var
|
|
1809
|
-
var
|
|
1810
|
-
var
|
|
1811
|
-
var
|
|
1936
|
+
var import_react12 = require("react");
|
|
1937
|
+
var import_image_editor13 = require("@pixerate/editor/image-editor");
|
|
1938
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1939
|
+
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"}`;
|
|
1812
1940
|
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
1813
|
-
const [, setTick] = (0,
|
|
1814
|
-
(0,
|
|
1815
|
-
const [error, setError] = (0,
|
|
1941
|
+
const [, setTick] = (0, import_react12.useState)(0);
|
|
1942
|
+
(0, import_react12.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1943
|
+
const [error, setError] = (0, import_react12.useState)(null);
|
|
1816
1944
|
const active = controller.getActiveLayer();
|
|
1817
1945
|
const shapeId = active?.type === "shape" ? active.id : null;
|
|
1818
1946
|
const set = (change) => {
|
|
@@ -1820,19 +1948,19 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1820
1948
|
if (!shapeId) return;
|
|
1821
1949
|
try {
|
|
1822
1950
|
setError(null);
|
|
1823
|
-
(0,
|
|
1951
|
+
(0, import_image_editor13.applyShapeOptions)(controller, shapeId, change);
|
|
1824
1952
|
} catch (e) {
|
|
1825
1953
|
setError(e instanceof Error ? e.message : String(e));
|
|
1826
1954
|
}
|
|
1827
1955
|
};
|
|
1828
1956
|
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
1829
|
-
return /* @__PURE__ */ (0,
|
|
1830
|
-
/* @__PURE__ */ (0,
|
|
1831
|
-
/* @__PURE__ */ (0,
|
|
1832
|
-
/* @__PURE__ */ (0,
|
|
1833
|
-
/* @__PURE__ */ (0,
|
|
1957
|
+
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: [
|
|
1958
|
+
/* @__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)) }),
|
|
1959
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
1960
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1961
|
+
/* @__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 }) }),
|
|
1834
1962
|
"Fill",
|
|
1835
|
-
/* @__PURE__ */ (0,
|
|
1963
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1836
1964
|
"input",
|
|
1837
1965
|
{
|
|
1838
1966
|
type: "color",
|
|
@@ -1844,10 +1972,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1844
1972
|
}
|
|
1845
1973
|
)
|
|
1846
1974
|
] }),
|
|
1847
|
-
/* @__PURE__ */ (0,
|
|
1848
|
-
/* @__PURE__ */ (0,
|
|
1975
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1976
|
+
/* @__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 }) }),
|
|
1849
1977
|
"Stroke",
|
|
1850
|
-
/* @__PURE__ */ (0,
|
|
1978
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1851
1979
|
"input",
|
|
1852
1980
|
{
|
|
1853
1981
|
type: "color",
|
|
@@ -1859,9 +1987,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1859
1987
|
}
|
|
1860
1988
|
)
|
|
1861
1989
|
] }),
|
|
1862
|
-
/* @__PURE__ */ (0,
|
|
1990
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1863
1991
|
"Width",
|
|
1864
|
-
/* @__PURE__ */ (0,
|
|
1992
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1865
1993
|
"input",
|
|
1866
1994
|
{
|
|
1867
1995
|
type: "number",
|
|
@@ -1875,23 +2003,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1875
2003
|
)
|
|
1876
2004
|
] })
|
|
1877
2005
|
] }),
|
|
1878
|
-
/* @__PURE__ */ (0,
|
|
1879
|
-
options.kind === "rect" && /* @__PURE__ */ (0,
|
|
2006
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
2007
|
+
options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1880
2008
|
"Radius",
|
|
1881
|
-
/* @__PURE__ */ (0,
|
|
2009
|
+
/* @__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" })
|
|
1882
2010
|
] }),
|
|
1883
|
-
options.kind === "polygon" && /* @__PURE__ */ (0,
|
|
2011
|
+
options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1884
2012
|
"Sides",
|
|
1885
|
-
/* @__PURE__ */ (0,
|
|
2013
|
+
/* @__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" })
|
|
1886
2014
|
] }),
|
|
1887
|
-
options.kind === "star" && /* @__PURE__ */ (0,
|
|
1888
|
-
/* @__PURE__ */ (0,
|
|
2015
|
+
options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
2016
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1889
2017
|
"Points",
|
|
1890
|
-
/* @__PURE__ */ (0,
|
|
2018
|
+
/* @__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" })
|
|
1891
2019
|
] }),
|
|
1892
|
-
/* @__PURE__ */ (0,
|
|
2020
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1893
2021
|
"Inner",
|
|
1894
|
-
/* @__PURE__ */ (0,
|
|
2022
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1895
2023
|
"input",
|
|
1896
2024
|
{
|
|
1897
2025
|
type: "range",
|
|
@@ -1906,33 +2034,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1906
2034
|
)
|
|
1907
2035
|
] })
|
|
1908
2036
|
] }),
|
|
1909
|
-
options.kind === "line" && /* @__PURE__ */ (0,
|
|
1910
|
-
/* @__PURE__ */ (0,
|
|
2037
|
+
options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
2038
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1911
2039
|
"Weight",
|
|
1912
|
-
/* @__PURE__ */ (0,
|
|
2040
|
+
/* @__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" })
|
|
1913
2041
|
] }),
|
|
1914
|
-
/* @__PURE__ */ (0,
|
|
1915
|
-
/* @__PURE__ */ (0,
|
|
2042
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2043
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
|
|
1916
2044
|
"Arrowhead"
|
|
1917
2045
|
] })
|
|
1918
2046
|
] })
|
|
1919
2047
|
] }),
|
|
1920
|
-
/* @__PURE__ */ (0,
|
|
1921
|
-
error && /* @__PURE__ */ (0,
|
|
2048
|
+
/* @__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." }),
|
|
2049
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1922
2050
|
] });
|
|
1923
2051
|
};
|
|
1924
2052
|
|
|
1925
2053
|
// src/image-editor/TypeOptionsBar.tsx
|
|
1926
|
-
var
|
|
1927
|
-
var
|
|
1928
|
-
var
|
|
1929
|
-
var
|
|
2054
|
+
var import_react13 = require("react");
|
|
2055
|
+
var import_image_editor14 = require("@pixerate/editor/image-editor");
|
|
2056
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2057
|
+
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"}`;
|
|
1930
2058
|
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
1931
2059
|
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
1932
|
-
const [, setTick] = (0,
|
|
1933
|
-
(0,
|
|
1934
|
-
(0,
|
|
1935
|
-
const [error, setError] = (0,
|
|
2060
|
+
const [, setTick] = (0, import_react13.useState)(0);
|
|
2061
|
+
(0, import_react13.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
2062
|
+
(0, import_react13.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
|
|
2063
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1936
2064
|
const active = controller.getActiveLayer();
|
|
1937
2065
|
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
1938
2066
|
const here = session?.alive ? session.styleHere() : {};
|
|
@@ -1964,11 +2092,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
1964
2092
|
setError(e instanceof Error ? e.message : String(e));
|
|
1965
2093
|
}
|
|
1966
2094
|
};
|
|
1967
|
-
return /* @__PURE__ */ (0,
|
|
1968
|
-
/* @__PURE__ */ (0,
|
|
1969
|
-
/* @__PURE__ */ (0,
|
|
2095
|
+
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: [
|
|
2096
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2097
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1970
2098
|
"Font",
|
|
1971
|
-
/* @__PURE__ */ (0,
|
|
2099
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1972
2100
|
"input",
|
|
1973
2101
|
{
|
|
1974
2102
|
list: "pixerate-type-fonts",
|
|
@@ -1978,11 +2106,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
1978
2106
|
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
1979
2107
|
}
|
|
1980
2108
|
),
|
|
1981
|
-
/* @__PURE__ */ (0,
|
|
2109
|
+
/* @__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)) })
|
|
1982
2110
|
] }),
|
|
1983
|
-
/* @__PURE__ */ (0,
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1984
2112
|
"Size",
|
|
1985
|
-
/* @__PURE__ */ (0,
|
|
2113
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1986
2114
|
"input",
|
|
1987
2115
|
{
|
|
1988
2116
|
type: "number",
|
|
@@ -1995,24 +2123,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
1995
2123
|
}
|
|
1996
2124
|
)
|
|
1997
2125
|
] }),
|
|
1998
|
-
/* @__PURE__ */ (0,
|
|
1999
|
-
/* @__PURE__ */ (0,
|
|
2000
|
-
/* @__PURE__ */ (0,
|
|
2126
|
+
/* @__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" }),
|
|
2127
|
+
/* @__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" }),
|
|
2128
|
+
/* @__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" })
|
|
2001
2129
|
] }),
|
|
2002
|
-
/* @__PURE__ */ (0,
|
|
2003
|
-
/* @__PURE__ */ (0,
|
|
2004
|
-
missing.length > 0 && /* @__PURE__ */ (0,
|
|
2130
|
+
/* @__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)) }),
|
|
2131
|
+
/* @__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." }),
|
|
2132
|
+
missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
|
|
2005
2133
|
"Missing ",
|
|
2006
2134
|
missing.length === 1 ? "font" : "fonts",
|
|
2007
2135
|
": ",
|
|
2008
2136
|
missing.join(", ")
|
|
2009
2137
|
] }),
|
|
2010
|
-
error && /* @__PURE__ */ (0,
|
|
2138
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
2011
2139
|
] });
|
|
2012
2140
|
};
|
|
2013
2141
|
|
|
2014
2142
|
// src/image-editor/ImageEditor.tsx
|
|
2015
|
-
var
|
|
2143
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2016
2144
|
var ImageEditor = ({
|
|
2017
2145
|
editor: externalEditor,
|
|
2018
2146
|
src,
|
|
@@ -2027,65 +2155,65 @@ var ImageEditor = ({
|
|
|
2027
2155
|
const internalEditor = useImageEditor({ image: src });
|
|
2028
2156
|
const editor = externalEditor || internalEditor;
|
|
2029
2157
|
const { state, controller } = editor;
|
|
2030
|
-
const legacyProcess = (0,
|
|
2031
|
-
const canvasRef = (0,
|
|
2032
|
-
const containerRef = (0,
|
|
2033
|
-
const [activeTab, setActiveTab] = (0,
|
|
2034
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
2035
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
2036
|
-
const selectionOptionsRef = (0,
|
|
2158
|
+
const legacyProcess = (0, import_image_editor15.normalizeProcessVersion)(state.adjustments.process) < import_image_editor15.LATEST_PROCESS_VERSION;
|
|
2159
|
+
const canvasRef = (0, import_react14.useRef)(null);
|
|
2160
|
+
const containerRef = (0, import_react14.useRef)(null);
|
|
2161
|
+
const [activeTab, setActiveTab] = (0, import_react14.useState)("crop");
|
|
2162
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react14.useState)(null);
|
|
2163
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react14.useState)(import_image_editor15.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
2164
|
+
const selectionOptionsRef = (0, import_react14.useRef)(selectionOptions);
|
|
2037
2165
|
selectionOptionsRef.current = selectionOptions;
|
|
2038
|
-
const selectionGestureRef = (0,
|
|
2166
|
+
const selectionGestureRef = (0, import_react14.useRef)(null);
|
|
2039
2167
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
2040
|
-
selectionGestureRef.current = new
|
|
2168
|
+
selectionGestureRef.current = new import_image_editor15.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
2041
2169
|
}
|
|
2042
|
-
const selectionDraftRef = (0,
|
|
2043
|
-
const [selectionError, setSelectionError] = (0,
|
|
2044
|
-
const paintGestureRef = (0,
|
|
2045
|
-
const paintControllerRef = (0,
|
|
2170
|
+
const selectionDraftRef = (0, import_react14.useRef)(null);
|
|
2171
|
+
const [selectionError, setSelectionError] = (0, import_react14.useState)(null);
|
|
2172
|
+
const paintGestureRef = (0, import_react14.useRef)(null);
|
|
2173
|
+
const paintControllerRef = (0, import_react14.useRef)(controller);
|
|
2046
2174
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
2047
|
-
paintGestureRef.current = new
|
|
2175
|
+
paintGestureRef.current = new import_image_editor15.PaintGesture(controller);
|
|
2048
2176
|
paintControllerRef.current = controller;
|
|
2049
2177
|
}
|
|
2050
|
-
const brushCursorRef = (0,
|
|
2051
|
-
const [paintError, setPaintError] = (0,
|
|
2052
|
-
const transformToolRef = (0,
|
|
2053
|
-
const transformControllerRef = (0,
|
|
2178
|
+
const brushCursorRef = (0, import_react14.useRef)(null);
|
|
2179
|
+
const [paintError, setPaintError] = (0, import_react14.useState)(null);
|
|
2180
|
+
const transformToolRef = (0, import_react14.useRef)(null);
|
|
2181
|
+
const transformControllerRef = (0, import_react14.useRef)(controller);
|
|
2054
2182
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
2055
2183
|
transformToolRef.current?.cancel();
|
|
2056
|
-
transformToolRef.current = new
|
|
2184
|
+
transformToolRef.current = new import_image_editor15.FreeTransformTool(controller, {
|
|
2057
2185
|
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
2058
2186
|
});
|
|
2059
2187
|
transformControllerRef.current = controller;
|
|
2060
2188
|
}
|
|
2061
2189
|
const transformTool = transformToolRef.current;
|
|
2062
|
-
const [, setTransformTick] = (0,
|
|
2063
|
-
const [transformCursor, setTransformCursor] = (0,
|
|
2064
|
-
const [shapeOptions, setShapeOptions] = (0,
|
|
2065
|
-
const shapeOptionsRef = (0,
|
|
2190
|
+
const [, setTransformTick] = (0, import_react14.useState)(0);
|
|
2191
|
+
const [transformCursor, setTransformCursor] = (0, import_react14.useState)("default");
|
|
2192
|
+
const [shapeOptions, setShapeOptions] = (0, import_react14.useState)(import_image_editor15.DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
2193
|
+
const shapeOptionsRef = (0, import_react14.useRef)(shapeOptions);
|
|
2066
2194
|
shapeOptionsRef.current = shapeOptions;
|
|
2067
|
-
const [typeOptions, setTypeOptions] = (0,
|
|
2068
|
-
const typeOptionsRef = (0,
|
|
2195
|
+
const [typeOptions, setTypeOptions] = (0, import_react14.useState)(import_image_editor15.DEFAULT_TYPE_TOOL_OPTIONS);
|
|
2196
|
+
const typeOptionsRef = (0, import_react14.useRef)(typeOptions);
|
|
2069
2197
|
typeOptionsRef.current = typeOptions;
|
|
2070
|
-
const shapeGestureRef = (0,
|
|
2071
|
-
const typeToolRef = (0,
|
|
2072
|
-
const shapeTypeControllerRef = (0,
|
|
2198
|
+
const shapeGestureRef = (0, import_react14.useRef)(null);
|
|
2199
|
+
const typeToolRef = (0, import_react14.useRef)(null);
|
|
2200
|
+
const shapeTypeControllerRef = (0, import_react14.useRef)(controller);
|
|
2073
2201
|
if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
|
|
2074
2202
|
typeToolRef.current?.finish();
|
|
2075
|
-
shapeGestureRef.current = new
|
|
2076
|
-
typeToolRef.current = new
|
|
2203
|
+
shapeGestureRef.current = new import_image_editor15.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
|
|
2204
|
+
typeToolRef.current = new import_image_editor15.TypeToolGesture(controller, () => typeOptionsRef.current);
|
|
2077
2205
|
shapeTypeControllerRef.current = controller;
|
|
2078
2206
|
}
|
|
2079
|
-
const typeInputRef = (0,
|
|
2080
|
-
const [typeSession, setTypeSession] = (0,
|
|
2081
|
-
const [shapeTypeError, setShapeTypeError] = (0,
|
|
2082
|
-
const [inpaintPrompt, setInpaintPrompt] = (0,
|
|
2083
|
-
const [inpaintMaskMode, setInpaintMaskMode] = (0,
|
|
2084
|
-
const [isRemovingBg, setIsRemovingBg] = (0,
|
|
2085
|
-
const [isInpainting, setIsInpainting] = (0,
|
|
2086
|
-
const [aiError, setAiError] = (0,
|
|
2087
|
-
const [aiSuccess, setAiSuccess] = (0,
|
|
2088
|
-
const [aiTarget, setAiTarget] = (0,
|
|
2207
|
+
const typeInputRef = (0, import_react14.useRef)(null);
|
|
2208
|
+
const [typeSession, setTypeSession] = (0, import_react14.useState)(typeToolRef.current.session);
|
|
2209
|
+
const [shapeTypeError, setShapeTypeError] = (0, import_react14.useState)(null);
|
|
2210
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react14.useState)("");
|
|
2211
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react14.useState)("annotations");
|
|
2212
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react14.useState)(false);
|
|
2213
|
+
const [isInpainting, setIsInpainting] = (0, import_react14.useState)(false);
|
|
2214
|
+
const [aiError, setAiError] = (0, import_react14.useState)(null);
|
|
2215
|
+
const [aiSuccess, setAiSuccess] = (0, import_react14.useState)(null);
|
|
2216
|
+
const [aiTarget, setAiTarget] = (0, import_react14.useState)("auto");
|
|
2089
2217
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
2090
2218
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
2091
2219
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -2148,18 +2276,18 @@ var ImageEditor = ({
|
|
|
2148
2276
|
setIsInpainting(false);
|
|
2149
2277
|
}
|
|
2150
2278
|
};
|
|
2151
|
-
const [activeColor, setActiveColor] = (0,
|
|
2152
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
2153
|
-
const [fontSize, setFontSize] = (0,
|
|
2154
|
-
const [textInput, setTextInput] = (0,
|
|
2155
|
-
const draftAnnotationRef = (0,
|
|
2156
|
-
const draftCropRef = (0,
|
|
2157
|
-
const cropDragInfoRef = (0,
|
|
2158
|
-
const annotationDragInfoRef = (0,
|
|
2159
|
-
const isDrawingRef = (0,
|
|
2160
|
-
const currentPathRef = (0,
|
|
2161
|
-
const dragStartPointRef = (0,
|
|
2162
|
-
const renderCanvas = (0,
|
|
2279
|
+
const [activeColor, setActiveColor] = (0, import_react14.useState)("#ef4444");
|
|
2280
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react14.useState)(3);
|
|
2281
|
+
const [fontSize, setFontSize] = (0, import_react14.useState)(24);
|
|
2282
|
+
const [textInput, setTextInput] = (0, import_react14.useState)("");
|
|
2283
|
+
const draftAnnotationRef = (0, import_react14.useRef)(null);
|
|
2284
|
+
const draftCropRef = (0, import_react14.useRef)(null);
|
|
2285
|
+
const cropDragInfoRef = (0, import_react14.useRef)(null);
|
|
2286
|
+
const annotationDragInfoRef = (0, import_react14.useRef)(null);
|
|
2287
|
+
const isDrawingRef = (0, import_react14.useRef)(false);
|
|
2288
|
+
const currentPathRef = (0, import_react14.useRef)([]);
|
|
2289
|
+
const dragStartPointRef = (0, import_react14.useRef)(null);
|
|
2290
|
+
const renderCanvas = (0, import_react14.useCallback)(
|
|
2163
2291
|
async (draftAnnotation, draftCrop) => {
|
|
2164
2292
|
const canvas = canvasRef.current;
|
|
2165
2293
|
const container = containerRef.current;
|
|
@@ -2182,8 +2310,8 @@ var ImageEditor = ({
|
|
|
2182
2310
|
},
|
|
2183
2311
|
[controller, activeTab, transformTool]
|
|
2184
2312
|
);
|
|
2185
|
-
(0,
|
|
2186
|
-
(0,
|
|
2313
|
+
(0, import_react14.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
2314
|
+
(0, import_react14.useEffect)(() => {
|
|
2187
2315
|
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
2188
2316
|
if (typeToolRef.current?.session) {
|
|
2189
2317
|
typeToolRef.current.finish();
|
|
@@ -2218,7 +2346,7 @@ var ImageEditor = ({
|
|
|
2218
2346
|
el.value = "";
|
|
2219
2347
|
}
|
|
2220
2348
|
};
|
|
2221
|
-
(0,
|
|
2349
|
+
(0, import_react14.useEffect)(() => transformTool.subscribe(() => {
|
|
2222
2350
|
setTransformTick((n) => n + 1);
|
|
2223
2351
|
void renderCanvas();
|
|
2224
2352
|
}), [transformTool, renderCanvas]);
|
|
@@ -2229,8 +2357,8 @@ var ImageEditor = ({
|
|
|
2229
2357
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
2230
2358
|
const s = controller.getState();
|
|
2231
2359
|
const cropping = activeTab === "crop";
|
|
2232
|
-
const projection = (0,
|
|
2233
|
-
const pt = (0,
|
|
2360
|
+
const projection = (0, import_image_editor15.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
2361
|
+
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);
|
|
2234
2362
|
transformTool.setView(projection.scale);
|
|
2235
2363
|
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
2236
2364
|
};
|
|
@@ -2261,7 +2389,7 @@ var ImageEditor = ({
|
|
|
2261
2389
|
transformTool.up();
|
|
2262
2390
|
return true;
|
|
2263
2391
|
};
|
|
2264
|
-
(0,
|
|
2392
|
+
(0, import_react14.useEffect)(() => {
|
|
2265
2393
|
if (typeof window === "undefined") return;
|
|
2266
2394
|
const onKey = (e) => {
|
|
2267
2395
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -2269,7 +2397,7 @@ var ImageEditor = ({
|
|
|
2269
2397
|
window.addEventListener("keydown", onKey);
|
|
2270
2398
|
return () => window.removeEventListener("keydown", onKey);
|
|
2271
2399
|
}, [transformTool]);
|
|
2272
|
-
(0,
|
|
2400
|
+
(0, import_react14.useEffect)(() => {
|
|
2273
2401
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
2274
2402
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
2275
2403
|
const animId = raf(() => {
|
|
@@ -2277,12 +2405,12 @@ var ImageEditor = ({
|
|
|
2277
2405
|
});
|
|
2278
2406
|
return () => caf(animId);
|
|
2279
2407
|
}, [renderCanvas, state]);
|
|
2280
|
-
(0,
|
|
2408
|
+
(0, import_react14.useEffect)(() => {
|
|
2281
2409
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
2282
2410
|
editor.setTool("crop");
|
|
2283
2411
|
}
|
|
2284
2412
|
}, [activeTab, editor]);
|
|
2285
|
-
(0,
|
|
2413
|
+
(0, import_react14.useEffect)(() => {
|
|
2286
2414
|
const container = containerRef.current;
|
|
2287
2415
|
if (!container) return;
|
|
2288
2416
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -2318,8 +2446,8 @@ var ImageEditor = ({
|
|
|
2318
2446
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
2319
2447
|
const s = controller.getState();
|
|
2320
2448
|
return list.map((ev) => ({
|
|
2321
|
-
...(0,
|
|
2322
|
-
pressure: (0,
|
|
2449
|
+
...(0, import_image_editor15.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
2450
|
+
pressure: (0, import_image_editor15.pointerPressure)(ev)
|
|
2323
2451
|
}));
|
|
2324
2452
|
};
|
|
2325
2453
|
const handlePaintPointerDown = (e) => {
|
|
@@ -2331,7 +2459,7 @@ var ImageEditor = ({
|
|
|
2331
2459
|
} catch {
|
|
2332
2460
|
}
|
|
2333
2461
|
const [first] = paintSamples(e);
|
|
2334
|
-
setPaintError(paintGestureRef.current.down(first));
|
|
2462
|
+
setPaintError(paintGestureRef.current.down({ ...first, altKey: e.altKey }));
|
|
2335
2463
|
};
|
|
2336
2464
|
const handlePaintPointerMove = (e) => {
|
|
2337
2465
|
if (handleTransformPointerMove(e)) return;
|
|
@@ -2350,10 +2478,10 @@ var ImageEditor = ({
|
|
|
2350
2478
|
if (g.error) setPaintError(g.error);
|
|
2351
2479
|
}
|
|
2352
2480
|
};
|
|
2353
|
-
(0,
|
|
2481
|
+
(0, import_react14.useEffect)(() => {
|
|
2354
2482
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
2355
2483
|
const onKey = (e) => {
|
|
2356
|
-
if ((0,
|
|
2484
|
+
if ((0, import_image_editor15.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
2357
2485
|
};
|
|
2358
2486
|
window.addEventListener("keydown", onKey);
|
|
2359
2487
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -2364,7 +2492,7 @@ var ImageEditor = ({
|
|
|
2364
2492
|
const canvasPt = getCanvasEventPoint(e);
|
|
2365
2493
|
if (activeTab === "select") {
|
|
2366
2494
|
const gesture = selectionGestureRef.current;
|
|
2367
|
-
const imgPt = (0,
|
|
2495
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2368
2496
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
2369
2497
|
return;
|
|
2370
2498
|
}
|
|
@@ -2375,8 +2503,8 @@ var ImageEditor = ({
|
|
|
2375
2503
|
width: state.imageDimensions.width,
|
|
2376
2504
|
height: state.imageDimensions.height
|
|
2377
2505
|
};
|
|
2378
|
-
const handle = (0,
|
|
2379
|
-
const startImgPt = (0,
|
|
2506
|
+
const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2507
|
+
const startImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
2380
2508
|
if (handle) {
|
|
2381
2509
|
cropDragInfoRef.current = {
|
|
2382
2510
|
handle,
|
|
@@ -2395,7 +2523,7 @@ var ImageEditor = ({
|
|
|
2395
2523
|
return;
|
|
2396
2524
|
}
|
|
2397
2525
|
if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
|
|
2398
|
-
const imgPt = (0,
|
|
2526
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2399
2527
|
setShapeTypeError(null);
|
|
2400
2528
|
if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
|
|
2401
2529
|
else {
|
|
@@ -2406,12 +2534,12 @@ var ImageEditor = ({
|
|
|
2406
2534
|
return;
|
|
2407
2535
|
}
|
|
2408
2536
|
if (activeTab === "annotate") {
|
|
2409
|
-
const imgPt = (0,
|
|
2537
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2410
2538
|
dragStartPointRef.current = imgPt;
|
|
2411
2539
|
if (state.activeTool === "select") {
|
|
2412
2540
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
2413
2541
|
const ann = state.annotations[i];
|
|
2414
|
-
if ((0,
|
|
2542
|
+
if ((0, import_image_editor15.hitTestAnnotation)(imgPt, ann)) {
|
|
2415
2543
|
editor.selectAnnotation(ann.id);
|
|
2416
2544
|
annotationDragInfoRef.current = {
|
|
2417
2545
|
annId: ann.id,
|
|
@@ -2447,7 +2575,7 @@ var ImageEditor = ({
|
|
|
2447
2575
|
const canvasPt = getCanvasEventPoint(e);
|
|
2448
2576
|
if (activeTab === "select") {
|
|
2449
2577
|
const gesture = selectionGestureRef.current;
|
|
2450
|
-
if (gesture.active && gesture.move((0,
|
|
2578
|
+
if (gesture.active && gesture.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
2451
2579
|
selectionDraftRef.current = gesture.draftPath;
|
|
2452
2580
|
renderCanvas();
|
|
2453
2581
|
}
|
|
@@ -2456,7 +2584,7 @@ var ImageEditor = ({
|
|
|
2456
2584
|
if (activeTab === "crop") {
|
|
2457
2585
|
const drag = cropDragInfoRef.current;
|
|
2458
2586
|
if (drag) {
|
|
2459
|
-
const currentImgPt = (0,
|
|
2587
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
2460
2588
|
let newCrop;
|
|
2461
2589
|
if (drag.handle === "new") {
|
|
2462
2590
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -2470,7 +2598,7 @@ var ImageEditor = ({
|
|
|
2470
2598
|
height: Math.round(Math.max(20, maxY - minY))
|
|
2471
2599
|
};
|
|
2472
2600
|
} else {
|
|
2473
|
-
newCrop = (0,
|
|
2601
|
+
newCrop = (0, import_image_editor15.calculateCropDrag)(
|
|
2474
2602
|
drag.startCrop,
|
|
2475
2603
|
drag.handle,
|
|
2476
2604
|
drag.startImgPt,
|
|
@@ -2490,15 +2618,15 @@ var ImageEditor = ({
|
|
|
2490
2618
|
width: state.imageDimensions.width,
|
|
2491
2619
|
height: state.imageDimensions.height
|
|
2492
2620
|
};
|
|
2493
|
-
const handle = (0,
|
|
2494
|
-
canvas.style.cursor = (0,
|
|
2621
|
+
const handle = (0, import_image_editor15.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2622
|
+
canvas.style.cursor = (0, import_image_editor15.getCropCursor)(handle, state.transform);
|
|
2495
2623
|
}
|
|
2496
2624
|
return;
|
|
2497
2625
|
}
|
|
2498
2626
|
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
2499
2627
|
const g = shapeGestureRef.current;
|
|
2500
2628
|
if (g.active) {
|
|
2501
|
-
g.move((0,
|
|
2629
|
+
g.move((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
|
|
2502
2630
|
if (g.error) setShapeTypeError(g.error);
|
|
2503
2631
|
}
|
|
2504
2632
|
return;
|
|
@@ -2506,7 +2634,7 @@ var ImageEditor = ({
|
|
|
2506
2634
|
if (activeTab === "annotate") {
|
|
2507
2635
|
if (annotationDragInfoRef.current) {
|
|
2508
2636
|
const drag = annotationDragInfoRef.current;
|
|
2509
|
-
const currentImgPt2 = (0,
|
|
2637
|
+
const currentImgPt2 = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2510
2638
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
2511
2639
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
2512
2640
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -2518,10 +2646,10 @@ var ImageEditor = ({
|
|
|
2518
2646
|
const startPt = dragStartPointRef.current;
|
|
2519
2647
|
if (!startPt) {
|
|
2520
2648
|
if (state.activeTool === "select") {
|
|
2521
|
-
const imgPt = (0,
|
|
2649
|
+
const imgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2522
2650
|
let hovered = false;
|
|
2523
2651
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
2524
|
-
if ((0,
|
|
2652
|
+
if ((0, import_image_editor15.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
2525
2653
|
hovered = true;
|
|
2526
2654
|
break;
|
|
2527
2655
|
}
|
|
@@ -2532,7 +2660,7 @@ var ImageEditor = ({
|
|
|
2532
2660
|
}
|
|
2533
2661
|
return;
|
|
2534
2662
|
}
|
|
2535
|
-
const currentImgPt = (0,
|
|
2663
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2536
2664
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2537
2665
|
currentPathRef.current.push(currentImgPt);
|
|
2538
2666
|
const draft = {
|
|
@@ -2612,7 +2740,7 @@ var ImageEditor = ({
|
|
|
2612
2740
|
if (activeTab === "select") {
|
|
2613
2741
|
const gesture = selectionGestureRef.current;
|
|
2614
2742
|
if (gesture.active) {
|
|
2615
|
-
gesture.end((0,
|
|
2743
|
+
gesture.end((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
2616
2744
|
selectionDraftRef.current = null;
|
|
2617
2745
|
renderCanvas();
|
|
2618
2746
|
}
|
|
@@ -2635,7 +2763,7 @@ var ImageEditor = ({
|
|
|
2635
2763
|
}
|
|
2636
2764
|
if (activeTab === "annotate" && state.activeTool === "type") {
|
|
2637
2765
|
const tool = typeToolRef.current;
|
|
2638
|
-
tool.up((0,
|
|
2766
|
+
tool.up((0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
|
|
2639
2767
|
setTypeSession(tool.session);
|
|
2640
2768
|
if (tool.error) setShapeTypeError(tool.error);
|
|
2641
2769
|
void renderCanvas();
|
|
@@ -2649,7 +2777,7 @@ var ImageEditor = ({
|
|
|
2649
2777
|
}
|
|
2650
2778
|
const startPt = dragStartPointRef.current;
|
|
2651
2779
|
if (startPt) {
|
|
2652
|
-
const currentImgPt = (0,
|
|
2780
|
+
const currentImgPt = (0, import_image_editor15.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2653
2781
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2654
2782
|
if (currentPathRef.current.length > 1) {
|
|
2655
2783
|
editor.addAnnotation({
|
|
@@ -2745,15 +2873,15 @@ var ImageEditor = ({
|
|
|
2745
2873
|
link.click();
|
|
2746
2874
|
}
|
|
2747
2875
|
};
|
|
2748
|
-
return /* @__PURE__ */ (0,
|
|
2876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2749
2877
|
"div",
|
|
2750
2878
|
{
|
|
2751
2879
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
2752
2880
|
style,
|
|
2753
2881
|
children: [
|
|
2754
|
-
/* @__PURE__ */ (0,
|
|
2755
|
-
/* @__PURE__ */ (0,
|
|
2756
|
-
/* @__PURE__ */ (0,
|
|
2882
|
+
/* @__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: [
|
|
2883
|
+
/* @__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: [
|
|
2884
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2757
2885
|
"button",
|
|
2758
2886
|
{
|
|
2759
2887
|
type: "button",
|
|
@@ -2765,7 +2893,7 @@ var ImageEditor = ({
|
|
|
2765
2893
|
children: "Transform & Crop"
|
|
2766
2894
|
}
|
|
2767
2895
|
),
|
|
2768
|
-
/* @__PURE__ */ (0,
|
|
2896
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2769
2897
|
"button",
|
|
2770
2898
|
{
|
|
2771
2899
|
type: "button",
|
|
@@ -2777,7 +2905,7 @@ var ImageEditor = ({
|
|
|
2777
2905
|
children: "Adjustments"
|
|
2778
2906
|
}
|
|
2779
2907
|
),
|
|
2780
|
-
/* @__PURE__ */ (0,
|
|
2908
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2781
2909
|
"button",
|
|
2782
2910
|
{
|
|
2783
2911
|
type: "button",
|
|
@@ -2789,7 +2917,7 @@ var ImageEditor = ({
|
|
|
2789
2917
|
children: "Layers"
|
|
2790
2918
|
}
|
|
2791
2919
|
),
|
|
2792
|
-
/* @__PURE__ */ (0,
|
|
2920
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2793
2921
|
"button",
|
|
2794
2922
|
{
|
|
2795
2923
|
type: "button",
|
|
@@ -2801,7 +2929,7 @@ var ImageEditor = ({
|
|
|
2801
2929
|
children: "Paint"
|
|
2802
2930
|
}
|
|
2803
2931
|
),
|
|
2804
|
-
/* @__PURE__ */ (0,
|
|
2932
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2805
2933
|
"button",
|
|
2806
2934
|
{
|
|
2807
2935
|
type: "button",
|
|
@@ -2813,7 +2941,7 @@ var ImageEditor = ({
|
|
|
2813
2941
|
children: "Select & Mask"
|
|
2814
2942
|
}
|
|
2815
2943
|
),
|
|
2816
|
-
/* @__PURE__ */ (0,
|
|
2944
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2817
2945
|
"button",
|
|
2818
2946
|
{
|
|
2819
2947
|
type: "button",
|
|
@@ -2825,7 +2953,7 @@ var ImageEditor = ({
|
|
|
2825
2953
|
children: "Annotations"
|
|
2826
2954
|
}
|
|
2827
2955
|
),
|
|
2828
|
-
/* @__PURE__ */ (0,
|
|
2956
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2829
2957
|
"button",
|
|
2830
2958
|
{
|
|
2831
2959
|
type: "button",
|
|
@@ -2837,7 +2965,7 @@ var ImageEditor = ({
|
|
|
2837
2965
|
children: "Depth Mask"
|
|
2838
2966
|
}
|
|
2839
2967
|
),
|
|
2840
|
-
/* @__PURE__ */ (0,
|
|
2968
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2841
2969
|
"button",
|
|
2842
2970
|
{
|
|
2843
2971
|
type: "button",
|
|
@@ -2847,14 +2975,14 @@ var ImageEditor = ({
|
|
|
2847
2975
|
},
|
|
2848
2976
|
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"}`,
|
|
2849
2977
|
children: [
|
|
2850
|
-
/* @__PURE__ */ (0,
|
|
2978
|
+
/* @__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" }) }),
|
|
2851
2979
|
"AI Tools"
|
|
2852
2980
|
]
|
|
2853
2981
|
}
|
|
2854
2982
|
)
|
|
2855
2983
|
] }),
|
|
2856
|
-
/* @__PURE__ */ (0,
|
|
2857
|
-
/* @__PURE__ */ (0,
|
|
2984
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
2985
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2858
2986
|
"button",
|
|
2859
2987
|
{
|
|
2860
2988
|
type: "button",
|
|
@@ -2865,7 +2993,7 @@ var ImageEditor = ({
|
|
|
2865
2993
|
children: "\u21A9"
|
|
2866
2994
|
}
|
|
2867
2995
|
),
|
|
2868
|
-
/* @__PURE__ */ (0,
|
|
2996
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2869
2997
|
"button",
|
|
2870
2998
|
{
|
|
2871
2999
|
type: "button",
|
|
@@ -2876,7 +3004,7 @@ var ImageEditor = ({
|
|
|
2876
3004
|
children: "\u21AA"
|
|
2877
3005
|
}
|
|
2878
3006
|
),
|
|
2879
|
-
/* @__PURE__ */ (0,
|
|
3007
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2880
3008
|
"button",
|
|
2881
3009
|
{
|
|
2882
3010
|
type: "button",
|
|
@@ -2885,8 +3013,8 @@ var ImageEditor = ({
|
|
|
2885
3013
|
children: "Reset"
|
|
2886
3014
|
}
|
|
2887
3015
|
),
|
|
2888
|
-
/* @__PURE__ */ (0,
|
|
2889
|
-
/* @__PURE__ */ (0,
|
|
3016
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
3017
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2890
3018
|
"button",
|
|
2891
3019
|
{
|
|
2892
3020
|
type: "button",
|
|
@@ -2896,11 +3024,11 @@ var ImageEditor = ({
|
|
|
2896
3024
|
children: "-"
|
|
2897
3025
|
}
|
|
2898
3026
|
),
|
|
2899
|
-
/* @__PURE__ */ (0,
|
|
3027
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
2900
3028
|
Math.round(state.zoom * 100),
|
|
2901
3029
|
"%"
|
|
2902
3030
|
] }),
|
|
2903
|
-
/* @__PURE__ */ (0,
|
|
3031
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2904
3032
|
"button",
|
|
2905
3033
|
{
|
|
2906
3034
|
type: "button",
|
|
@@ -2910,8 +3038,8 @@ var ImageEditor = ({
|
|
|
2910
3038
|
children: "+"
|
|
2911
3039
|
}
|
|
2912
3040
|
),
|
|
2913
|
-
/* @__PURE__ */ (0,
|
|
2914
|
-
/* @__PURE__ */ (0,
|
|
3041
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
3042
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2915
3043
|
"button",
|
|
2916
3044
|
{
|
|
2917
3045
|
type: "button",
|
|
@@ -2922,7 +3050,7 @@ var ImageEditor = ({
|
|
|
2922
3050
|
children: "Hold Compare"
|
|
2923
3051
|
}
|
|
2924
3052
|
),
|
|
2925
|
-
/* @__PURE__ */ (0,
|
|
3053
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2926
3054
|
"button",
|
|
2927
3055
|
{
|
|
2928
3056
|
type: "button",
|
|
@@ -2933,16 +3061,16 @@ var ImageEditor = ({
|
|
|
2933
3061
|
)
|
|
2934
3062
|
] })
|
|
2935
3063
|
] }),
|
|
2936
|
-
transformTool.active && /* @__PURE__ */ (0,
|
|
2937
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */ (0,
|
|
2938
|
-
/* @__PURE__ */ (0,
|
|
2939
|
-
/* @__PURE__ */ (0,
|
|
3064
|
+
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" }),
|
|
3065
|
+
!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 }),
|
|
3066
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
3067
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2940
3068
|
"div",
|
|
2941
3069
|
{
|
|
2942
3070
|
ref: containerRef,
|
|
2943
3071
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
2944
3072
|
children: [
|
|
2945
|
-
/* @__PURE__ */ (0,
|
|
3073
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2946
3074
|
"canvas",
|
|
2947
3075
|
{
|
|
2948
3076
|
ref: canvasRef,
|
|
@@ -2959,7 +3087,7 @@ var ImageEditor = ({
|
|
|
2959
3087
|
className: `absolute inset-0 w-full h-full block ${transformTool.active ? "touch-none" : activeTab === "paint" ? "touch-none cursor-crosshair" : activeTab === "annotate" && state.activeTool === "type" ? "cursor-text" : activeTab === "annotate" && state.activeTool === "shape" ? "cursor-crosshair" : ""}`
|
|
2960
3088
|
}
|
|
2961
3089
|
),
|
|
2962
|
-
typeSession && /* @__PURE__ */ (0,
|
|
3090
|
+
typeSession && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2963
3091
|
"textarea",
|
|
2964
3092
|
{
|
|
2965
3093
|
ref: typeInputRef,
|
|
@@ -2981,11 +3109,11 @@ var ImageEditor = ({
|
|
|
2981
3109
|
]
|
|
2982
3110
|
}
|
|
2983
3111
|
),
|
|
2984
|
-
/* @__PURE__ */ (0,
|
|
2985
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
2986
|
-
/* @__PURE__ */ (0,
|
|
2987
|
-
/* @__PURE__ */ (0,
|
|
2988
|
-
/* @__PURE__ */ (0,
|
|
3112
|
+
/* @__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: [
|
|
3113
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3114
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
3115
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
3116
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2989
3117
|
"button",
|
|
2990
3118
|
{
|
|
2991
3119
|
type: "button",
|
|
@@ -2997,7 +3125,7 @@ var ImageEditor = ({
|
|
|
2997
3125
|
children: "Freeform"
|
|
2998
3126
|
}
|
|
2999
3127
|
),
|
|
3000
|
-
/* @__PURE__ */ (0,
|
|
3128
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3001
3129
|
"button",
|
|
3002
3130
|
{
|
|
3003
3131
|
type: "button",
|
|
@@ -3009,7 +3137,7 @@ var ImageEditor = ({
|
|
|
3009
3137
|
children: "1:1 Square"
|
|
3010
3138
|
}
|
|
3011
3139
|
),
|
|
3012
|
-
/* @__PURE__ */ (0,
|
|
3140
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3013
3141
|
"button",
|
|
3014
3142
|
{
|
|
3015
3143
|
type: "button",
|
|
@@ -3021,7 +3149,7 @@ var ImageEditor = ({
|
|
|
3021
3149
|
children: "4:3 Standard"
|
|
3022
3150
|
}
|
|
3023
3151
|
),
|
|
3024
|
-
/* @__PURE__ */ (0,
|
|
3152
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3025
3153
|
"button",
|
|
3026
3154
|
{
|
|
3027
3155
|
type: "button",
|
|
@@ -3033,7 +3161,7 @@ var ImageEditor = ({
|
|
|
3033
3161
|
children: "16:9 Wide"
|
|
3034
3162
|
}
|
|
3035
3163
|
),
|
|
3036
|
-
/* @__PURE__ */ (0,
|
|
3164
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3037
3165
|
"button",
|
|
3038
3166
|
{
|
|
3039
3167
|
type: "button",
|
|
@@ -3045,7 +3173,7 @@ var ImageEditor = ({
|
|
|
3045
3173
|
children: "3:2 Photo"
|
|
3046
3174
|
}
|
|
3047
3175
|
),
|
|
3048
|
-
/* @__PURE__ */ (0,
|
|
3176
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3049
3177
|
"button",
|
|
3050
3178
|
{
|
|
3051
3179
|
type: "button",
|
|
@@ -3058,10 +3186,10 @@ var ImageEditor = ({
|
|
|
3058
3186
|
}
|
|
3059
3187
|
)
|
|
3060
3188
|
] }),
|
|
3061
|
-
/* @__PURE__ */ (0,
|
|
3062
|
-
/* @__PURE__ */ (0,
|
|
3063
|
-
/* @__PURE__ */ (0,
|
|
3064
|
-
/* @__PURE__ */ (0,
|
|
3189
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3190
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
3191
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
3192
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3065
3193
|
"button",
|
|
3066
3194
|
{
|
|
3067
3195
|
type: "button",
|
|
@@ -3070,7 +3198,7 @@ var ImageEditor = ({
|
|
|
3070
3198
|
children: "Rotate -90\xB0"
|
|
3071
3199
|
}
|
|
3072
3200
|
),
|
|
3073
|
-
/* @__PURE__ */ (0,
|
|
3201
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3074
3202
|
"button",
|
|
3075
3203
|
{
|
|
3076
3204
|
type: "button",
|
|
@@ -3079,7 +3207,7 @@ var ImageEditor = ({
|
|
|
3079
3207
|
children: "Rotate +90\xB0"
|
|
3080
3208
|
}
|
|
3081
3209
|
),
|
|
3082
|
-
/* @__PURE__ */ (0,
|
|
3210
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3083
3211
|
"button",
|
|
3084
3212
|
{
|
|
3085
3213
|
type: "button",
|
|
@@ -3088,7 +3216,7 @@ var ImageEditor = ({
|
|
|
3088
3216
|
children: "Flip Horizontal"
|
|
3089
3217
|
}
|
|
3090
3218
|
),
|
|
3091
|
-
/* @__PURE__ */ (0,
|
|
3219
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3092
3220
|
"button",
|
|
3093
3221
|
{
|
|
3094
3222
|
type: "button",
|
|
@@ -3099,10 +3227,10 @@ var ImageEditor = ({
|
|
|
3099
3227
|
)
|
|
3100
3228
|
] })
|
|
3101
3229
|
] }),
|
|
3102
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
3103
|
-
/* @__PURE__ */ (0,
|
|
3104
|
-
/* @__PURE__ */ (0,
|
|
3105
|
-
/* @__PURE__ */ (0,
|
|
3230
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3231
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3232
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
3233
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3106
3234
|
"button",
|
|
3107
3235
|
{
|
|
3108
3236
|
type: "button",
|
|
@@ -3112,25 +3240,25 @@ var ImageEditor = ({
|
|
|
3112
3240
|
}
|
|
3113
3241
|
)
|
|
3114
3242
|
] }),
|
|
3115
|
-
/* @__PURE__ */ (0,
|
|
3116
|
-
|
|
3117
|
-
/* @__PURE__ */ (0,
|
|
3243
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Histogram, { histogram: editor.histogram }),
|
|
3244
|
+
import_image_editor15.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react14.default.Fragment, { children: [
|
|
3245
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3118
3246
|
ControlSlider,
|
|
3119
3247
|
{
|
|
3120
3248
|
spec,
|
|
3121
|
-
value: (0,
|
|
3249
|
+
value: (0, import_image_editor15.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
3122
3250
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
3123
3251
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
3124
3252
|
}
|
|
3125
3253
|
),
|
|
3126
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
3254
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3127
3255
|
"div",
|
|
3128
3256
|
{
|
|
3129
3257
|
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",
|
|
3130
3258
|
"data-testid": "image-editor-process-notice",
|
|
3131
3259
|
children: [
|
|
3132
|
-
/* @__PURE__ */ (0,
|
|
3133
|
-
/* @__PURE__ */ (0,
|
|
3260
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
3261
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3134
3262
|
"button",
|
|
3135
3263
|
{
|
|
3136
3264
|
type: "button",
|
|
@@ -3143,7 +3271,7 @@ var ImageEditor = ({
|
|
|
3143
3271
|
}
|
|
3144
3272
|
)
|
|
3145
3273
|
] }, spec.id)),
|
|
3146
|
-
/* @__PURE__ */ (0,
|
|
3274
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3147
3275
|
AdjustmentLayersPanel,
|
|
3148
3276
|
{
|
|
3149
3277
|
controller,
|
|
@@ -3152,9 +3280,9 @@ var ImageEditor = ({
|
|
|
3152
3280
|
}
|
|
3153
3281
|
) })
|
|
3154
3282
|
] }),
|
|
3155
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
3156
|
-
/* @__PURE__ */ (0,
|
|
3157
|
-
/* @__PURE__ */ (0,
|
|
3283
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3284
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
3285
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3158
3286
|
"button",
|
|
3159
3287
|
{
|
|
3160
3288
|
type: "button",
|
|
@@ -3165,12 +3293,14 @@ var ImageEditor = ({
|
|
|
3165
3293
|
children: "Free Transform"
|
|
3166
3294
|
}
|
|
3167
3295
|
),
|
|
3168
|
-
/* @__PURE__ */ (0,
|
|
3296
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LayersPanel, { controller }),
|
|
3297
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
|
|
3298
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ColorProfilePanel, { controller })
|
|
3169
3299
|
] }),
|
|
3170
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
3171
|
-
/* @__PURE__ */ (0,
|
|
3172
|
-
/* @__PURE__ */ (0,
|
|
3173
|
-
/* @__PURE__ */ (0,
|
|
3300
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3301
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
3302
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BrushOptionsBar, { controller }),
|
|
3303
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3174
3304
|
"button",
|
|
3175
3305
|
{
|
|
3176
3306
|
type: "button",
|
|
@@ -3181,12 +3311,12 @@ var ImageEditor = ({
|
|
|
3181
3311
|
children: "Free Transform"
|
|
3182
3312
|
}
|
|
3183
3313
|
),
|
|
3184
|
-
paintError && /* @__PURE__ */ (0,
|
|
3185
|
-
/* @__PURE__ */ (0,
|
|
3314
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
3315
|
+
/* @__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 }) })
|
|
3186
3316
|
] }),
|
|
3187
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
3188
|
-
/* @__PURE__ */ (0,
|
|
3189
|
-
/* @__PURE__ */ (0,
|
|
3317
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3318
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
|
|
3319
|
+
/* @__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)(
|
|
3190
3320
|
"button",
|
|
3191
3321
|
{
|
|
3192
3322
|
type: "button",
|
|
@@ -3197,13 +3327,13 @@ var ImageEditor = ({
|
|
|
3197
3327
|
},
|
|
3198
3328
|
t
|
|
3199
3329
|
)) }),
|
|
3200
|
-
state.activeTool === "shape" && /* @__PURE__ */ (0,
|
|
3201
|
-
state.activeTool === "type" && /* @__PURE__ */ (0,
|
|
3202
|
-
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0,
|
|
3203
|
-
shapeTypeError && /* @__PURE__ */ (0,
|
|
3204
|
-
/* @__PURE__ */ (0,
|
|
3205
|
-
/* @__PURE__ */ (0,
|
|
3206
|
-
/* @__PURE__ */ (0,
|
|
3330
|
+
state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
|
|
3331
|
+
state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
|
|
3332
|
+
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" }),
|
|
3333
|
+
shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
|
|
3334
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3335
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
3336
|
+
/* @__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)(
|
|
3207
3337
|
"button",
|
|
3208
3338
|
{
|
|
3209
3339
|
type: "button",
|
|
@@ -3213,9 +3343,9 @@ var ImageEditor = ({
|
|
|
3213
3343
|
},
|
|
3214
3344
|
t
|
|
3215
3345
|
)) }),
|
|
3216
|
-
/* @__PURE__ */ (0,
|
|
3217
|
-
/* @__PURE__ */ (0,
|
|
3218
|
-
/* @__PURE__ */ (0,
|
|
3346
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
3347
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
3348
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3219
3349
|
"input",
|
|
3220
3350
|
{
|
|
3221
3351
|
type: "color",
|
|
@@ -3224,15 +3354,15 @@ var ImageEditor = ({
|
|
|
3224
3354
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
3225
3355
|
}
|
|
3226
3356
|
),
|
|
3227
|
-
/* @__PURE__ */ (0,
|
|
3228
|
-
/* @__PURE__ */ (0,
|
|
3229
|
-
/* @__PURE__ */ (0,
|
|
3230
|
-
/* @__PURE__ */ (0,
|
|
3357
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
3358
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
3359
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Width:" }),
|
|
3360
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-mono", children: [
|
|
3231
3361
|
strokeWidth,
|
|
3232
3362
|
"px"
|
|
3233
3363
|
] })
|
|
3234
3364
|
] }),
|
|
3235
|
-
/* @__PURE__ */ (0,
|
|
3365
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3236
3366
|
"input",
|
|
3237
3367
|
{
|
|
3238
3368
|
type: "range",
|
|
@@ -3245,10 +3375,10 @@ var ImageEditor = ({
|
|
|
3245
3375
|
)
|
|
3246
3376
|
] })
|
|
3247
3377
|
] }),
|
|
3248
|
-
/* @__PURE__ */ (0,
|
|
3249
|
-
/* @__PURE__ */ (0,
|
|
3250
|
-
/* @__PURE__ */ (0,
|
|
3251
|
-
/* @__PURE__ */ (0,
|
|
3378
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3379
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
3380
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-2", children: [
|
|
3381
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3252
3382
|
"input",
|
|
3253
3383
|
{
|
|
3254
3384
|
type: "text",
|
|
@@ -3259,7 +3389,7 @@ var ImageEditor = ({
|
|
|
3259
3389
|
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"
|
|
3260
3390
|
}
|
|
3261
3391
|
),
|
|
3262
|
-
/* @__PURE__ */ (0,
|
|
3392
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3263
3393
|
"button",
|
|
3264
3394
|
{
|
|
3265
3395
|
type: "button",
|
|
@@ -3269,14 +3399,14 @@ var ImageEditor = ({
|
|
|
3269
3399
|
}
|
|
3270
3400
|
)
|
|
3271
3401
|
] }),
|
|
3272
|
-
/* @__PURE__ */ (0,
|
|
3273
|
-
/* @__PURE__ */ (0,
|
|
3274
|
-
/* @__PURE__ */ (0,
|
|
3402
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
3403
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Font Size:" }),
|
|
3404
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "font-mono", children: [
|
|
3275
3405
|
fontSize,
|
|
3276
3406
|
"px"
|
|
3277
3407
|
] })
|
|
3278
3408
|
] }),
|
|
3279
|
-
/* @__PURE__ */ (0,
|
|
3409
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3280
3410
|
"input",
|
|
3281
3411
|
{
|
|
3282
3412
|
type: "range",
|
|
@@ -3287,14 +3417,14 @@ var ImageEditor = ({
|
|
|
3287
3417
|
className: "w-full accent-indigo-500"
|
|
3288
3418
|
}
|
|
3289
3419
|
),
|
|
3290
|
-
/* @__PURE__ */ (0,
|
|
3291
|
-
/* @__PURE__ */ (0,
|
|
3292
|
-
/* @__PURE__ */ (0,
|
|
3420
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3421
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3422
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-slate-400", children: [
|
|
3293
3423
|
"Layers (",
|
|
3294
3424
|
state.annotations.length,
|
|
3295
3425
|
")"
|
|
3296
3426
|
] }),
|
|
3297
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
3427
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3298
3428
|
"button",
|
|
3299
3429
|
{
|
|
3300
3430
|
type: "button",
|
|
@@ -3303,7 +3433,7 @@ var ImageEditor = ({
|
|
|
3303
3433
|
children: "Delete Selected"
|
|
3304
3434
|
}
|
|
3305
3435
|
),
|
|
3306
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
3436
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3307
3437
|
"button",
|
|
3308
3438
|
{
|
|
3309
3439
|
type: "button",
|
|
@@ -3314,10 +3444,10 @@ var ImageEditor = ({
|
|
|
3314
3444
|
)
|
|
3315
3445
|
] })
|
|
3316
3446
|
] }),
|
|
3317
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
3318
|
-
/* @__PURE__ */ (0,
|
|
3319
|
-
/* @__PURE__ */ (0,
|
|
3320
|
-
/* @__PURE__ */ (0,
|
|
3447
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3448
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3449
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
3450
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3321
3451
|
"button",
|
|
3322
3452
|
{
|
|
3323
3453
|
type: "button",
|
|
@@ -3327,8 +3457,8 @@ var ImageEditor = ({
|
|
|
3327
3457
|
}
|
|
3328
3458
|
)
|
|
3329
3459
|
] }),
|
|
3330
|
-
/* @__PURE__ */ (0,
|
|
3331
|
-
/* @__PURE__ */ (0,
|
|
3460
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
3461
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3332
3462
|
"input",
|
|
3333
3463
|
{
|
|
3334
3464
|
type: "checkbox",
|
|
@@ -3337,12 +3467,12 @@ var ImageEditor = ({
|
|
|
3337
3467
|
className: "rounded accent-indigo-500"
|
|
3338
3468
|
}
|
|
3339
3469
|
),
|
|
3340
|
-
/* @__PURE__ */ (0,
|
|
3470
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
3341
3471
|
] }),
|
|
3342
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
3343
|
-
/* @__PURE__ */ (0,
|
|
3344
|
-
/* @__PURE__ */ (0,
|
|
3345
|
-
/* @__PURE__ */ (0,
|
|
3472
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3473
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3474
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
3475
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3346
3476
|
"input",
|
|
3347
3477
|
{
|
|
3348
3478
|
type: "text",
|
|
@@ -3353,8 +3483,8 @@ var ImageEditor = ({
|
|
|
3353
3483
|
}
|
|
3354
3484
|
)
|
|
3355
3485
|
] }),
|
|
3356
|
-
/* @__PURE__ */ (0,
|
|
3357
|
-
/* @__PURE__ */ (0,
|
|
3486
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-2", children: [
|
|
3487
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3358
3488
|
"button",
|
|
3359
3489
|
{
|
|
3360
3490
|
type: "button",
|
|
@@ -3363,7 +3493,7 @@ var ImageEditor = ({
|
|
|
3363
3493
|
children: "Threshold Mode"
|
|
3364
3494
|
}
|
|
3365
3495
|
),
|
|
3366
|
-
/* @__PURE__ */ (0,
|
|
3496
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3367
3497
|
"button",
|
|
3368
3498
|
{
|
|
3369
3499
|
type: "button",
|
|
@@ -3373,12 +3503,12 @@ var ImageEditor = ({
|
|
|
3373
3503
|
}
|
|
3374
3504
|
)
|
|
3375
3505
|
] }),
|
|
3376
|
-
/* @__PURE__ */ (0,
|
|
3377
|
-
/* @__PURE__ */ (0,
|
|
3378
|
-
/* @__PURE__ */ (0,
|
|
3379
|
-
/* @__PURE__ */ (0,
|
|
3506
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3507
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3508
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
3509
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
3380
3510
|
] }),
|
|
3381
|
-
/* @__PURE__ */ (0,
|
|
3511
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3382
3512
|
"input",
|
|
3383
3513
|
{
|
|
3384
3514
|
type: "range",
|
|
@@ -3392,12 +3522,12 @@ var ImageEditor = ({
|
|
|
3392
3522
|
}
|
|
3393
3523
|
)
|
|
3394
3524
|
] }),
|
|
3395
|
-
/* @__PURE__ */ (0,
|
|
3396
|
-
/* @__PURE__ */ (0,
|
|
3397
|
-
/* @__PURE__ */ (0,
|
|
3398
|
-
/* @__PURE__ */ (0,
|
|
3525
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3526
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3527
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
3528
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
3399
3529
|
] }),
|
|
3400
|
-
/* @__PURE__ */ (0,
|
|
3530
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3401
3531
|
"input",
|
|
3402
3532
|
{
|
|
3403
3533
|
type: "range",
|
|
@@ -3411,12 +3541,12 @@ var ImageEditor = ({
|
|
|
3411
3541
|
}
|
|
3412
3542
|
)
|
|
3413
3543
|
] }),
|
|
3414
|
-
/* @__PURE__ */ (0,
|
|
3415
|
-
/* @__PURE__ */ (0,
|
|
3416
|
-
/* @__PURE__ */ (0,
|
|
3417
|
-
/* @__PURE__ */ (0,
|
|
3544
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
|
|
3545
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3546
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Softness:" }),
|
|
3547
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
3418
3548
|
] }),
|
|
3419
|
-
/* @__PURE__ */ (0,
|
|
3549
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3420
3550
|
"input",
|
|
3421
3551
|
{
|
|
3422
3552
|
type: "range",
|
|
@@ -3428,8 +3558,8 @@ var ImageEditor = ({
|
|
|
3428
3558
|
}
|
|
3429
3559
|
)
|
|
3430
3560
|
] }),
|
|
3431
|
-
/* @__PURE__ */ (0,
|
|
3432
|
-
/* @__PURE__ */ (0,
|
|
3561
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
3562
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3433
3563
|
"input",
|
|
3434
3564
|
{
|
|
3435
3565
|
type: "checkbox",
|
|
@@ -3438,12 +3568,12 @@ var ImageEditor = ({
|
|
|
3438
3568
|
className: "rounded accent-indigo-500"
|
|
3439
3569
|
}
|
|
3440
3570
|
),
|
|
3441
|
-
/* @__PURE__ */ (0,
|
|
3571
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Invert Mask" })
|
|
3442
3572
|
] })
|
|
3443
3573
|
] })
|
|
3444
3574
|
] }),
|
|
3445
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
3446
|
-
/* @__PURE__ */ (0,
|
|
3575
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3576
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3447
3577
|
SelectionOptionsBar,
|
|
3448
3578
|
{
|
|
3449
3579
|
controller,
|
|
@@ -3453,9 +3583,9 @@ var ImageEditor = ({
|
|
|
3453
3583
|
quickMask: Boolean(state.quickMask)
|
|
3454
3584
|
}
|
|
3455
3585
|
),
|
|
3456
|
-
selectionError && /* @__PURE__ */ (0,
|
|
3457
|
-
/* @__PURE__ */ (0,
|
|
3458
|
-
/* @__PURE__ */ (0,
|
|
3586
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
3587
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex gap-1", children: [
|
|
3588
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3459
3589
|
"button",
|
|
3460
3590
|
{
|
|
3461
3591
|
type: "button",
|
|
@@ -3466,7 +3596,7 @@ var ImageEditor = ({
|
|
|
3466
3596
|
children: "Transform Selection"
|
|
3467
3597
|
}
|
|
3468
3598
|
),
|
|
3469
|
-
/* @__PURE__ */ (0,
|
|
3599
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3470
3600
|
"button",
|
|
3471
3601
|
{
|
|
3472
3602
|
type: "button",
|
|
@@ -3478,12 +3608,12 @@ var ImageEditor = ({
|
|
|
3478
3608
|
}
|
|
3479
3609
|
)
|
|
3480
3610
|
] }),
|
|
3481
|
-
/* @__PURE__ */ (0,
|
|
3611
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
3482
3612
|
] }),
|
|
3483
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
3484
|
-
/* @__PURE__ */ (0,
|
|
3485
|
-
/* @__PURE__ */ (0,
|
|
3486
|
-
/* @__PURE__ */ (0,
|
|
3613
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3614
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
3615
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Results go to" }),
|
|
3616
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3487
3617
|
"select",
|
|
3488
3618
|
{
|
|
3489
3619
|
"aria-label": "AI result target",
|
|
@@ -3491,54 +3621,54 @@ var ImageEditor = ({
|
|
|
3491
3621
|
onChange: (e) => setAiTarget(e.target.value),
|
|
3492
3622
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
3493
3623
|
children: [
|
|
3494
|
-
/* @__PURE__ */ (0,
|
|
3495
|
-
/* @__PURE__ */ (0,
|
|
3496
|
-
/* @__PURE__ */ (0,
|
|
3624
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
3625
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
3626
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "replace", children: "Replace image" })
|
|
3497
3627
|
]
|
|
3498
3628
|
}
|
|
3499
3629
|
)
|
|
3500
3630
|
] }),
|
|
3501
|
-
/* @__PURE__ */ (0,
|
|
3502
|
-
/* @__PURE__ */ (0,
|
|
3503
|
-
/* @__PURE__ */ (0,
|
|
3504
|
-
/* @__PURE__ */ (0,
|
|
3631
|
+
/* @__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: [
|
|
3632
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3633
|
+
/* @__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: [
|
|
3634
|
+
/* @__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" }) }),
|
|
3505
3635
|
"Background Removal"
|
|
3506
3636
|
] }),
|
|
3507
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
3637
|
+
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..." })
|
|
3508
3638
|
] }),
|
|
3509
|
-
/* @__PURE__ */ (0,
|
|
3510
|
-
/* @__PURE__ */ (0,
|
|
3639
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
3640
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3511
3641
|
"button",
|
|
3512
3642
|
{
|
|
3513
3643
|
type: "button",
|
|
3514
3644
|
onClick: handleRemoveBackground,
|
|
3515
3645
|
disabled: isRemovingBg || isInpainting,
|
|
3516
3646
|
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",
|
|
3517
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
3518
|
-
/* @__PURE__ */ (0,
|
|
3647
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3648
|
+
/* @__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" }),
|
|
3519
3649
|
"Removing Background..."
|
|
3520
|
-
] }) : /* @__PURE__ */ (0,
|
|
3521
|
-
/* @__PURE__ */ (0,
|
|
3650
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3651
|
+
/* @__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" }) }),
|
|
3522
3652
|
"Remove Background"
|
|
3523
3653
|
] })
|
|
3524
3654
|
}
|
|
3525
3655
|
)
|
|
3526
3656
|
] }),
|
|
3527
|
-
/* @__PURE__ */ (0,
|
|
3528
|
-
/* @__PURE__ */ (0,
|
|
3529
|
-
/* @__PURE__ */ (0,
|
|
3530
|
-
/* @__PURE__ */ (0,
|
|
3531
|
-
/* @__PURE__ */ (0,
|
|
3532
|
-
/* @__PURE__ */ (0,
|
|
3657
|
+
/* @__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: [
|
|
3658
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3659
|
+
/* @__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: [
|
|
3660
|
+
/* @__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: [
|
|
3661
|
+
/* @__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" }),
|
|
3662
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "m14 7 3 3" })
|
|
3533
3663
|
] }),
|
|
3534
3664
|
"Generative Inpainting"
|
|
3535
3665
|
] }),
|
|
3536
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
3666
|
+
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..." })
|
|
3537
3667
|
] }),
|
|
3538
|
-
/* @__PURE__ */ (0,
|
|
3539
|
-
/* @__PURE__ */ (0,
|
|
3540
|
-
/* @__PURE__ */ (0,
|
|
3541
|
-
/* @__PURE__ */ (0,
|
|
3668
|
+
/* @__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." }),
|
|
3669
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3670
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
3671
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3542
3672
|
"textarea",
|
|
3543
3673
|
{
|
|
3544
3674
|
id: "ai-inpaint-prompt-react",
|
|
@@ -3550,10 +3680,10 @@ var ImageEditor = ({
|
|
|
3550
3680
|
}
|
|
3551
3681
|
)
|
|
3552
3682
|
] }),
|
|
3553
|
-
/* @__PURE__ */ (0,
|
|
3554
|
-
/* @__PURE__ */ (0,
|
|
3555
|
-
/* @__PURE__ */ (0,
|
|
3556
|
-
/* @__PURE__ */ (0,
|
|
3683
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3684
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
3685
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
3686
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3557
3687
|
"button",
|
|
3558
3688
|
{
|
|
3559
3689
|
type: "button",
|
|
@@ -3566,7 +3696,7 @@ var ImageEditor = ({
|
|
|
3566
3696
|
]
|
|
3567
3697
|
}
|
|
3568
3698
|
),
|
|
3569
|
-
/* @__PURE__ */ (0,
|
|
3699
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3570
3700
|
"button",
|
|
3571
3701
|
{
|
|
3572
3702
|
type: "button",
|
|
@@ -3581,25 +3711,25 @@ var ImageEditor = ({
|
|
|
3581
3711
|
)
|
|
3582
3712
|
] })
|
|
3583
3713
|
] }),
|
|
3584
|
-
/* @__PURE__ */ (0,
|
|
3714
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3585
3715
|
"button",
|
|
3586
3716
|
{
|
|
3587
3717
|
type: "button",
|
|
3588
3718
|
onClick: handleInpaint,
|
|
3589
3719
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
3590
3720
|
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",
|
|
3591
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
3592
|
-
/* @__PURE__ */ (0,
|
|
3721
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3722
|
+
/* @__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" }),
|
|
3593
3723
|
"Generating Inpaint..."
|
|
3594
|
-
] }) : /* @__PURE__ */ (0,
|
|
3595
|
-
/* @__PURE__ */ (0,
|
|
3724
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
3725
|
+
/* @__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" }) }),
|
|
3596
3726
|
"Apply Inpainting"
|
|
3597
3727
|
] })
|
|
3598
3728
|
}
|
|
3599
3729
|
)
|
|
3600
3730
|
] }),
|
|
3601
|
-
aiError && /* @__PURE__ */ (0,
|
|
3602
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
3731
|
+
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 }),
|
|
3732
|
+
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 })
|
|
3603
3733
|
] })
|
|
3604
3734
|
] })
|
|
3605
3735
|
] })
|
|
@@ -3611,6 +3741,7 @@ var ImageEditor = ({
|
|
|
3611
3741
|
0 && (module.exports = {
|
|
3612
3742
|
AdjustmentLayersPanel,
|
|
3613
3743
|
BrushOptionsBar,
|
|
3744
|
+
ColorProfilePanel,
|
|
3614
3745
|
ControlSlider,
|
|
3615
3746
|
CurvesEditor,
|
|
3616
3747
|
FreeTransformOptionsBar,
|