@pixerate/editor-react 0.76.0 → 0.77.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/PaintGradientEditorView-CCPCY5Ib.d.cts +14 -0
- package/dist/PaintGradientEditorView-CCPCY5Ib.d.ts +14 -0
- package/dist/canvas/index.cjs +662 -561
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +36 -5
- package/dist/canvas/index.d.ts +36 -5
- package/dist/canvas/index.js +232 -129
- package/dist/canvas/index.js.map +1 -1
- package/dist/chunk-MO354USR.js +126 -0
- package/dist/chunk-MO354USR.js.map +1 -0
- package/dist/{chunk-LWMUV5TC.js → chunk-QARGR5E5.js} +278 -253
- package/dist/chunk-QARGR5E5.js.map +1 -0
- package/dist/image-editor/index.cjs +677 -531
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +8 -2
- package/dist/image-editor/index.d.ts +8 -2
- package/dist/image-editor/index.js +4 -1
- package/dist/index.cjs +1095 -949
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/paint-editor/index.cjs +438 -289
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +8 -3
- package/dist/paint-editor/index.d.ts +8 -3
- package/dist/paint-editor/index.js +215 -187
- package/dist/paint-editor/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-LWMUV5TC.js.map +0 -1
|
@@ -40,6 +40,7 @@ __export(image_editor_exports, {
|
|
|
40
40
|
ImageEditor: () => ImageEditor,
|
|
41
41
|
LayerEffectsPanel: () => LayerEffectsPanel,
|
|
42
42
|
LayersPanel: () => LayersPanel,
|
|
43
|
+
PaintGradientEditor: () => PaintGradientEditor,
|
|
43
44
|
RefineEdgePanel: () => RefineEdgePanel,
|
|
44
45
|
SelectionOptionsBar: () => SelectionOptionsBar,
|
|
45
46
|
ShapeOptionsBar: () => ShapeOptionsBar,
|
|
@@ -208,8 +209,8 @@ function useImageEditor(options = {}) {
|
|
|
208
209
|
}
|
|
209
210
|
|
|
210
211
|
// src/image-editor/ImageEditor.tsx
|
|
211
|
-
var
|
|
212
|
-
var
|
|
212
|
+
var import_react15 = __toESM(require("react"), 1);
|
|
213
|
+
var import_image_editor17 = require("@pixerate/editor/image-editor");
|
|
213
214
|
|
|
214
215
|
// src/image-editor/ControlSlider.tsx
|
|
215
216
|
var import_image_editor2 = require("@pixerate/editor/image-editor");
|
|
@@ -1259,16 +1260,148 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
1259
1260
|
};
|
|
1260
1261
|
|
|
1261
1262
|
// src/image-editor/BrushOptionsBar.tsx
|
|
1262
|
-
var
|
|
1263
|
+
var import_react8 = require("react");
|
|
1264
|
+
var import_image_editor9 = require("@pixerate/editor/image-editor");
|
|
1265
|
+
var import_image_editor10 = require("@pixerate/editor/image-editor");
|
|
1266
|
+
|
|
1267
|
+
// src/image-editor/PaintGradientEditor.tsx
|
|
1263
1268
|
var import_image_editor8 = require("@pixerate/editor/image-editor");
|
|
1269
|
+
|
|
1270
|
+
// src/paint-editor/PaintGradientEditorView.tsx
|
|
1271
|
+
var import_react7 = require("react");
|
|
1264
1272
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1273
|
+
var button2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-200 hover:bg-slate-700 disabled:opacity-40";
|
|
1274
|
+
var select = "rounded bg-slate-800 px-1 py-0.5 text-[11px]";
|
|
1275
|
+
var number = "w-16 rounded bg-slate-800 px-1 py-0.5 text-[11px]";
|
|
1276
|
+
var pct = (v) => Math.round(v * 1e3) / 10;
|
|
1277
|
+
var PaintGradientEditorView = ({ value, onChange, colors, className, kit }) => {
|
|
1278
|
+
const {
|
|
1279
|
+
PAINT_GRADIENT_MAPPINGS,
|
|
1280
|
+
PAINT_GRADIENT_MAPPING_LABELS,
|
|
1281
|
+
PAINT_GRADIENT_PRESETS,
|
|
1282
|
+
PAINT_GRADIENT_REPEATS,
|
|
1283
|
+
PAINT_GRADIENT_REPEAT_LABELS,
|
|
1284
|
+
PAINT_GRADIENT_SPACES,
|
|
1285
|
+
PAINT_GRADIENT_SPACE_LABELS,
|
|
1286
|
+
addPaintGradientStop,
|
|
1287
|
+
paintGradientMappingFor,
|
|
1288
|
+
paintSourceCss,
|
|
1289
|
+
removePaintGradientStop,
|
|
1290
|
+
reversePaintGradient,
|
|
1291
|
+
updatePaintGradientStop
|
|
1292
|
+
} = kit;
|
|
1293
|
+
const [selected, setSelected] = (0, import_react7.useState)(0);
|
|
1294
|
+
const sel = Math.min(selected, value.stops.length - 1);
|
|
1295
|
+
const stop = value.stops[sel];
|
|
1296
|
+
const map = value.map;
|
|
1297
|
+
const stopHex = (c) => c === "paint" ? colors.paint : c === "secondary" ? colors.secondary : c;
|
|
1298
|
+
const patchStop = (patch) => {
|
|
1299
|
+
const r = updatePaintGradientStop(value, sel, patch);
|
|
1300
|
+
setSelected(r.index);
|
|
1301
|
+
onChange(r.paint);
|
|
1302
|
+
};
|
|
1303
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `flex flex-col gap-1.5 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "paint-gradient-editor", "aria-label": "Gradient paint", children: [
|
|
1304
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
1305
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("select", { "aria-label": "Gradient preset", className: select, value: "", onChange: (e) => e.target.value && (setSelected(0), onChange(PAINT_GRADIENT_PRESETS[Number(e.target.value)].paint)), children: [
|
|
1306
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", children: "Presets\u2026" }),
|
|
1307
|
+
PAINT_GRADIENT_PRESETS.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: i, children: p.name }, p.name))
|
|
1308
|
+
] }),
|
|
1309
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: button2, onClick: () => onChange(reversePaintGradient(value)), children: "Reverse" })
|
|
1310
|
+
] }),
|
|
1311
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1312
|
+
"div",
|
|
1313
|
+
{
|
|
1314
|
+
role: "slider",
|
|
1315
|
+
tabIndex: 0,
|
|
1316
|
+
"aria-label": "Gradient ramp: click to add a stop",
|
|
1317
|
+
"aria-valuemin": 0,
|
|
1318
|
+
"aria-valuemax": 100,
|
|
1319
|
+
"aria-valuenow": pct(stop.offset),
|
|
1320
|
+
"data-testid": "paint-gradient-ramp",
|
|
1321
|
+
className: "relative h-6 cursor-copy rounded ring-1 ring-slate-700",
|
|
1322
|
+
style: { background: paintSourceCss(value, colors) },
|
|
1323
|
+
onClick: (e) => {
|
|
1324
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
1325
|
+
const r = addPaintGradientStop(value, rect.width ? (e.clientX - rect.left) / rect.width : 0.5, colors);
|
|
1326
|
+
if (r.index >= 0) {
|
|
1327
|
+
setSelected(r.index);
|
|
1328
|
+
onChange(r.paint);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
),
|
|
1333
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "relative h-4", "aria-label": "Stops", children: value.stops.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1334
|
+
"button",
|
|
1335
|
+
{
|
|
1336
|
+
type: "button",
|
|
1337
|
+
"aria-label": `Stop ${i + 1} at ${pct(s.offset)}%`,
|
|
1338
|
+
"aria-pressed": i === sel,
|
|
1339
|
+
className: `absolute top-0 h-4 w-3 -translate-x-1/2 rounded-sm ring-1 ${i === sel ? "ring-white" : "ring-slate-600"}`,
|
|
1340
|
+
style: { left: `${s.offset * 100}%`, background: stopHex(s.color) },
|
|
1341
|
+
onClick: () => setSelected(i)
|
|
1342
|
+
},
|
|
1343
|
+
i
|
|
1344
|
+
)) }),
|
|
1345
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap items-center gap-1", "data-testid": "paint-gradient-stop", children: [
|
|
1346
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("select", { "aria-label": "Stop colour source", className: select, value: stop.color === "paint" || stop.color === "secondary" ? stop.color : "color", onChange: (e) => patchStop({ color: e.target.value === "color" ? stopHex(stop.color) : e.target.value }), children: [
|
|
1347
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "color", children: "Colour" }),
|
|
1348
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "paint", children: "Paint colour" }),
|
|
1349
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "secondary", children: "Second colour" })
|
|
1350
|
+
] }),
|
|
1351
|
+
stop.color !== "paint" && stop.color !== "secondary" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "color", "aria-label": "Stop colour", value: stop.color, onChange: (e) => patchStop({ color: e.target.value }), className: "h-6 w-8 rounded bg-transparent" }),
|
|
1352
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1353
|
+
"At",
|
|
1354
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "number", "aria-label": "Stop position", min: 0, max: 100, step: 1, value: pct(stop.offset), onChange: (e) => patchStop({ offset: Number(e.target.value) / 100 }), className: number }),
|
|
1355
|
+
"%"
|
|
1356
|
+
] }),
|
|
1357
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1358
|
+
"Opacity",
|
|
1359
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "number", "aria-label": "Stop opacity", min: 0, max: 100, step: 5, value: pct(stop.opacity ?? 1), onChange: (e) => patchStop({ opacity: Number(e.target.value) / 100 }), className: number }),
|
|
1360
|
+
"%"
|
|
1361
|
+
] }),
|
|
1362
|
+
sel < value.stops.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1363
|
+
"Midpoint",
|
|
1364
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "number", "aria-label": "Stop midpoint", min: 5, max: 95, step: 1, value: pct(stop.midpoint ?? 0.5), onChange: (e) => patchStop({ midpoint: Number(e.target.value) / 100 }), className: number }),
|
|
1365
|
+
"%"
|
|
1366
|
+
] }),
|
|
1367
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: button2, disabled: value.stops.length <= 2, onClick: () => (setSelected(Math.max(0, sel - 1)), onChange(removePaintGradientStop(value, sel))), children: "Remove stop" })
|
|
1368
|
+
] }),
|
|
1369
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap items-center gap-1", "data-testid": "paint-gradient-mapping", children: [
|
|
1370
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("select", { "aria-label": "Gradient follows", className: select, value: map.by, onChange: (e) => onChange({ ...value, map: paintGradientMappingFor(e.target.value, map) }), children: PAINT_GRADIENT_MAPPINGS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: m, children: PAINT_GRADIENT_MAPPING_LABELS[m] }, m)) }),
|
|
1371
|
+
map.by === "distance" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1372
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "number", "aria-label": "Gradient length", min: 1, max: 1e5, value: map.length, onChange: (e) => onChange({ ...value, map: { ...map, length: Math.max(1, Number(e.target.value) || 1) } }), className: number }),
|
|
1373
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("select", { "aria-label": "Gradient length unit", className: select, value: map.unit ?? "px", onChange: (e) => onChange({ ...value, map: { ...map, unit: e.target.value } }), children: [
|
|
1374
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "px", children: "px" }),
|
|
1375
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "dabs", children: "dabs" })
|
|
1376
|
+
] })
|
|
1377
|
+
] }),
|
|
1378
|
+
map.by === "time" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "number", "aria-label": "Gradient duration", min: 1, max: 6e5, value: map.duration, onChange: (e) => onChange({ ...value, map: { ...map, duration: Math.max(1, Number(e.target.value) || 1) } }), className: number }),
|
|
1379
|
+
map.by === "random" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "number", "aria-label": "Dabs per pick", min: 1, max: 500, value: map.every ?? 1, onChange: (e) => onChange({ ...value, map: { ...map, every: Math.max(1, Math.round(Number(e.target.value) || 1)) } }), className: number }),
|
|
1380
|
+
(map.by === "distance" || map.by === "time") && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("select", { "aria-label": "Gradient repeat", className: select, value: map.repeat ?? "clamp", onChange: (e) => onChange({ ...value, map: { ...map, repeat: e.target.value } }), children: PAINT_GRADIENT_REPEATS.map((r) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: r, children: PAINT_GRADIENT_REPEAT_LABELS[r] }, r)) })
|
|
1381
|
+
] }),
|
|
1382
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
1383
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("select", { "aria-label": "Gradient mixing", className: select, value: value.space, onChange: (e) => onChange({ ...value, space: e.target.value }), children: PAINT_GRADIENT_SPACES.map((s) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: s, children: PAINT_GRADIENT_SPACE_LABELS[s] }, s)) }),
|
|
1384
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex flex-1 items-center gap-1", children: [
|
|
1385
|
+
"Softness",
|
|
1386
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "range", "aria-label": "Gradient softness", min: 0, max: 1, step: 0.05, value: value.softness ?? 1, onChange: (e) => onChange({ ...value, softness: Number(e.target.value) }), className: "flex-1 accent-indigo-500" })
|
|
1387
|
+
] })
|
|
1388
|
+
] })
|
|
1389
|
+
] });
|
|
1390
|
+
};
|
|
1391
|
+
|
|
1392
|
+
// src/image-editor/PaintGradientEditor.tsx
|
|
1393
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1394
|
+
var PaintGradientEditor = (props) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PaintGradientEditorView, { ...props, kit: import_image_editor8.PAINT_GRADIENT_KIT });
|
|
1395
|
+
|
|
1396
|
+
// src/image-editor/BrushOptionsBar.tsx
|
|
1397
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1265
1398
|
var chip = (on) => `px-2 py-1 rounded text-[11px] ${on ? "bg-indigo-600 text-white" : "bg-slate-800 text-slate-300 hover:text-white"}`;
|
|
1266
1399
|
var BrushOptionsBar = ({ controller, className }) => {
|
|
1267
|
-
const [, setTick] = (0,
|
|
1268
|
-
(0,
|
|
1269
|
-
const [error, setError] = (0,
|
|
1400
|
+
const [, setTick] = (0, import_react8.useState)(0);
|
|
1401
|
+
(0, import_react8.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1402
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
1270
1403
|
const state = controller.getState();
|
|
1271
|
-
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource } = state.paint;
|
|
1404
|
+
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource, paint } = state.paint;
|
|
1272
1405
|
const tool = state.activeTool;
|
|
1273
1406
|
const attempt = (fn) => {
|
|
1274
1407
|
try {
|
|
@@ -1278,8 +1411,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1278
1411
|
setError(err instanceof Error ? err.message : String(err));
|
|
1279
1412
|
}
|
|
1280
1413
|
};
|
|
1281
|
-
return /* @__PURE__ */ (0,
|
|
1282
|
-
/* @__PURE__ */ (0,
|
|
1414
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "brush-options", children: [
|
|
1415
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Paint tools", children: import_image_editor9.PAINT_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1283
1416
|
"button",
|
|
1284
1417
|
{
|
|
1285
1418
|
type: "button",
|
|
@@ -1291,9 +1424,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1291
1424
|
},
|
|
1292
1425
|
t.id
|
|
1293
1426
|
)) }),
|
|
1294
|
-
/* @__PURE__ */ (0,
|
|
1295
|
-
/* @__PURE__ */ (0,
|
|
1296
|
-
/* @__PURE__ */ (0,
|
|
1427
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", role: "group", "aria-label": "Colours", children: [
|
|
1428
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1429
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1297
1430
|
"input",
|
|
1298
1431
|
{
|
|
1299
1432
|
type: "color",
|
|
@@ -1303,10 +1436,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1303
1436
|
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
1304
1437
|
}
|
|
1305
1438
|
),
|
|
1306
|
-
/* @__PURE__ */ (0,
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-slate-400", children: "FG" })
|
|
1307
1440
|
] }),
|
|
1308
|
-
/* @__PURE__ */ (0,
|
|
1309
|
-
/* @__PURE__ */ (0,
|
|
1441
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1442
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1310
1443
|
"input",
|
|
1311
1444
|
{
|
|
1312
1445
|
type: "color",
|
|
@@ -1316,12 +1449,24 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1316
1449
|
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
1317
1450
|
}
|
|
1318
1451
|
),
|
|
1319
|
-
/* @__PURE__ */ (0,
|
|
1452
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-slate-400", children: "BG" })
|
|
1320
1453
|
] }),
|
|
1321
|
-
/* @__PURE__ */ (0,
|
|
1322
|
-
/* @__PURE__ */ (0,
|
|
1454
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", title: "Swap colours (X)", className: chip(false), onClick: () => controller.swapPaintColors(), children: "Swap" }),
|
|
1455
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", title: "Default colours (D)", className: chip(false), onClick: () => controller.resetPaintColors(), children: "Default" }),
|
|
1456
|
+
state.activeTool === "brush" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1457
|
+
"button",
|
|
1458
|
+
{
|
|
1459
|
+
type: "button",
|
|
1460
|
+
"aria-pressed": paint.type === "gradient",
|
|
1461
|
+
title: "Gradient paint: the brush changes colour as the stroke goes",
|
|
1462
|
+
className: chip(paint.type === "gradient"),
|
|
1463
|
+
onClick: () => attempt(() => controller.setPaintOptions(paint.type === "gradient" ? { foreground } : { paint: import_image_editor10.DEFAULT_PAINT_GRADIENT })),
|
|
1464
|
+
children: "Gradient"
|
|
1465
|
+
}
|
|
1466
|
+
)
|
|
1323
1467
|
] }),
|
|
1324
|
-
|
|
1468
|
+
state.activeTool === "brush" && paint.type === "gradient" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PaintGradientEditor, { value: paint, colors: { paint: foreground, secondary: background }, onChange: (g) => attempt(() => controller.setPaintOptions({ paint: g })) }),
|
|
1469
|
+
import_image_editor9.BRUSH_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1325
1470
|
ControlSlider,
|
|
1326
1471
|
{
|
|
1327
1472
|
spec,
|
|
@@ -1330,21 +1475,21 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1330
1475
|
},
|
|
1331
1476
|
spec.id
|
|
1332
1477
|
)),
|
|
1333
|
-
state.activeTool === "mixer" && /* @__PURE__ */ (0,
|
|
1334
|
-
/* @__PURE__ */ (0,
|
|
1335
|
-
/* @__PURE__ */ (0,
|
|
1478
|
+
state.activeTool === "mixer" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-2 border-t border-slate-800 pt-2", role: "group", "aria-label": "Mixer Brush", "data-testid": "mixer-options", children: [
|
|
1479
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1480
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1336
1481
|
"span",
|
|
1337
1482
|
{
|
|
1338
1483
|
"aria-label": "Brush load",
|
|
1339
|
-
title: mixerLoad.reservoir ? `Loaded ${(0,
|
|
1484
|
+
title: mixerLoad.reservoir ? `Loaded ${(0, import_image_editor9.rgbUnitToHex)(mixerLoad.reservoir)}, ${Math.round(mixerLoad.amount * 100)}% left` : "Unloaded",
|
|
1340
1485
|
className: "h-6 w-6 rounded border border-slate-700",
|
|
1341
|
-
style: { background: mixerLoad.reservoir ? (0,
|
|
1486
|
+
style: { background: mixerLoad.reservoir ? (0, import_image_editor9.rgbUnitToHex)(mixerLoad.reservoir) : "transparent" }
|
|
1342
1487
|
}
|
|
1343
1488
|
),
|
|
1344
|
-
/* @__PURE__ */ (0,
|
|
1345
|
-
/* @__PURE__ */ (0,
|
|
1489
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", title: "Fill the reservoir with the foreground colour", className: chip(false), onClick: () => controller.loadMixerBrush(), children: "Load brush" }),
|
|
1490
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", title: "Empty the picked-up colour", className: chip(false), onClick: () => controller.cleanMixerBrush(), children: "Clean brush" })
|
|
1346
1491
|
] }),
|
|
1347
|
-
/* @__PURE__ */ (0,
|
|
1492
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Mixing", children: import_image_editor9.MIXER_MIXING_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1348
1493
|
"button",
|
|
1349
1494
|
{
|
|
1350
1495
|
type: "button",
|
|
@@ -1356,10 +1501,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1356
1501
|
},
|
|
1357
1502
|
m.id
|
|
1358
1503
|
)) }),
|
|
1359
|
-
|
|
1360
|
-
/* @__PURE__ */ (0,
|
|
1361
|
-
/* @__PURE__ */ (0,
|
|
1362
|
-
/* @__PURE__ */ (0,
|
|
1504
|
+
import_image_editor9.MIXER_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ControlSlider, { spec, value: mixer[spec.id], onChange: (v) => controller.setPaintOptions({ mixer: { [spec.id]: v } }) }, spec.id)),
|
|
1505
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-wrap gap-3 text-slate-300", children: [
|
|
1506
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
1507
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1363
1508
|
"input",
|
|
1364
1509
|
{
|
|
1365
1510
|
type: "checkbox",
|
|
@@ -1371,8 +1516,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1371
1516
|
),
|
|
1372
1517
|
"Load each stroke"
|
|
1373
1518
|
] }),
|
|
1374
|
-
/* @__PURE__ */ (0,
|
|
1375
|
-
/* @__PURE__ */ (0,
|
|
1519
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
1520
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1376
1521
|
"input",
|
|
1377
1522
|
{
|
|
1378
1523
|
type: "checkbox",
|
|
@@ -1386,29 +1531,29 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1386
1531
|
] })
|
|
1387
1532
|
] })
|
|
1388
1533
|
] }),
|
|
1389
|
-
(0,
|
|
1390
|
-
(tool === "clone" || tool === "heal") && /* @__PURE__ */ (0,
|
|
1391
|
-
/* @__PURE__ */ (0,
|
|
1392
|
-
cloneSource && /* @__PURE__ */ (0,
|
|
1534
|
+
(0, import_image_editor9.isRetouchPaintTool)(tool) && /* @__PURE__ */ (0, import_jsx_runtime9.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: [
|
|
1535
|
+
(tool === "clone" || tool === "heal") && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1536
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-slate-400", "data-testid": "clone-source", children: (0, import_image_editor9.cloneSourceLabel)(controller) }),
|
|
1537
|
+
cloneSource && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", title: "Forget the source point", className: chip(false), onClick: () => controller.setCloneSource(null), children: "Clear source" })
|
|
1393
1538
|
] }),
|
|
1394
|
-
|
|
1395
|
-
/* @__PURE__ */ (0,
|
|
1396
|
-
choice.options.map((o) => /* @__PURE__ */ (0,
|
|
1539
|
+
import_image_editor9.RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": choice.label, children: [
|
|
1540
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-slate-400", children: choice.label }),
|
|
1541
|
+
choice.options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1397
1542
|
"button",
|
|
1398
1543
|
{
|
|
1399
1544
|
type: "button",
|
|
1400
1545
|
"aria-pressed": retouch[choice.id] === o.id,
|
|
1401
1546
|
title: o.title,
|
|
1402
1547
|
className: chip(retouch[choice.id] === o.id),
|
|
1403
|
-
onClick: () => (0,
|
|
1548
|
+
onClick: () => (0, import_image_editor9.setRetouchChoice)(controller, choice.id, o.id),
|
|
1404
1549
|
children: o.label
|
|
1405
1550
|
},
|
|
1406
1551
|
o.id
|
|
1407
1552
|
))
|
|
1408
1553
|
] }, choice.id)),
|
|
1409
|
-
|
|
1410
|
-
/* @__PURE__ */ (0,
|
|
1411
|
-
/* @__PURE__ */ (0,
|
|
1554
|
+
import_image_editor9.RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ControlSlider, { spec, value: retouch[spec.id], onChange: (v) => controller.setPaintOptions({ retouch: { [spec.id]: v } }) }, spec.id)),
|
|
1555
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex flex-wrap gap-3 text-slate-300", children: import_image_editor9.RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
1556
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1412
1557
|
"input",
|
|
1413
1558
|
{
|
|
1414
1559
|
type: "checkbox",
|
|
@@ -1421,9 +1566,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1421
1566
|
t.label
|
|
1422
1567
|
] }, t.id)) })
|
|
1423
1568
|
] }),
|
|
1424
|
-
/* @__PURE__ */ (0,
|
|
1425
|
-
/* @__PURE__ */ (0,
|
|
1426
|
-
/* @__PURE__ */ (0,
|
|
1569
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-wrap gap-3 text-slate-300", role: "group", "aria-label": "Pressure", children: [
|
|
1570
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
1571
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1427
1572
|
"input",
|
|
1428
1573
|
{
|
|
1429
1574
|
type: "checkbox",
|
|
@@ -1435,8 +1580,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1435
1580
|
),
|
|
1436
1581
|
"Pressure size"
|
|
1437
1582
|
] }),
|
|
1438
|
-
/* @__PURE__ */ (0,
|
|
1439
|
-
/* @__PURE__ */ (0,
|
|
1583
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "flex items-center gap-1.5", children: [
|
|
1584
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1440
1585
|
"input",
|
|
1441
1586
|
{
|
|
1442
1587
|
type: "checkbox",
|
|
@@ -1449,28 +1594,28 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1449
1594
|
"Pressure opacity"
|
|
1450
1595
|
] })
|
|
1451
1596
|
] }),
|
|
1452
|
-
/* @__PURE__ */ (0,
|
|
1453
|
-
/* @__PURE__ */ (0,
|
|
1454
|
-
/* @__PURE__ */ (0,
|
|
1597
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex gap-1", children: [
|
|
1598
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.fillPixels()), children: "Fill" }),
|
|
1599
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.clearPixels()), children: "Clear" })
|
|
1455
1600
|
] }),
|
|
1456
|
-
error && /* @__PURE__ */ (0,
|
|
1601
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1457
1602
|
] });
|
|
1458
1603
|
};
|
|
1459
1604
|
|
|
1460
1605
|
// src/image-editor/ColorProfilePanel.tsx
|
|
1461
|
-
var
|
|
1462
|
-
var
|
|
1463
|
-
var
|
|
1606
|
+
var import_react9 = require("react");
|
|
1607
|
+
var import_image_editor11 = require("@pixerate/editor/image-editor");
|
|
1608
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1464
1609
|
var chip2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white";
|
|
1465
|
-
var
|
|
1610
|
+
var select2 = "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200";
|
|
1466
1611
|
var ColorProfilePanel = ({ controller, className }) => {
|
|
1467
|
-
const [, setTick] = (0,
|
|
1468
|
-
(0,
|
|
1469
|
-
const [target, setTarget] = (0,
|
|
1470
|
-
const [intent, setIntent] = (0,
|
|
1471
|
-
const [bpc, setBpc] = (0,
|
|
1472
|
-
const [error, setError] = (0,
|
|
1473
|
-
const view = (0,
|
|
1612
|
+
const [, setTick] = (0, import_react9.useState)(0);
|
|
1613
|
+
(0, import_react9.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1614
|
+
const [target, setTarget] = (0, import_react9.useState)("display-p3");
|
|
1615
|
+
const [intent, setIntent] = (0, import_react9.useState)("relative");
|
|
1616
|
+
const [bpc, setBpc] = (0, import_react9.useState)(true);
|
|
1617
|
+
const [error, setError] = (0, import_react9.useState)(null);
|
|
1618
|
+
const view = (0, import_image_editor11.colorPanelView)(controller);
|
|
1474
1619
|
const attempt = (fn) => {
|
|
1475
1620
|
try {
|
|
1476
1621
|
setError(null);
|
|
@@ -1491,61 +1636,61 @@ var ColorProfilePanel = ({ controller, className }) => {
|
|
|
1491
1636
|
})
|
|
1492
1637
|
);
|
|
1493
1638
|
};
|
|
1494
|
-
return /* @__PURE__ */ (0,
|
|
1495
|
-
/* @__PURE__ */ (0,
|
|
1496
|
-
/* @__PURE__ */ (0,
|
|
1497
|
-
/* @__PURE__ */ (0,
|
|
1639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "color-profile-panel", children: [
|
|
1640
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1641
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Profile" }),
|
|
1642
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "data-testid": "color-profile-name", children: view.profileName })
|
|
1498
1643
|
] }),
|
|
1499
|
-
/* @__PURE__ */ (0,
|
|
1500
|
-
/* @__PURE__ */ (0,
|
|
1501
|
-
/* @__PURE__ */ (0,
|
|
1502
|
-
view.cmykProfileName && /* @__PURE__ */ (0,
|
|
1644
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Colour mode", children: [
|
|
1645
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Mode" }),
|
|
1646
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("select", { "aria-label": "Colour mode", className: select2, value: view.mode, onChange: (e) => attempt(() => controller.setColorMode(e.target.value)), children: import_image_editor11.COLOR_MODE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
|
|
1647
|
+
view.cmykProfileName && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: view.cmykProfileName })
|
|
1503
1648
|
] }),
|
|
1504
|
-
/* @__PURE__ */ (0,
|
|
1505
|
-
/* @__PURE__ */ (0,
|
|
1506
|
-
/* @__PURE__ */ (0,
|
|
1507
|
-
/* @__PURE__ */ (0,
|
|
1508
|
-
/* @__PURE__ */ (0,
|
|
1649
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Assign or convert", children: [
|
|
1650
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("select", { "aria-label": "Target profile", className: select2, value: target, onChange: (e) => setTarget(e.target.value), children: import_image_editor11.WORKING_SPACE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
|
|
1651
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("select", { "aria-label": "Rendering intent", className: select2, value: intent, onChange: (e) => setIntent(e.target.value), children: import_image_editor11.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1653
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", "aria-label": "Black point compensation", checked: bpc, onChange: (e) => setBpc(e.target.checked), className: "accent-indigo-500" }),
|
|
1509
1654
|
"BPC"
|
|
1510
1655
|
] }),
|
|
1511
|
-
/* @__PURE__ */ (0,
|
|
1512
|
-
/* @__PURE__ */ (0,
|
|
1656
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Assign Profile: keep the numbers", onClick: () => attempt(() => controller.assignProfile(target)), children: "Assign" }),
|
|
1657
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: chip2, title: "Edit \u203A Convert to Profile: keep the look", onClick: () => attempt(() => controller.convertToProfile(target, { intent, bpc })), children: "Convert" })
|
|
1513
1658
|
] }),
|
|
1514
|
-
/* @__PURE__ */ (0,
|
|
1515
|
-
/* @__PURE__ */ (0,
|
|
1516
|
-
/* @__PURE__ */ (0,
|
|
1659
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
|
|
1660
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-slate-400", children: "Proof" }),
|
|
1661
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1517
1662
|
"select",
|
|
1518
1663
|
{
|
|
1519
1664
|
"aria-label": "Proof profile",
|
|
1520
|
-
className:
|
|
1665
|
+
className: select2,
|
|
1521
1666
|
value: view.proof?.id ?? "",
|
|
1522
1667
|
onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
|
|
1523
1668
|
children: [
|
|
1524
|
-
/* @__PURE__ */ (0,
|
|
1525
|
-
|
|
1669
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "Off" }),
|
|
1670
|
+
import_image_editor11.PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: o.id, children: o.label }, o.id))
|
|
1526
1671
|
]
|
|
1527
1672
|
}
|
|
1528
1673
|
),
|
|
1529
|
-
view.proof && /* @__PURE__ */ (0,
|
|
1530
|
-
/* @__PURE__ */ (0,
|
|
1531
|
-
/* @__PURE__ */ (0,
|
|
1532
|
-
/* @__PURE__ */ (0,
|
|
1674
|
+
view.proof && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1675
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("select", { "aria-label": "Proof intent", className: select2, value: view.proof.intent, onChange: (e) => proofWith({ intent: e.target.value }), children: import_image_editor11.INTENT_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: o.id, children: o.label }, o.id)) }),
|
|
1676
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1677
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", "aria-label": "Simulate paper colour", checked: view.proof.simulatePaper, onChange: (e) => proofWith({ simulatePaper: e.target.checked }), className: "accent-indigo-500" }),
|
|
1533
1678
|
"Paper"
|
|
1534
1679
|
] }),
|
|
1535
|
-
/* @__PURE__ */ (0,
|
|
1536
|
-
/* @__PURE__ */ (0,
|
|
1680
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1681
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", "aria-label": "Gamut warning", checked: view.proof.gamutWarning, onChange: (e) => proofWith({ gamutWarning: e.target.checked }), className: "accent-indigo-500" }),
|
|
1537
1682
|
"Gamut warning"
|
|
1538
1683
|
] })
|
|
1539
1684
|
] })
|
|
1540
1685
|
] }),
|
|
1541
|
-
error && /* @__PURE__ */ (0,
|
|
1686
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1542
1687
|
] });
|
|
1543
1688
|
};
|
|
1544
1689
|
|
|
1545
1690
|
// src/image-editor/SelectionOptionsBar.tsx
|
|
1546
|
-
var
|
|
1547
|
-
var
|
|
1548
|
-
var
|
|
1691
|
+
var import_react10 = require("react");
|
|
1692
|
+
var import_image_editor12 = require("@pixerate/editor/image-editor");
|
|
1693
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1549
1694
|
var MODIFY_OPS = [
|
|
1550
1695
|
{ op: "grow", label: "Grow" },
|
|
1551
1696
|
{ op: "shrink", label: "Shrink" },
|
|
@@ -1562,20 +1707,20 @@ var SelectionOptionsBar = ({
|
|
|
1562
1707
|
quickMask,
|
|
1563
1708
|
className = ""
|
|
1564
1709
|
}) => {
|
|
1565
|
-
const [radius, setRadius] = (0,
|
|
1710
|
+
const [radius, setRadius] = (0, import_react10.useState)(2);
|
|
1566
1711
|
const set = (patch) => onOptionsChange({ ...options, ...patch });
|
|
1567
1712
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
1568
1713
|
const qm = quickMask ?? Boolean(controller.getState().quickMask);
|
|
1569
|
-
return /* @__PURE__ */ (0,
|
|
1570
|
-
/* @__PURE__ */ (0,
|
|
1571
|
-
/* @__PURE__ */ (0,
|
|
1572
|
-
options.tool === "wand" && /* @__PURE__ */ (0,
|
|
1573
|
-
/* @__PURE__ */ (0,
|
|
1574
|
-
/* @__PURE__ */ (0,
|
|
1575
|
-
/* @__PURE__ */ (0,
|
|
1576
|
-
/* @__PURE__ */ (0,
|
|
1714
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
1715
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: import_image_editor12.SELECTION_TOOLS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime11.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)) }),
|
|
1716
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: import_image_editor12.SELECTION_MODES.map((m) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-pressed": options.mode === m, className: btn(options.mode === m), onClick: () => set({ mode: m }), children: import_image_editor12.SELECTION_MODE_LABELS[m] }, m)) }),
|
|
1717
|
+
options.tool === "wand" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
1718
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1719
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1720
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Tolerance" }),
|
|
1721
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-mono", children: options.tolerance })
|
|
1577
1722
|
] }),
|
|
1578
|
-
/* @__PURE__ */ (0,
|
|
1723
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1579
1724
|
"input",
|
|
1580
1725
|
{
|
|
1581
1726
|
type: "range",
|
|
@@ -1589,17 +1734,17 @@ var SelectionOptionsBar = ({
|
|
|
1589
1734
|
}
|
|
1590
1735
|
)
|
|
1591
1736
|
] }),
|
|
1592
|
-
/* @__PURE__ */ (0,
|
|
1593
|
-
/* @__PURE__ */ (0,
|
|
1737
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1738
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
|
|
1594
1739
|
"Contiguous"
|
|
1595
1740
|
] }),
|
|
1596
|
-
/* @__PURE__ */ (0,
|
|
1597
|
-
/* @__PURE__ */ (0,
|
|
1741
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1742
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
|
|
1598
1743
|
"Sample adjusted image"
|
|
1599
1744
|
] }),
|
|
1600
|
-
/* @__PURE__ */ (0,
|
|
1745
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1601
1746
|
"Sample",
|
|
1602
|
-
/* @__PURE__ */ (0,
|
|
1747
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1603
1748
|
"select",
|
|
1604
1749
|
{
|
|
1605
1750
|
"aria-label": "Sample from",
|
|
@@ -1607,27 +1752,27 @@ var SelectionOptionsBar = ({
|
|
|
1607
1752
|
onChange: (e) => set({ sample: e.target.value }),
|
|
1608
1753
|
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
1609
1754
|
children: [
|
|
1610
|
-
/* @__PURE__ */ (0,
|
|
1611
|
-
/* @__PURE__ */ (0,
|
|
1755
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "composite", children: "All layers" }),
|
|
1756
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "active-layer", children: "Active layer" })
|
|
1612
1757
|
]
|
|
1613
1758
|
}
|
|
1614
1759
|
)
|
|
1615
1760
|
] })
|
|
1616
1761
|
] }),
|
|
1617
|
-
/* @__PURE__ */ (0,
|
|
1618
|
-
/* @__PURE__ */ (0,
|
|
1762
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1763
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
|
|
1619
1764
|
"Anti-alias"
|
|
1620
1765
|
] }),
|
|
1621
|
-
/* @__PURE__ */ (0,
|
|
1622
|
-
/* @__PURE__ */ (0,
|
|
1623
|
-
/* @__PURE__ */ (0,
|
|
1624
|
-
/* @__PURE__ */ (0,
|
|
1625
|
-
/* @__PURE__ */ (0,
|
|
1766
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
1767
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.selectAll(), children: "Select All" }),
|
|
1768
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
|
|
1769
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: btn(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
|
|
1770
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-pressed": qm, className: btn(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
|
|
1626
1771
|
] }),
|
|
1627
|
-
/* @__PURE__ */ (0,
|
|
1628
|
-
/* @__PURE__ */ (0,
|
|
1772
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
1773
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "flex items-center gap-1 text-slate-400", children: [
|
|
1629
1774
|
"Radius",
|
|
1630
|
-
/* @__PURE__ */ (0,
|
|
1775
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1631
1776
|
"input",
|
|
1632
1777
|
{
|
|
1633
1778
|
type: "number",
|
|
@@ -1641,24 +1786,24 @@ var SelectionOptionsBar = ({
|
|
|
1641
1786
|
}
|
|
1642
1787
|
)
|
|
1643
1788
|
] }),
|
|
1644
|
-
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0,
|
|
1789
|
+
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: btn(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
|
|
1645
1790
|
] }),
|
|
1646
|
-
/* @__PURE__ */ (0,
|
|
1791
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { "data-testid": "selection-status", className: "text-slate-400", children: (0, import_image_editor12.describeSelection)(sel) })
|
|
1647
1792
|
] });
|
|
1648
1793
|
};
|
|
1649
1794
|
|
|
1650
1795
|
// src/image-editor/RefineEdgePanel.tsx
|
|
1651
|
-
var
|
|
1652
|
-
var
|
|
1653
|
-
var
|
|
1796
|
+
var import_react11 = require("react");
|
|
1797
|
+
var import_image_editor13 = require("@pixerate/editor/image-editor");
|
|
1798
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1654
1799
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
1655
|
-
var
|
|
1800
|
+
var button3 = "px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40";
|
|
1656
1801
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
1657
|
-
const [params, setParams] = (0,
|
|
1658
|
-
const [busy, setBusy] = (0,
|
|
1659
|
-
const [error, setError] = (0,
|
|
1660
|
-
const [layerId, setLayerId] = (0,
|
|
1661
|
-
const [newKind, setNewKind] = (0,
|
|
1802
|
+
const [params, setParams] = (0, import_react11.useState)(DEFAULT_PARAMS);
|
|
1803
|
+
const [busy, setBusy] = (0, import_react11.useState)(false);
|
|
1804
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
1805
|
+
const [layerId, setLayerId] = (0, import_react11.useState)("");
|
|
1806
|
+
const [newKind, setNewKind] = (0, import_react11.useState)("hueSaturation");
|
|
1662
1807
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
1663
1808
|
const list = layers ?? controller.getAdjustmentLayers();
|
|
1664
1809
|
const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
|
|
@@ -1673,17 +1818,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1673
1818
|
setBusy(false);
|
|
1674
1819
|
}
|
|
1675
1820
|
};
|
|
1676
|
-
return /* @__PURE__ */ (0,
|
|
1677
|
-
/* @__PURE__ */ (0,
|
|
1678
|
-
|
|
1679
|
-
/* @__PURE__ */ (0,
|
|
1680
|
-
/* @__PURE__ */ (0,
|
|
1681
|
-
/* @__PURE__ */ (0,
|
|
1821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
1822
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
|
|
1823
|
+
import_image_editor13.REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1824
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1825
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: c.label }),
|
|
1826
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "font-mono", children: [
|
|
1682
1827
|
params[c.id],
|
|
1683
1828
|
c.unit
|
|
1684
1829
|
] })
|
|
1685
1830
|
] }),
|
|
1686
|
-
/* @__PURE__ */ (0,
|
|
1831
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1687
1832
|
"input",
|
|
1688
1833
|
{
|
|
1689
1834
|
type: "range",
|
|
@@ -1697,67 +1842,67 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1697
1842
|
}
|
|
1698
1843
|
)
|
|
1699
1844
|
] }, c.id)),
|
|
1700
|
-
/* @__PURE__ */ (0,
|
|
1701
|
-
/* @__PURE__ */ (0,
|
|
1845
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1846
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
|
|
1702
1847
|
"Smart Radius"
|
|
1703
1848
|
] }),
|
|
1704
|
-
/* @__PURE__ */ (0,
|
|
1705
|
-
/* @__PURE__ */ (0,
|
|
1706
|
-
/* @__PURE__ */ (0,
|
|
1849
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex gap-1", children: [
|
|
1850
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: button3, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
|
|
1851
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: button3, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
|
|
1707
1852
|
] }),
|
|
1708
|
-
error && /* @__PURE__ */ (0,
|
|
1709
|
-
/* @__PURE__ */ (0,
|
|
1710
|
-
/* @__PURE__ */ (0,
|
|
1711
|
-
/* @__PURE__ */ (0,
|
|
1853
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", className: "text-rose-400", children: error }),
|
|
1854
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
|
|
1855
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex gap-1 items-center", children: [
|
|
1856
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1712
1857
|
"select",
|
|
1713
1858
|
{
|
|
1714
1859
|
"aria-label": "New masked layer kind",
|
|
1715
1860
|
value: newKind,
|
|
1716
1861
|
onChange: (e) => setNewKind(e.target.value),
|
|
1717
1862
|
className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
1718
|
-
children:
|
|
1863
|
+
children: import_image_editor13.ADJUSTMENT_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("option", { value: k.kind, children: k.label }, k.kind))
|
|
1719
1864
|
}
|
|
1720
1865
|
),
|
|
1721
|
-
/* @__PURE__ */ (0,
|
|
1866
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1722
1867
|
"button",
|
|
1723
1868
|
{
|
|
1724
1869
|
type: "button",
|
|
1725
|
-
className:
|
|
1870
|
+
className: button3,
|
|
1726
1871
|
disabled: !sel,
|
|
1727
|
-
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0,
|
|
1872
|
+
onClick: () => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: (0, import_image_editor13.layerMaskFromSelection)(sel) })),
|
|
1728
1873
|
children: "New Masked Layer"
|
|
1729
1874
|
}
|
|
1730
1875
|
)
|
|
1731
1876
|
] }),
|
|
1732
|
-
list.length > 0 && target && /* @__PURE__ */ (0,
|
|
1733
|
-
/* @__PURE__ */ (0,
|
|
1877
|
+
list.length > 0 && target && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
1878
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1734
1879
|
"select",
|
|
1735
1880
|
{
|
|
1736
1881
|
"aria-label": "Mask layer",
|
|
1737
1882
|
value: target.id,
|
|
1738
1883
|
onChange: (e) => setLayerId(e.target.value),
|
|
1739
1884
|
className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
1740
|
-
children: list.map((l) => /* @__PURE__ */ (0,
|
|
1741
|
-
l.name || (0,
|
|
1885
|
+
children: list.map((l) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("option", { value: l.id, children: [
|
|
1886
|
+
l.name || (0, import_image_editor13.adjustmentKindLabel)(l.kind),
|
|
1742
1887
|
l.mask ? " (masked)" : ""
|
|
1743
1888
|
] }, l.id))
|
|
1744
1889
|
}
|
|
1745
1890
|
),
|
|
1746
|
-
/* @__PURE__ */ (0,
|
|
1747
|
-
/* @__PURE__ */ (0,
|
|
1748
|
-
/* @__PURE__ */ (0,
|
|
1749
|
-
/* @__PURE__ */ (0,
|
|
1891
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
|
|
1892
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: button3, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
|
|
1893
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: button3, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
|
|
1894
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: button3, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
|
|
1750
1895
|
] }),
|
|
1751
|
-
target.mask && /* @__PURE__ */ (0,
|
|
1752
|
-
/* @__PURE__ */ (0,
|
|
1753
|
-
/* @__PURE__ */ (0,
|
|
1754
|
-
/* @__PURE__ */ (0,
|
|
1755
|
-
/* @__PURE__ */ (0,
|
|
1896
|
+
target.mask && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
1897
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1898
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1899
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "Density" }),
|
|
1900
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "font-mono", children: [
|
|
1756
1901
|
Math.round((target.mask.density ?? 1) * 100),
|
|
1757
1902
|
"%"
|
|
1758
1903
|
] })
|
|
1759
1904
|
] }),
|
|
1760
|
-
/* @__PURE__ */ (0,
|
|
1905
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1761
1906
|
"input",
|
|
1762
1907
|
{
|
|
1763
1908
|
type: "range",
|
|
@@ -1771,15 +1916,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1771
1916
|
}
|
|
1772
1917
|
)
|
|
1773
1918
|
] }),
|
|
1774
|
-
/* @__PURE__ */ (0,
|
|
1775
|
-
/* @__PURE__ */ (0,
|
|
1776
|
-
/* @__PURE__ */ (0,
|
|
1777
|
-
/* @__PURE__ */ (0,
|
|
1919
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
1920
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "flex justify-between text-slate-400", children: [
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "Mask Feather" }),
|
|
1922
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "font-mono", children: [
|
|
1778
1923
|
target.mask.feather ?? 0,
|
|
1779
1924
|
"px"
|
|
1780
1925
|
] })
|
|
1781
1926
|
] }),
|
|
1782
|
-
/* @__PURE__ */ (0,
|
|
1927
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1783
1928
|
"input",
|
|
1784
1929
|
{
|
|
1785
1930
|
type: "range",
|
|
@@ -1799,14 +1944,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1799
1944
|
};
|
|
1800
1945
|
|
|
1801
1946
|
// src/image-editor/FreeTransformOptionsBar.tsx
|
|
1802
|
-
var
|
|
1803
|
-
var
|
|
1804
|
-
var
|
|
1947
|
+
var import_react12 = require("react");
|
|
1948
|
+
var import_image_editor14 = require("@pixerate/editor/image-editor");
|
|
1949
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1805
1950
|
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"}`;
|
|
1806
1951
|
var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
|
|
1807
1952
|
var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
1808
|
-
const [, setTick] = (0,
|
|
1809
|
-
(0,
|
|
1953
|
+
const [, setTick] = (0, import_react12.useState)(0);
|
|
1954
|
+
(0, import_react12.useEffect)(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
|
|
1810
1955
|
const bar = tool.bar();
|
|
1811
1956
|
if (!tool.active || !bar) return null;
|
|
1812
1957
|
const warp = tool.warpBar();
|
|
@@ -1818,17 +1963,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1818
1963
|
const v = Number(raw);
|
|
1819
1964
|
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
1820
1965
|
};
|
|
1821
|
-
return /* @__PURE__ */ (0,
|
|
1822
|
-
/* @__PURE__ */ (0,
|
|
1823
|
-
/* @__PURE__ */ (0,
|
|
1824
|
-
tool.mode === "warp" && /* @__PURE__ */ (0,
|
|
1825
|
-
/* @__PURE__ */ (0,
|
|
1826
|
-
/* @__PURE__ */ (0,
|
|
1827
|
-
/* @__PURE__ */ (0,
|
|
1966
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.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: [
|
|
1967
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: import_image_editor14.FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ (0, import_jsx_runtime13.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)) }),
|
|
1968
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: import_image_editor14.TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime13.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)) }),
|
|
1969
|
+
tool.mode === "warp" && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
|
|
1970
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1971
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-slate-400", children: "Warp" }),
|
|
1972
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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_editor14.WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: o.id, children: o.label }, o.id)) })
|
|
1828
1973
|
] }),
|
|
1829
|
-
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0,
|
|
1830
|
-
/* @__PURE__ */ (0,
|
|
1831
|
-
/* @__PURE__ */ (0,
|
|
1974
|
+
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1975
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
|
|
1976
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1832
1977
|
"input",
|
|
1833
1978
|
{
|
|
1834
1979
|
type: "number",
|
|
@@ -1849,9 +1994,9 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1849
1994
|
},
|
|
1850
1995
|
`${k}:${warp[k]}`
|
|
1851
1996
|
),
|
|
1852
|
-
/* @__PURE__ */ (0,
|
|
1997
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-slate-500", children: "%" })
|
|
1853
1998
|
] }, k)),
|
|
1854
|
-
/* @__PURE__ */ (0,
|
|
1999
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1855
2000
|
"button",
|
|
1856
2001
|
{
|
|
1857
2002
|
type: "button",
|
|
@@ -1863,26 +2008,26 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1863
2008
|
children: "Vertical"
|
|
1864
2009
|
}
|
|
1865
2010
|
),
|
|
1866
|
-
/* @__PURE__ */ (0,
|
|
1867
|
-
/* @__PURE__ */ (0,
|
|
1868
|
-
/* @__PURE__ */ (0,
|
|
2011
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2012
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-slate-400", children: "Grid" }),
|
|
2013
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1869
2014
|
"select",
|
|
1870
2015
|
{
|
|
1871
2016
|
"aria-label": "Warp grid",
|
|
1872
|
-
value:
|
|
2017
|
+
value: import_image_editor14.WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? "1x1",
|
|
1873
2018
|
onChange: (e) => {
|
|
1874
|
-
const g =
|
|
2019
|
+
const g = import_image_editor14.WARP_GRID_OPTIONS.find((o) => o.id === e.target.value);
|
|
1875
2020
|
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
1876
2021
|
},
|
|
1877
2022
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1878
|
-
children:
|
|
2023
|
+
children: import_image_editor14.WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: g.id, children: g.label }, g.id))
|
|
1879
2024
|
}
|
|
1880
2025
|
)
|
|
1881
2026
|
] })
|
|
1882
2027
|
] }),
|
|
1883
|
-
tool.mode !== "warp" &&
|
|
1884
|
-
/* @__PURE__ */ (0,
|
|
1885
|
-
/* @__PURE__ */ (0,
|
|
2028
|
+
tool.mode !== "warp" && import_image_editor14.FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", title: f.title, children: [
|
|
2029
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-slate-400", children: f.label }),
|
|
2030
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1886
2031
|
"input",
|
|
1887
2032
|
{
|
|
1888
2033
|
type: "number",
|
|
@@ -1902,8 +2047,8 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1902
2047
|
},
|
|
1903
2048
|
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
1904
2049
|
),
|
|
1905
|
-
/* @__PURE__ */ (0,
|
|
1906
|
-
f.id === "scaleX" && /* @__PURE__ */ (0,
|
|
2050
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-slate-500", children: f.unit }),
|
|
2051
|
+
f.id === "scaleX" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1907
2052
|
"button",
|
|
1908
2053
|
{
|
|
1909
2054
|
type: "button",
|
|
@@ -1918,34 +2063,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1918
2063
|
}
|
|
1919
2064
|
)
|
|
1920
2065
|
] }, f.id)),
|
|
1921
|
-
/* @__PURE__ */ (0,
|
|
1922
|
-
/* @__PURE__ */ (0,
|
|
1923
|
-
/* @__PURE__ */ (0,
|
|
2066
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2067
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-slate-400", children: "Interpolation" }),
|
|
2068
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1924
2069
|
"select",
|
|
1925
2070
|
{
|
|
1926
2071
|
"aria-label": "Interpolation",
|
|
1927
2072
|
value: tool.interpolation,
|
|
1928
2073
|
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
1929
2074
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1930
|
-
children:
|
|
2075
|
+
children: import_image_editor14.INTERPOLATIONS.map((i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
1931
2076
|
}
|
|
1932
2077
|
)
|
|
1933
2078
|
] }),
|
|
1934
|
-
/* @__PURE__ */ (0,
|
|
1935
|
-
/* @__PURE__ */ (0,
|
|
1936
|
-
tool.error && /* @__PURE__ */ (0,
|
|
2079
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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" }),
|
|
2080
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
|
|
2081
|
+
tool.error && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { role: "alert", className: "text-rose-400", children: tool.error })
|
|
1937
2082
|
] });
|
|
1938
2083
|
};
|
|
1939
2084
|
|
|
1940
2085
|
// src/image-editor/ShapeOptionsBar.tsx
|
|
1941
|
-
var
|
|
1942
|
-
var
|
|
1943
|
-
var
|
|
2086
|
+
var import_react13 = require("react");
|
|
2087
|
+
var import_image_editor15 = require("@pixerate/editor/image-editor");
|
|
2088
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1944
2089
|
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"}`;
|
|
1945
2090
|
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
1946
|
-
const [, setTick] = (0,
|
|
1947
|
-
(0,
|
|
1948
|
-
const [error, setError] = (0,
|
|
2091
|
+
const [, setTick] = (0, import_react13.useState)(0);
|
|
2092
|
+
(0, import_react13.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
2093
|
+
const [error, setError] = (0, import_react13.useState)(null);
|
|
1949
2094
|
const active = controller.getActiveLayer();
|
|
1950
2095
|
const shapeId = active?.type === "shape" ? active.id : null;
|
|
1951
2096
|
const set = (change) => {
|
|
@@ -1953,19 +2098,19 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1953
2098
|
if (!shapeId) return;
|
|
1954
2099
|
try {
|
|
1955
2100
|
setError(null);
|
|
1956
|
-
(0,
|
|
2101
|
+
(0, import_image_editor15.applyShapeOptions)(controller, shapeId, change);
|
|
1957
2102
|
} catch (e) {
|
|
1958
2103
|
setError(e instanceof Error ? e.message : String(e));
|
|
1959
2104
|
}
|
|
1960
2105
|
};
|
|
1961
2106
|
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
1962
|
-
return /* @__PURE__ */ (0,
|
|
1963
|
-
/* @__PURE__ */ (0,
|
|
1964
|
-
/* @__PURE__ */ (0,
|
|
1965
|
-
/* @__PURE__ */ (0,
|
|
1966
|
-
/* @__PURE__ */ (0,
|
|
2107
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
|
|
2108
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: import_image_editor15.LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", "aria-pressed": options.kind === k, className: chip4(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: import_image_editor15.SHAPE_KIND_LABELS[k] }, k)) }),
|
|
2109
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
2110
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
|
|
1967
2112
|
"Fill",
|
|
1968
|
-
/* @__PURE__ */ (0,
|
|
2113
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1969
2114
|
"input",
|
|
1970
2115
|
{
|
|
1971
2116
|
type: "color",
|
|
@@ -1977,10 +2122,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1977
2122
|
}
|
|
1978
2123
|
)
|
|
1979
2124
|
] }),
|
|
1980
|
-
/* @__PURE__ */ (0,
|
|
1981
|
-
/* @__PURE__ */ (0,
|
|
2125
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2126
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
|
|
1982
2127
|
"Stroke",
|
|
1983
|
-
/* @__PURE__ */ (0,
|
|
2128
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1984
2129
|
"input",
|
|
1985
2130
|
{
|
|
1986
2131
|
type: "color",
|
|
@@ -1992,9 +2137,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1992
2137
|
}
|
|
1993
2138
|
)
|
|
1994
2139
|
] }),
|
|
1995
|
-
/* @__PURE__ */ (0,
|
|
2140
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
1996
2141
|
"Width",
|
|
1997
|
-
/* @__PURE__ */ (0,
|
|
2142
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1998
2143
|
"input",
|
|
1999
2144
|
{
|
|
2000
2145
|
type: "number",
|
|
@@ -2008,23 +2153,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2008
2153
|
)
|
|
2009
2154
|
] })
|
|
2010
2155
|
] }),
|
|
2011
|
-
/* @__PURE__ */ (0,
|
|
2012
|
-
options.kind === "rect" && /* @__PURE__ */ (0,
|
|
2156
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
2157
|
+
options.kind === "rect" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2013
2158
|
"Radius",
|
|
2014
|
-
/* @__PURE__ */ (0,
|
|
2159
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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" })
|
|
2015
2160
|
] }),
|
|
2016
|
-
options.kind === "polygon" && /* @__PURE__ */ (0,
|
|
2161
|
+
options.kind === "polygon" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2017
2162
|
"Sides",
|
|
2018
|
-
/* @__PURE__ */ (0,
|
|
2163
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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" })
|
|
2019
2164
|
] }),
|
|
2020
|
-
options.kind === "star" && /* @__PURE__ */ (0,
|
|
2021
|
-
/* @__PURE__ */ (0,
|
|
2165
|
+
options.kind === "star" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2166
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2022
2167
|
"Points",
|
|
2023
|
-
/* @__PURE__ */ (0,
|
|
2168
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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" })
|
|
2024
2169
|
] }),
|
|
2025
|
-
/* @__PURE__ */ (0,
|
|
2170
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2026
2171
|
"Inner",
|
|
2027
|
-
/* @__PURE__ */ (0,
|
|
2172
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2028
2173
|
"input",
|
|
2029
2174
|
{
|
|
2030
2175
|
type: "range",
|
|
@@ -2039,33 +2184,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2039
2184
|
)
|
|
2040
2185
|
] })
|
|
2041
2186
|
] }),
|
|
2042
|
-
options.kind === "line" && /* @__PURE__ */ (0,
|
|
2043
|
-
/* @__PURE__ */ (0,
|
|
2187
|
+
options.kind === "line" && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2188
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2044
2189
|
"Weight",
|
|
2045
|
-
/* @__PURE__ */ (0,
|
|
2190
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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" })
|
|
2046
2191
|
] }),
|
|
2047
|
-
/* @__PURE__ */ (0,
|
|
2048
|
-
/* @__PURE__ */ (0,
|
|
2192
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2193
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
|
|
2049
2194
|
"Arrowhead"
|
|
2050
2195
|
] })
|
|
2051
2196
|
] })
|
|
2052
2197
|
] }),
|
|
2053
|
-
/* @__PURE__ */ (0,
|
|
2054
|
-
error && /* @__PURE__ */ (0,
|
|
2198
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.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." }),
|
|
2199
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
2055
2200
|
] });
|
|
2056
2201
|
};
|
|
2057
2202
|
|
|
2058
2203
|
// src/image-editor/TypeOptionsBar.tsx
|
|
2059
|
-
var
|
|
2060
|
-
var
|
|
2061
|
-
var
|
|
2204
|
+
var import_react14 = require("react");
|
|
2205
|
+
var import_image_editor16 = require("@pixerate/editor/image-editor");
|
|
2206
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2062
2207
|
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"}`;
|
|
2063
2208
|
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
2064
2209
|
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
2065
|
-
const [, setTick] = (0,
|
|
2066
|
-
(0,
|
|
2067
|
-
(0,
|
|
2068
|
-
const [error, setError] = (0,
|
|
2210
|
+
const [, setTick] = (0, import_react14.useState)(0);
|
|
2211
|
+
(0, import_react14.useEffect)(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
2212
|
+
(0, import_react14.useEffect)(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
|
|
2213
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
2069
2214
|
const active = controller.getActiveLayer();
|
|
2070
2215
|
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
2071
2216
|
const here = session?.alive ? session.styleHere() : {};
|
|
@@ -2097,11 +2242,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2097
2242
|
setError(e instanceof Error ? e.message : String(e));
|
|
2098
2243
|
}
|
|
2099
2244
|
};
|
|
2100
|
-
return /* @__PURE__ */ (0,
|
|
2101
|
-
/* @__PURE__ */ (0,
|
|
2102
|
-
/* @__PURE__ */ (0,
|
|
2245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
|
|
2246
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2247
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2103
2248
|
"Font",
|
|
2104
|
-
/* @__PURE__ */ (0,
|
|
2249
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2105
2250
|
"input",
|
|
2106
2251
|
{
|
|
2107
2252
|
list: "pixerate-type-fonts",
|
|
@@ -2111,11 +2256,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2111
2256
|
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
2112
2257
|
}
|
|
2113
2258
|
),
|
|
2114
|
-
/* @__PURE__ */ (0,
|
|
2259
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("option", { value: f }, f)) })
|
|
2115
2260
|
] }),
|
|
2116
|
-
/* @__PURE__ */ (0,
|
|
2261
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "flex items-center gap-1", children: [
|
|
2117
2262
|
"Size",
|
|
2118
|
-
/* @__PURE__ */ (0,
|
|
2263
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2119
2264
|
"input",
|
|
2120
2265
|
{
|
|
2121
2266
|
type: "number",
|
|
@@ -2128,24 +2273,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2128
2273
|
}
|
|
2129
2274
|
)
|
|
2130
2275
|
] }),
|
|
2131
|
-
/* @__PURE__ */ (0,
|
|
2132
|
-
/* @__PURE__ */ (0,
|
|
2133
|
-
/* @__PURE__ */ (0,
|
|
2276
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.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" }),
|
|
2277
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", "aria-pressed": shown.italic, className: `${chip5(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
|
|
2278
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.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" })
|
|
2134
2279
|
] }),
|
|
2135
|
-
/* @__PURE__ */ (0,
|
|
2136
|
-
/* @__PURE__ */ (0,
|
|
2137
|
-
missing.length > 0 && /* @__PURE__ */ (0,
|
|
2280
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: import_image_editor16.TEXT_ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", "aria-pressed": options.align === a, className: chip5(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
|
|
2281
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.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." }),
|
|
2282
|
+
missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
|
|
2138
2283
|
"Missing ",
|
|
2139
2284
|
missing.length === 1 ? "font" : "fonts",
|
|
2140
2285
|
": ",
|
|
2141
2286
|
missing.join(", ")
|
|
2142
2287
|
] }),
|
|
2143
|
-
error && /* @__PURE__ */ (0,
|
|
2288
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { role: "alert", className: "text-rose-400", children: error })
|
|
2144
2289
|
] });
|
|
2145
2290
|
};
|
|
2146
2291
|
|
|
2147
2292
|
// src/image-editor/ImageEditor.tsx
|
|
2148
|
-
var
|
|
2293
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2149
2294
|
var ImageEditor = ({
|
|
2150
2295
|
editor: externalEditor,
|
|
2151
2296
|
src,
|
|
@@ -2160,65 +2305,65 @@ var ImageEditor = ({
|
|
|
2160
2305
|
const internalEditor = useImageEditor({ image: src });
|
|
2161
2306
|
const editor = externalEditor || internalEditor;
|
|
2162
2307
|
const { state, controller } = editor;
|
|
2163
|
-
const legacyProcess = (0,
|
|
2164
|
-
const canvasRef = (0,
|
|
2165
|
-
const containerRef = (0,
|
|
2166
|
-
const [activeTab, setActiveTab] = (0,
|
|
2167
|
-
const [activeCropRatio, setActiveCropRatio] = (0,
|
|
2168
|
-
const [selectionOptions, setSelectionOptions] = (0,
|
|
2169
|
-
const selectionOptionsRef = (0,
|
|
2308
|
+
const legacyProcess = (0, import_image_editor17.normalizeProcessVersion)(state.adjustments.process) < import_image_editor17.LATEST_PROCESS_VERSION;
|
|
2309
|
+
const canvasRef = (0, import_react15.useRef)(null);
|
|
2310
|
+
const containerRef = (0, import_react15.useRef)(null);
|
|
2311
|
+
const [activeTab, setActiveTab] = (0, import_react15.useState)("crop");
|
|
2312
|
+
const [activeCropRatio, setActiveCropRatio] = (0, import_react15.useState)(null);
|
|
2313
|
+
const [selectionOptions, setSelectionOptions] = (0, import_react15.useState)(import_image_editor17.DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
2314
|
+
const selectionOptionsRef = (0, import_react15.useRef)(selectionOptions);
|
|
2170
2315
|
selectionOptionsRef.current = selectionOptions;
|
|
2171
|
-
const selectionGestureRef = (0,
|
|
2316
|
+
const selectionGestureRef = (0, import_react15.useRef)(null);
|
|
2172
2317
|
if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {
|
|
2173
|
-
selectionGestureRef.current = new
|
|
2318
|
+
selectionGestureRef.current = new import_image_editor17.SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
2174
2319
|
}
|
|
2175
|
-
const selectionDraftRef = (0,
|
|
2176
|
-
const [selectionError, setSelectionError] = (0,
|
|
2177
|
-
const paintGestureRef = (0,
|
|
2178
|
-
const paintControllerRef = (0,
|
|
2320
|
+
const selectionDraftRef = (0, import_react15.useRef)(null);
|
|
2321
|
+
const [selectionError, setSelectionError] = (0, import_react15.useState)(null);
|
|
2322
|
+
const paintGestureRef = (0, import_react15.useRef)(null);
|
|
2323
|
+
const paintControllerRef = (0, import_react15.useRef)(controller);
|
|
2179
2324
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
2180
|
-
paintGestureRef.current = new
|
|
2325
|
+
paintGestureRef.current = new import_image_editor17.PaintGesture(controller);
|
|
2181
2326
|
paintControllerRef.current = controller;
|
|
2182
2327
|
}
|
|
2183
|
-
const brushCursorRef = (0,
|
|
2184
|
-
const [paintError, setPaintError] = (0,
|
|
2185
|
-
const transformToolRef = (0,
|
|
2186
|
-
const transformControllerRef = (0,
|
|
2328
|
+
const brushCursorRef = (0, import_react15.useRef)(null);
|
|
2329
|
+
const [paintError, setPaintError] = (0, import_react15.useState)(null);
|
|
2330
|
+
const transformToolRef = (0, import_react15.useRef)(null);
|
|
2331
|
+
const transformControllerRef = (0, import_react15.useRef)(controller);
|
|
2187
2332
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
2188
2333
|
transformToolRef.current?.cancel();
|
|
2189
|
-
transformToolRef.current = new
|
|
2334
|
+
transformToolRef.current = new import_image_editor17.FreeTransformTool(controller, {
|
|
2190
2335
|
schedule: (run) => typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame(run) : run()
|
|
2191
2336
|
});
|
|
2192
2337
|
transformControllerRef.current = controller;
|
|
2193
2338
|
}
|
|
2194
2339
|
const transformTool = transformToolRef.current;
|
|
2195
|
-
const [, setTransformTick] = (0,
|
|
2196
|
-
const [transformCursor, setTransformCursor] = (0,
|
|
2197
|
-
const [shapeOptions, setShapeOptions] = (0,
|
|
2198
|
-
const shapeOptionsRef = (0,
|
|
2340
|
+
const [, setTransformTick] = (0, import_react15.useState)(0);
|
|
2341
|
+
const [transformCursor, setTransformCursor] = (0, import_react15.useState)("default");
|
|
2342
|
+
const [shapeOptions, setShapeOptions] = (0, import_react15.useState)(import_image_editor17.DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
2343
|
+
const shapeOptionsRef = (0, import_react15.useRef)(shapeOptions);
|
|
2199
2344
|
shapeOptionsRef.current = shapeOptions;
|
|
2200
|
-
const [typeOptions, setTypeOptions] = (0,
|
|
2201
|
-
const typeOptionsRef = (0,
|
|
2345
|
+
const [typeOptions, setTypeOptions] = (0, import_react15.useState)(import_image_editor17.DEFAULT_TYPE_TOOL_OPTIONS);
|
|
2346
|
+
const typeOptionsRef = (0, import_react15.useRef)(typeOptions);
|
|
2202
2347
|
typeOptionsRef.current = typeOptions;
|
|
2203
|
-
const shapeGestureRef = (0,
|
|
2204
|
-
const typeToolRef = (0,
|
|
2205
|
-
const shapeTypeControllerRef = (0,
|
|
2348
|
+
const shapeGestureRef = (0, import_react15.useRef)(null);
|
|
2349
|
+
const typeToolRef = (0, import_react15.useRef)(null);
|
|
2350
|
+
const shapeTypeControllerRef = (0, import_react15.useRef)(controller);
|
|
2206
2351
|
if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {
|
|
2207
2352
|
typeToolRef.current?.finish();
|
|
2208
|
-
shapeGestureRef.current = new
|
|
2209
|
-
typeToolRef.current = new
|
|
2353
|
+
shapeGestureRef.current = new import_image_editor17.ShapeDrawGesture(controller, () => shapeOptionsRef.current);
|
|
2354
|
+
typeToolRef.current = new import_image_editor17.TypeToolGesture(controller, () => typeOptionsRef.current);
|
|
2210
2355
|
shapeTypeControllerRef.current = controller;
|
|
2211
2356
|
}
|
|
2212
|
-
const typeInputRef = (0,
|
|
2213
|
-
const [typeSession, setTypeSession] = (0,
|
|
2214
|
-
const [shapeTypeError, setShapeTypeError] = (0,
|
|
2215
|
-
const [inpaintPrompt, setInpaintPrompt] = (0,
|
|
2216
|
-
const [inpaintMaskMode, setInpaintMaskMode] = (0,
|
|
2217
|
-
const [isRemovingBg, setIsRemovingBg] = (0,
|
|
2218
|
-
const [isInpainting, setIsInpainting] = (0,
|
|
2219
|
-
const [aiError, setAiError] = (0,
|
|
2220
|
-
const [aiSuccess, setAiSuccess] = (0,
|
|
2221
|
-
const [aiTarget, setAiTarget] = (0,
|
|
2357
|
+
const typeInputRef = (0, import_react15.useRef)(null);
|
|
2358
|
+
const [typeSession, setTypeSession] = (0, import_react15.useState)(typeToolRef.current.session);
|
|
2359
|
+
const [shapeTypeError, setShapeTypeError] = (0, import_react15.useState)(null);
|
|
2360
|
+
const [inpaintPrompt, setInpaintPrompt] = (0, import_react15.useState)("");
|
|
2361
|
+
const [inpaintMaskMode, setInpaintMaskMode] = (0, import_react15.useState)("annotations");
|
|
2362
|
+
const [isRemovingBg, setIsRemovingBg] = (0, import_react15.useState)(false);
|
|
2363
|
+
const [isInpainting, setIsInpainting] = (0, import_react15.useState)(false);
|
|
2364
|
+
const [aiError, setAiError] = (0, import_react15.useState)(null);
|
|
2365
|
+
const [aiSuccess, setAiSuccess] = (0, import_react15.useState)(null);
|
|
2366
|
+
const [aiTarget, setAiTarget] = (0, import_react15.useState)("auto");
|
|
2222
2367
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
2223
2368
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
2224
2369
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -2281,18 +2426,18 @@ var ImageEditor = ({
|
|
|
2281
2426
|
setIsInpainting(false);
|
|
2282
2427
|
}
|
|
2283
2428
|
};
|
|
2284
|
-
const [activeColor, setActiveColor] = (0,
|
|
2285
|
-
const [strokeWidth, setStrokeWidth] = (0,
|
|
2286
|
-
const [fontSize, setFontSize] = (0,
|
|
2287
|
-
const [textInput, setTextInput] = (0,
|
|
2288
|
-
const draftAnnotationRef = (0,
|
|
2289
|
-
const draftCropRef = (0,
|
|
2290
|
-
const cropDragInfoRef = (0,
|
|
2291
|
-
const annotationDragInfoRef = (0,
|
|
2292
|
-
const isDrawingRef = (0,
|
|
2293
|
-
const currentPathRef = (0,
|
|
2294
|
-
const dragStartPointRef = (0,
|
|
2295
|
-
const renderCanvas = (0,
|
|
2429
|
+
const [activeColor, setActiveColor] = (0, import_react15.useState)("#ef4444");
|
|
2430
|
+
const [strokeWidth, setStrokeWidth] = (0, import_react15.useState)(3);
|
|
2431
|
+
const [fontSize, setFontSize] = (0, import_react15.useState)(24);
|
|
2432
|
+
const [textInput, setTextInput] = (0, import_react15.useState)("");
|
|
2433
|
+
const draftAnnotationRef = (0, import_react15.useRef)(null);
|
|
2434
|
+
const draftCropRef = (0, import_react15.useRef)(null);
|
|
2435
|
+
const cropDragInfoRef = (0, import_react15.useRef)(null);
|
|
2436
|
+
const annotationDragInfoRef = (0, import_react15.useRef)(null);
|
|
2437
|
+
const isDrawingRef = (0, import_react15.useRef)(false);
|
|
2438
|
+
const currentPathRef = (0, import_react15.useRef)([]);
|
|
2439
|
+
const dragStartPointRef = (0, import_react15.useRef)(null);
|
|
2440
|
+
const renderCanvas = (0, import_react15.useCallback)(
|
|
2296
2441
|
async (draftAnnotation, draftCrop) => {
|
|
2297
2442
|
const canvas = canvasRef.current;
|
|
2298
2443
|
const container = containerRef.current;
|
|
@@ -2315,8 +2460,8 @@ var ImageEditor = ({
|
|
|
2315
2460
|
},
|
|
2316
2461
|
[controller, activeTab, transformTool]
|
|
2317
2462
|
);
|
|
2318
|
-
(0,
|
|
2319
|
-
(0,
|
|
2463
|
+
(0, import_react15.useEffect)(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
2464
|
+
(0, import_react15.useEffect)(() => {
|
|
2320
2465
|
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
2321
2466
|
if (typeToolRef.current?.session) {
|
|
2322
2467
|
typeToolRef.current.finish();
|
|
@@ -2351,7 +2496,7 @@ var ImageEditor = ({
|
|
|
2351
2496
|
el.value = "";
|
|
2352
2497
|
}
|
|
2353
2498
|
};
|
|
2354
|
-
(0,
|
|
2499
|
+
(0, import_react15.useEffect)(() => transformTool.subscribe(() => {
|
|
2355
2500
|
setTransformTick((n) => n + 1);
|
|
2356
2501
|
void renderCanvas();
|
|
2357
2502
|
}), [transformTool, renderCanvas]);
|
|
@@ -2362,8 +2507,8 @@ var ImageEditor = ({
|
|
|
2362
2507
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
2363
2508
|
const s = controller.getState();
|
|
2364
2509
|
const cropping = activeTab === "crop";
|
|
2365
|
-
const projection = (0,
|
|
2366
|
-
const pt = (0,
|
|
2510
|
+
const projection = (0, import_image_editor17.getViewportProjection)(s, canvas.width, canvas.height, cropping);
|
|
2511
|
+
const pt = (0, import_image_editor17.canvasToImagePoint)({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);
|
|
2367
2512
|
transformTool.setView(projection.scale);
|
|
2368
2513
|
return { pt, tolerance: 6 / (projection.scale || 1) };
|
|
2369
2514
|
};
|
|
@@ -2394,7 +2539,7 @@ var ImageEditor = ({
|
|
|
2394
2539
|
transformTool.up();
|
|
2395
2540
|
return true;
|
|
2396
2541
|
};
|
|
2397
|
-
(0,
|
|
2542
|
+
(0, import_react15.useEffect)(() => {
|
|
2398
2543
|
if (typeof window === "undefined") return;
|
|
2399
2544
|
const onKey = (e) => {
|
|
2400
2545
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -2402,7 +2547,7 @@ var ImageEditor = ({
|
|
|
2402
2547
|
window.addEventListener("keydown", onKey);
|
|
2403
2548
|
return () => window.removeEventListener("keydown", onKey);
|
|
2404
2549
|
}, [transformTool]);
|
|
2405
|
-
(0,
|
|
2550
|
+
(0, import_react15.useEffect)(() => {
|
|
2406
2551
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
2407
2552
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
2408
2553
|
const animId = raf(() => {
|
|
@@ -2410,12 +2555,12 @@ var ImageEditor = ({
|
|
|
2410
2555
|
});
|
|
2411
2556
|
return () => caf(animId);
|
|
2412
2557
|
}, [renderCanvas, state]);
|
|
2413
|
-
(0,
|
|
2558
|
+
(0, import_react15.useEffect)(() => {
|
|
2414
2559
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
2415
2560
|
editor.setTool("crop");
|
|
2416
2561
|
}
|
|
2417
2562
|
}, [activeTab, editor]);
|
|
2418
|
-
(0,
|
|
2563
|
+
(0, import_react15.useEffect)(() => {
|
|
2419
2564
|
const container = containerRef.current;
|
|
2420
2565
|
if (!container) return;
|
|
2421
2566
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -2451,8 +2596,8 @@ var ImageEditor = ({
|
|
|
2451
2596
|
const sy = rect.height > 0 ? canvas.height / rect.height : 1;
|
|
2452
2597
|
const s = controller.getState();
|
|
2453
2598
|
return list.map((ev) => ({
|
|
2454
|
-
...(0,
|
|
2455
|
-
pressure: (0,
|
|
2599
|
+
...(0, import_image_editor17.canvasToImagePoint)({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),
|
|
2600
|
+
pressure: (0, import_image_editor17.pointerPressure)(ev)
|
|
2456
2601
|
}));
|
|
2457
2602
|
};
|
|
2458
2603
|
const handlePaintPointerDown = (e) => {
|
|
@@ -2483,10 +2628,10 @@ var ImageEditor = ({
|
|
|
2483
2628
|
if (g.error) setPaintError(g.error);
|
|
2484
2629
|
}
|
|
2485
2630
|
};
|
|
2486
|
-
(0,
|
|
2631
|
+
(0, import_react15.useEffect)(() => {
|
|
2487
2632
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
2488
2633
|
const onKey = (e) => {
|
|
2489
|
-
if ((0,
|
|
2634
|
+
if ((0, import_image_editor17.handlePaintShortcut)(controller, e)) e.preventDefault();
|
|
2490
2635
|
};
|
|
2491
2636
|
window.addEventListener("keydown", onKey);
|
|
2492
2637
|
return () => window.removeEventListener("keydown", onKey);
|
|
@@ -2497,7 +2642,7 @@ var ImageEditor = ({
|
|
|
2497
2642
|
const canvasPt = getCanvasEventPoint(e);
|
|
2498
2643
|
if (activeTab === "select") {
|
|
2499
2644
|
const gesture = selectionGestureRef.current;
|
|
2500
|
-
const imgPt = (0,
|
|
2645
|
+
const imgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2501
2646
|
void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));
|
|
2502
2647
|
return;
|
|
2503
2648
|
}
|
|
@@ -2508,8 +2653,8 @@ var ImageEditor = ({
|
|
|
2508
2653
|
width: state.imageDimensions.width,
|
|
2509
2654
|
height: state.imageDimensions.height
|
|
2510
2655
|
};
|
|
2511
|
-
const handle = (0,
|
|
2512
|
-
const startImgPt = (0,
|
|
2656
|
+
const handle = (0, import_image_editor17.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2657
|
+
const startImgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
2513
2658
|
if (handle) {
|
|
2514
2659
|
cropDragInfoRef.current = {
|
|
2515
2660
|
handle,
|
|
@@ -2528,7 +2673,7 @@ var ImageEditor = ({
|
|
|
2528
2673
|
return;
|
|
2529
2674
|
}
|
|
2530
2675
|
if (activeTab === "annotate" && (state.activeTool === "shape" || state.activeTool === "type")) {
|
|
2531
|
-
const imgPt = (0,
|
|
2676
|
+
const imgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2532
2677
|
setShapeTypeError(null);
|
|
2533
2678
|
if (state.activeTool === "shape") shapeGestureRef.current.down(imgPt);
|
|
2534
2679
|
else {
|
|
@@ -2539,12 +2684,12 @@ var ImageEditor = ({
|
|
|
2539
2684
|
return;
|
|
2540
2685
|
}
|
|
2541
2686
|
if (activeTab === "annotate") {
|
|
2542
|
-
const imgPt = (0,
|
|
2687
|
+
const imgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2543
2688
|
dragStartPointRef.current = imgPt;
|
|
2544
2689
|
if (state.activeTool === "select") {
|
|
2545
2690
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
2546
2691
|
const ann = state.annotations[i];
|
|
2547
|
-
if ((0,
|
|
2692
|
+
if ((0, import_image_editor17.hitTestAnnotation)(imgPt, ann)) {
|
|
2548
2693
|
editor.selectAnnotation(ann.id);
|
|
2549
2694
|
annotationDragInfoRef.current = {
|
|
2550
2695
|
annId: ann.id,
|
|
@@ -2580,7 +2725,7 @@ var ImageEditor = ({
|
|
|
2580
2725
|
const canvasPt = getCanvasEventPoint(e);
|
|
2581
2726
|
if (activeTab === "select") {
|
|
2582
2727
|
const gesture = selectionGestureRef.current;
|
|
2583
|
-
if (gesture.active && gesture.move((0,
|
|
2728
|
+
if (gesture.active && gesture.move((0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false))) {
|
|
2584
2729
|
selectionDraftRef.current = gesture.draftPath;
|
|
2585
2730
|
renderCanvas();
|
|
2586
2731
|
}
|
|
@@ -2589,7 +2734,7 @@ var ImageEditor = ({
|
|
|
2589
2734
|
if (activeTab === "crop") {
|
|
2590
2735
|
const drag = cropDragInfoRef.current;
|
|
2591
2736
|
if (drag) {
|
|
2592
|
-
const currentImgPt = (0,
|
|
2737
|
+
const currentImgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, true);
|
|
2593
2738
|
let newCrop;
|
|
2594
2739
|
if (drag.handle === "new") {
|
|
2595
2740
|
const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));
|
|
@@ -2603,7 +2748,7 @@ var ImageEditor = ({
|
|
|
2603
2748
|
height: Math.round(Math.max(20, maxY - minY))
|
|
2604
2749
|
};
|
|
2605
2750
|
} else {
|
|
2606
|
-
newCrop = (0,
|
|
2751
|
+
newCrop = (0, import_image_editor17.calculateCropDrag)(
|
|
2607
2752
|
drag.startCrop,
|
|
2608
2753
|
drag.handle,
|
|
2609
2754
|
drag.startImgPt,
|
|
@@ -2623,15 +2768,15 @@ var ImageEditor = ({
|
|
|
2623
2768
|
width: state.imageDimensions.width,
|
|
2624
2769
|
height: state.imageDimensions.height
|
|
2625
2770
|
};
|
|
2626
|
-
const handle = (0,
|
|
2627
|
-
canvas.style.cursor = (0,
|
|
2771
|
+
const handle = (0, import_image_editor17.hitTestCrop)(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);
|
|
2772
|
+
canvas.style.cursor = (0, import_image_editor17.getCropCursor)(handle, state.transform);
|
|
2628
2773
|
}
|
|
2629
2774
|
return;
|
|
2630
2775
|
}
|
|
2631
2776
|
if (activeTab === "annotate" && state.activeTool === "shape") {
|
|
2632
2777
|
const g = shapeGestureRef.current;
|
|
2633
2778
|
if (g.active) {
|
|
2634
|
-
g.move((0,
|
|
2779
|
+
g.move((0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });
|
|
2635
2780
|
if (g.error) setShapeTypeError(g.error);
|
|
2636
2781
|
}
|
|
2637
2782
|
return;
|
|
@@ -2639,7 +2784,7 @@ var ImageEditor = ({
|
|
|
2639
2784
|
if (activeTab === "annotate") {
|
|
2640
2785
|
if (annotationDragInfoRef.current) {
|
|
2641
2786
|
const drag = annotationDragInfoRef.current;
|
|
2642
|
-
const currentImgPt2 = (0,
|
|
2787
|
+
const currentImgPt2 = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2643
2788
|
const dx = currentImgPt2.x - drag.startImgPt.x;
|
|
2644
2789
|
const dy = currentImgPt2.y - drag.startImgPt.y;
|
|
2645
2790
|
editor.updateAnnotation(drag.annId, {
|
|
@@ -2651,10 +2796,10 @@ var ImageEditor = ({
|
|
|
2651
2796
|
const startPt = dragStartPointRef.current;
|
|
2652
2797
|
if (!startPt) {
|
|
2653
2798
|
if (state.activeTool === "select") {
|
|
2654
|
-
const imgPt = (0,
|
|
2799
|
+
const imgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2655
2800
|
let hovered = false;
|
|
2656
2801
|
for (let i = state.annotations.length - 1; i >= 0; i--) {
|
|
2657
|
-
if ((0,
|
|
2802
|
+
if ((0, import_image_editor17.hitTestAnnotation)(imgPt, state.annotations[i])) {
|
|
2658
2803
|
hovered = true;
|
|
2659
2804
|
break;
|
|
2660
2805
|
}
|
|
@@ -2665,7 +2810,7 @@ var ImageEditor = ({
|
|
|
2665
2810
|
}
|
|
2666
2811
|
return;
|
|
2667
2812
|
}
|
|
2668
|
-
const currentImgPt = (0,
|
|
2813
|
+
const currentImgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2669
2814
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2670
2815
|
currentPathRef.current.push(currentImgPt);
|
|
2671
2816
|
const draft = {
|
|
@@ -2745,7 +2890,7 @@ var ImageEditor = ({
|
|
|
2745
2890
|
if (activeTab === "select") {
|
|
2746
2891
|
const gesture = selectionGestureRef.current;
|
|
2747
2892
|
if (gesture.active) {
|
|
2748
|
-
gesture.end((0,
|
|
2893
|
+
gesture.end((0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false), e);
|
|
2749
2894
|
selectionDraftRef.current = null;
|
|
2750
2895
|
renderCanvas();
|
|
2751
2896
|
}
|
|
@@ -2768,7 +2913,7 @@ var ImageEditor = ({
|
|
|
2768
2913
|
}
|
|
2769
2914
|
if (activeTab === "annotate" && state.activeTool === "type") {
|
|
2770
2915
|
const tool = typeToolRef.current;
|
|
2771
|
-
tool.up((0,
|
|
2916
|
+
tool.up((0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false));
|
|
2772
2917
|
setTypeSession(tool.session);
|
|
2773
2918
|
if (tool.error) setShapeTypeError(tool.error);
|
|
2774
2919
|
void renderCanvas();
|
|
@@ -2782,7 +2927,7 @@ var ImageEditor = ({
|
|
|
2782
2927
|
}
|
|
2783
2928
|
const startPt = dragStartPointRef.current;
|
|
2784
2929
|
if (startPt) {
|
|
2785
|
-
const currentImgPt = (0,
|
|
2930
|
+
const currentImgPt = (0, import_image_editor17.canvasToImagePoint)(canvasPt, state, canvas.width, canvas.height, false);
|
|
2786
2931
|
if (state.activeTool === "pen" && isDrawingRef.current) {
|
|
2787
2932
|
if (currentPathRef.current.length > 1) {
|
|
2788
2933
|
editor.addAnnotation({
|
|
@@ -2878,15 +3023,15 @@ var ImageEditor = ({
|
|
|
2878
3023
|
link.click();
|
|
2879
3024
|
}
|
|
2880
3025
|
};
|
|
2881
|
-
return /* @__PURE__ */ (0,
|
|
3026
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2882
3027
|
"div",
|
|
2883
3028
|
{
|
|
2884
3029
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
2885
3030
|
style,
|
|
2886
3031
|
children: [
|
|
2887
|
-
/* @__PURE__ */ (0,
|
|
2888
|
-
/* @__PURE__ */ (0,
|
|
2889
|
-
/* @__PURE__ */ (0,
|
|
3032
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.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: [
|
|
3033
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
3034
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2890
3035
|
"button",
|
|
2891
3036
|
{
|
|
2892
3037
|
type: "button",
|
|
@@ -2898,7 +3043,7 @@ var ImageEditor = ({
|
|
|
2898
3043
|
children: "Transform & Crop"
|
|
2899
3044
|
}
|
|
2900
3045
|
),
|
|
2901
|
-
/* @__PURE__ */ (0,
|
|
3046
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2902
3047
|
"button",
|
|
2903
3048
|
{
|
|
2904
3049
|
type: "button",
|
|
@@ -2910,7 +3055,7 @@ var ImageEditor = ({
|
|
|
2910
3055
|
children: "Adjustments"
|
|
2911
3056
|
}
|
|
2912
3057
|
),
|
|
2913
|
-
/* @__PURE__ */ (0,
|
|
3058
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2914
3059
|
"button",
|
|
2915
3060
|
{
|
|
2916
3061
|
type: "button",
|
|
@@ -2922,7 +3067,7 @@ var ImageEditor = ({
|
|
|
2922
3067
|
children: "Layers"
|
|
2923
3068
|
}
|
|
2924
3069
|
),
|
|
2925
|
-
/* @__PURE__ */ (0,
|
|
3070
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2926
3071
|
"button",
|
|
2927
3072
|
{
|
|
2928
3073
|
type: "button",
|
|
@@ -2934,7 +3079,7 @@ var ImageEditor = ({
|
|
|
2934
3079
|
children: "Paint"
|
|
2935
3080
|
}
|
|
2936
3081
|
),
|
|
2937
|
-
/* @__PURE__ */ (0,
|
|
3082
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2938
3083
|
"button",
|
|
2939
3084
|
{
|
|
2940
3085
|
type: "button",
|
|
@@ -2946,7 +3091,7 @@ var ImageEditor = ({
|
|
|
2946
3091
|
children: "Select & Mask"
|
|
2947
3092
|
}
|
|
2948
3093
|
),
|
|
2949
|
-
/* @__PURE__ */ (0,
|
|
3094
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2950
3095
|
"button",
|
|
2951
3096
|
{
|
|
2952
3097
|
type: "button",
|
|
@@ -2958,7 +3103,7 @@ var ImageEditor = ({
|
|
|
2958
3103
|
children: "Annotations"
|
|
2959
3104
|
}
|
|
2960
3105
|
),
|
|
2961
|
-
/* @__PURE__ */ (0,
|
|
3106
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2962
3107
|
"button",
|
|
2963
3108
|
{
|
|
2964
3109
|
type: "button",
|
|
@@ -2970,7 +3115,7 @@ var ImageEditor = ({
|
|
|
2970
3115
|
children: "Depth Mask"
|
|
2971
3116
|
}
|
|
2972
3117
|
),
|
|
2973
|
-
/* @__PURE__ */ (0,
|
|
3118
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2974
3119
|
"button",
|
|
2975
3120
|
{
|
|
2976
3121
|
type: "button",
|
|
@@ -2980,14 +3125,14 @@ var ImageEditor = ({
|
|
|
2980
3125
|
},
|
|
2981
3126
|
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"}`,
|
|
2982
3127
|
children: [
|
|
2983
|
-
/* @__PURE__ */ (0,
|
|
3128
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.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_runtime16.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" }) }),
|
|
2984
3129
|
"AI Tools"
|
|
2985
3130
|
]
|
|
2986
3131
|
}
|
|
2987
3132
|
)
|
|
2988
3133
|
] }),
|
|
2989
|
-
/* @__PURE__ */ (0,
|
|
2990
|
-
/* @__PURE__ */ (0,
|
|
3134
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
3135
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2991
3136
|
"button",
|
|
2992
3137
|
{
|
|
2993
3138
|
type: "button",
|
|
@@ -2998,7 +3143,7 @@ var ImageEditor = ({
|
|
|
2998
3143
|
children: "\u21A9"
|
|
2999
3144
|
}
|
|
3000
3145
|
),
|
|
3001
|
-
/* @__PURE__ */ (0,
|
|
3146
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3002
3147
|
"button",
|
|
3003
3148
|
{
|
|
3004
3149
|
type: "button",
|
|
@@ -3009,7 +3154,7 @@ var ImageEditor = ({
|
|
|
3009
3154
|
children: "\u21AA"
|
|
3010
3155
|
}
|
|
3011
3156
|
),
|
|
3012
|
-
/* @__PURE__ */ (0,
|
|
3157
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3013
3158
|
"button",
|
|
3014
3159
|
{
|
|
3015
3160
|
type: "button",
|
|
@@ -3018,8 +3163,8 @@ var ImageEditor = ({
|
|
|
3018
3163
|
children: "Reset"
|
|
3019
3164
|
}
|
|
3020
3165
|
),
|
|
3021
|
-
/* @__PURE__ */ (0,
|
|
3022
|
-
/* @__PURE__ */ (0,
|
|
3166
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
3167
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3023
3168
|
"button",
|
|
3024
3169
|
{
|
|
3025
3170
|
type: "button",
|
|
@@ -3029,11 +3174,11 @@ var ImageEditor = ({
|
|
|
3029
3174
|
children: "-"
|
|
3030
3175
|
}
|
|
3031
3176
|
),
|
|
3032
|
-
/* @__PURE__ */ (0,
|
|
3177
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
3033
3178
|
Math.round(state.zoom * 100),
|
|
3034
3179
|
"%"
|
|
3035
3180
|
] }),
|
|
3036
|
-
/* @__PURE__ */ (0,
|
|
3181
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3037
3182
|
"button",
|
|
3038
3183
|
{
|
|
3039
3184
|
type: "button",
|
|
@@ -3043,8 +3188,8 @@ var ImageEditor = ({
|
|
|
3043
3188
|
children: "+"
|
|
3044
3189
|
}
|
|
3045
3190
|
),
|
|
3046
|
-
/* @__PURE__ */ (0,
|
|
3047
|
-
/* @__PURE__ */ (0,
|
|
3191
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
3192
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3048
3193
|
"button",
|
|
3049
3194
|
{
|
|
3050
3195
|
type: "button",
|
|
@@ -3055,7 +3200,7 @@ var ImageEditor = ({
|
|
|
3055
3200
|
children: "Hold Compare"
|
|
3056
3201
|
}
|
|
3057
3202
|
),
|
|
3058
|
-
/* @__PURE__ */ (0,
|
|
3203
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3059
3204
|
"button",
|
|
3060
3205
|
{
|
|
3061
3206
|
type: "button",
|
|
@@ -3066,16 +3211,16 @@ var ImageEditor = ({
|
|
|
3066
3211
|
)
|
|
3067
3212
|
] })
|
|
3068
3213
|
] }),
|
|
3069
|
-
transformTool.active && /* @__PURE__ */ (0,
|
|
3070
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */ (0,
|
|
3071
|
-
/* @__PURE__ */ (0,
|
|
3072
|
-
/* @__PURE__ */ (0,
|
|
3214
|
+
transformTool.active && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
|
|
3215
|
+
!transformTool.active && transformTool.error && /* @__PURE__ */ (0, import_jsx_runtime16.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 }),
|
|
3216
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
3217
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3073
3218
|
"div",
|
|
3074
3219
|
{
|
|
3075
3220
|
ref: containerRef,
|
|
3076
3221
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
3077
3222
|
children: [
|
|
3078
|
-
/* @__PURE__ */ (0,
|
|
3223
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3079
3224
|
"canvas",
|
|
3080
3225
|
{
|
|
3081
3226
|
ref: canvasRef,
|
|
@@ -3092,7 +3237,7 @@ var ImageEditor = ({
|
|
|
3092
3237
|
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" : ""}`
|
|
3093
3238
|
}
|
|
3094
3239
|
),
|
|
3095
|
-
typeSession && /* @__PURE__ */ (0,
|
|
3240
|
+
typeSession && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3096
3241
|
"textarea",
|
|
3097
3242
|
{
|
|
3098
3243
|
ref: typeInputRef,
|
|
@@ -3114,11 +3259,11 @@ var ImageEditor = ({
|
|
|
3114
3259
|
]
|
|
3115
3260
|
}
|
|
3116
3261
|
),
|
|
3117
|
-
/* @__PURE__ */ (0,
|
|
3118
|
-
activeTab === "crop" && /* @__PURE__ */ (0,
|
|
3119
|
-
/* @__PURE__ */ (0,
|
|
3120
|
-
/* @__PURE__ */ (0,
|
|
3121
|
-
/* @__PURE__ */ (0,
|
|
3262
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.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: [
|
|
3263
|
+
activeTab === "crop" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3264
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
3265
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
3266
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3122
3267
|
"button",
|
|
3123
3268
|
{
|
|
3124
3269
|
type: "button",
|
|
@@ -3130,7 +3275,7 @@ var ImageEditor = ({
|
|
|
3130
3275
|
children: "Freeform"
|
|
3131
3276
|
}
|
|
3132
3277
|
),
|
|
3133
|
-
/* @__PURE__ */ (0,
|
|
3278
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3134
3279
|
"button",
|
|
3135
3280
|
{
|
|
3136
3281
|
type: "button",
|
|
@@ -3142,7 +3287,7 @@ var ImageEditor = ({
|
|
|
3142
3287
|
children: "1:1 Square"
|
|
3143
3288
|
}
|
|
3144
3289
|
),
|
|
3145
|
-
/* @__PURE__ */ (0,
|
|
3290
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3146
3291
|
"button",
|
|
3147
3292
|
{
|
|
3148
3293
|
type: "button",
|
|
@@ -3154,7 +3299,7 @@ var ImageEditor = ({
|
|
|
3154
3299
|
children: "4:3 Standard"
|
|
3155
3300
|
}
|
|
3156
3301
|
),
|
|
3157
|
-
/* @__PURE__ */ (0,
|
|
3302
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3158
3303
|
"button",
|
|
3159
3304
|
{
|
|
3160
3305
|
type: "button",
|
|
@@ -3166,7 +3311,7 @@ var ImageEditor = ({
|
|
|
3166
3311
|
children: "16:9 Wide"
|
|
3167
3312
|
}
|
|
3168
3313
|
),
|
|
3169
|
-
/* @__PURE__ */ (0,
|
|
3314
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3170
3315
|
"button",
|
|
3171
3316
|
{
|
|
3172
3317
|
type: "button",
|
|
@@ -3178,7 +3323,7 @@ var ImageEditor = ({
|
|
|
3178
3323
|
children: "3:2 Photo"
|
|
3179
3324
|
}
|
|
3180
3325
|
),
|
|
3181
|
-
/* @__PURE__ */ (0,
|
|
3326
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3182
3327
|
"button",
|
|
3183
3328
|
{
|
|
3184
3329
|
type: "button",
|
|
@@ -3191,10 +3336,10 @@ var ImageEditor = ({
|
|
|
3191
3336
|
}
|
|
3192
3337
|
)
|
|
3193
3338
|
] }),
|
|
3194
|
-
/* @__PURE__ */ (0,
|
|
3195
|
-
/* @__PURE__ */ (0,
|
|
3196
|
-
/* @__PURE__ */ (0,
|
|
3197
|
-
/* @__PURE__ */ (0,
|
|
3339
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3340
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
3341
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
3342
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3198
3343
|
"button",
|
|
3199
3344
|
{
|
|
3200
3345
|
type: "button",
|
|
@@ -3203,7 +3348,7 @@ var ImageEditor = ({
|
|
|
3203
3348
|
children: "Rotate -90\xB0"
|
|
3204
3349
|
}
|
|
3205
3350
|
),
|
|
3206
|
-
/* @__PURE__ */ (0,
|
|
3351
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3207
3352
|
"button",
|
|
3208
3353
|
{
|
|
3209
3354
|
type: "button",
|
|
@@ -3212,7 +3357,7 @@ var ImageEditor = ({
|
|
|
3212
3357
|
children: "Rotate +90\xB0"
|
|
3213
3358
|
}
|
|
3214
3359
|
),
|
|
3215
|
-
/* @__PURE__ */ (0,
|
|
3360
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3216
3361
|
"button",
|
|
3217
3362
|
{
|
|
3218
3363
|
type: "button",
|
|
@@ -3221,7 +3366,7 @@ var ImageEditor = ({
|
|
|
3221
3366
|
children: "Flip Horizontal"
|
|
3222
3367
|
}
|
|
3223
3368
|
),
|
|
3224
|
-
/* @__PURE__ */ (0,
|
|
3369
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3225
3370
|
"button",
|
|
3226
3371
|
{
|
|
3227
3372
|
type: "button",
|
|
@@ -3232,10 +3377,10 @@ var ImageEditor = ({
|
|
|
3232
3377
|
)
|
|
3233
3378
|
] })
|
|
3234
3379
|
] }),
|
|
3235
|
-
activeTab === "adjust" && /* @__PURE__ */ (0,
|
|
3236
|
-
/* @__PURE__ */ (0,
|
|
3237
|
-
/* @__PURE__ */ (0,
|
|
3238
|
-
/* @__PURE__ */ (0,
|
|
3380
|
+
activeTab === "adjust" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3381
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3382
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
3383
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3239
3384
|
"button",
|
|
3240
3385
|
{
|
|
3241
3386
|
type: "button",
|
|
@@ -3245,25 +3390,25 @@ var ImageEditor = ({
|
|
|
3245
3390
|
}
|
|
3246
3391
|
)
|
|
3247
3392
|
] }),
|
|
3248
|
-
/* @__PURE__ */ (0,
|
|
3249
|
-
|
|
3250
|
-
/* @__PURE__ */ (0,
|
|
3393
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Histogram, { histogram: editor.histogram }),
|
|
3394
|
+
import_image_editor17.IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react15.default.Fragment, { children: [
|
|
3395
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3251
3396
|
ControlSlider,
|
|
3252
3397
|
{
|
|
3253
3398
|
spec,
|
|
3254
|
-
value: (0,
|
|
3399
|
+
value: (0, import_image_editor17.readAdjustmentControls)(state.adjustments)[spec.id],
|
|
3255
3400
|
disabled: spec.requiresProcess !== void 0 && legacyProcess,
|
|
3256
3401
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
3257
3402
|
}
|
|
3258
3403
|
),
|
|
3259
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0,
|
|
3404
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3260
3405
|
"div",
|
|
3261
3406
|
{
|
|
3262
3407
|
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",
|
|
3263
3408
|
"data-testid": "image-editor-process-notice",
|
|
3264
3409
|
children: [
|
|
3265
|
-
/* @__PURE__ */ (0,
|
|
3266
|
-
/* @__PURE__ */ (0,
|
|
3410
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
3411
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3267
3412
|
"button",
|
|
3268
3413
|
{
|
|
3269
3414
|
type: "button",
|
|
@@ -3276,7 +3421,7 @@ var ImageEditor = ({
|
|
|
3276
3421
|
}
|
|
3277
3422
|
)
|
|
3278
3423
|
] }, spec.id)),
|
|
3279
|
-
/* @__PURE__ */ (0,
|
|
3424
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3280
3425
|
AdjustmentLayersPanel,
|
|
3281
3426
|
{
|
|
3282
3427
|
controller,
|
|
@@ -3285,9 +3430,9 @@ var ImageEditor = ({
|
|
|
3285
3430
|
}
|
|
3286
3431
|
) })
|
|
3287
3432
|
] }),
|
|
3288
|
-
activeTab === "layers" && /* @__PURE__ */ (0,
|
|
3289
|
-
/* @__PURE__ */ (0,
|
|
3290
|
-
/* @__PURE__ */ (0,
|
|
3433
|
+
activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3434
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
3435
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3291
3436
|
"button",
|
|
3292
3437
|
{
|
|
3293
3438
|
type: "button",
|
|
@@ -3298,14 +3443,14 @@ var ImageEditor = ({
|
|
|
3298
3443
|
children: "Free Transform"
|
|
3299
3444
|
}
|
|
3300
3445
|
),
|
|
3301
|
-
/* @__PURE__ */ (0,
|
|
3302
|
-
/* @__PURE__ */ (0,
|
|
3303
|
-
/* @__PURE__ */ (0,
|
|
3446
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(LayersPanel, { controller }),
|
|
3447
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
|
|
3448
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ColorProfilePanel, { controller })
|
|
3304
3449
|
] }),
|
|
3305
|
-
activeTab === "paint" && /* @__PURE__ */ (0,
|
|
3306
|
-
/* @__PURE__ */ (0,
|
|
3307
|
-
/* @__PURE__ */ (0,
|
|
3308
|
-
/* @__PURE__ */ (0,
|
|
3450
|
+
activeTab === "paint" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3451
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
3452
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(BrushOptionsBar, { controller }),
|
|
3453
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3309
3454
|
"button",
|
|
3310
3455
|
{
|
|
3311
3456
|
type: "button",
|
|
@@ -3316,12 +3461,12 @@ var ImageEditor = ({
|
|
|
3316
3461
|
children: "Free Transform"
|
|
3317
3462
|
}
|
|
3318
3463
|
),
|
|
3319
|
-
paintError && /* @__PURE__ */ (0,
|
|
3320
|
-
/* @__PURE__ */ (0,
|
|
3464
|
+
paintError && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
3465
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(LayersPanel, { controller }) })
|
|
3321
3466
|
] }),
|
|
3322
|
-
activeTab === "annotate" && /* @__PURE__ */ (0,
|
|
3323
|
-
/* @__PURE__ */ (0,
|
|
3324
|
-
/* @__PURE__ */ (0,
|
|
3467
|
+
activeTab === "annotate" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3468
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
|
|
3469
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3325
3470
|
"button",
|
|
3326
3471
|
{
|
|
3327
3472
|
type: "button",
|
|
@@ -3332,13 +3477,13 @@ var ImageEditor = ({
|
|
|
3332
3477
|
},
|
|
3333
3478
|
t
|
|
3334
3479
|
)) }),
|
|
3335
|
-
state.activeTool === "shape" && /* @__PURE__ */ (0,
|
|
3336
|
-
state.activeTool === "type" && /* @__PURE__ */ (0,
|
|
3337
|
-
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0,
|
|
3338
|
-
shapeTypeError && /* @__PURE__ */ (0,
|
|
3339
|
-
/* @__PURE__ */ (0,
|
|
3340
|
-
/* @__PURE__ */ (0,
|
|
3341
|
-
/* @__PURE__ */ (0,
|
|
3480
|
+
state.activeTool === "shape" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
|
|
3481
|
+
state.activeTool === "type" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
|
|
3482
|
+
state.activeTool === "type" && typeSession && /* @__PURE__ */ (0, import_jsx_runtime16.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" }),
|
|
3483
|
+
shapeTypeError && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
|
|
3484
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3485
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
3486
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3342
3487
|
"button",
|
|
3343
3488
|
{
|
|
3344
3489
|
type: "button",
|
|
@@ -3348,9 +3493,9 @@ var ImageEditor = ({
|
|
|
3348
3493
|
},
|
|
3349
3494
|
t
|
|
3350
3495
|
)) }),
|
|
3351
|
-
/* @__PURE__ */ (0,
|
|
3352
|
-
/* @__PURE__ */ (0,
|
|
3353
|
-
/* @__PURE__ */ (0,
|
|
3496
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
3497
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { className: "text-slate-400", children: "Color:" }),
|
|
3498
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3354
3499
|
"input",
|
|
3355
3500
|
{
|
|
3356
3501
|
type: "color",
|
|
@@ -3359,15 +3504,15 @@ var ImageEditor = ({
|
|
|
3359
3504
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
3360
3505
|
}
|
|
3361
3506
|
),
|
|
3362
|
-
/* @__PURE__ */ (0,
|
|
3363
|
-
/* @__PURE__ */ (0,
|
|
3364
|
-
/* @__PURE__ */ (0,
|
|
3365
|
-
/* @__PURE__ */ (0,
|
|
3507
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex-1 ml-2", children: [
|
|
3508
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
3509
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Width:" }),
|
|
3510
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "font-mono", children: [
|
|
3366
3511
|
strokeWidth,
|
|
3367
3512
|
"px"
|
|
3368
3513
|
] })
|
|
3369
3514
|
] }),
|
|
3370
|
-
/* @__PURE__ */ (0,
|
|
3515
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3371
3516
|
"input",
|
|
3372
3517
|
{
|
|
3373
3518
|
type: "range",
|
|
@@ -3380,10 +3525,10 @@ var ImageEditor = ({
|
|
|
3380
3525
|
)
|
|
3381
3526
|
] })
|
|
3382
3527
|
] }),
|
|
3383
|
-
/* @__PURE__ */ (0,
|
|
3384
|
-
/* @__PURE__ */ (0,
|
|
3385
|
-
/* @__PURE__ */ (0,
|
|
3386
|
-
/* @__PURE__ */ (0,
|
|
3528
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3529
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
3530
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex gap-2", children: [
|
|
3531
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3387
3532
|
"input",
|
|
3388
3533
|
{
|
|
3389
3534
|
type: "text",
|
|
@@ -3394,7 +3539,7 @@ var ImageEditor = ({
|
|
|
3394
3539
|
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"
|
|
3395
3540
|
}
|
|
3396
3541
|
),
|
|
3397
|
-
/* @__PURE__ */ (0,
|
|
3542
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3398
3543
|
"button",
|
|
3399
3544
|
{
|
|
3400
3545
|
type: "button",
|
|
@@ -3404,14 +3549,14 @@ var ImageEditor = ({
|
|
|
3404
3549
|
}
|
|
3405
3550
|
)
|
|
3406
3551
|
] }),
|
|
3407
|
-
/* @__PURE__ */ (0,
|
|
3408
|
-
/* @__PURE__ */ (0,
|
|
3409
|
-
/* @__PURE__ */ (0,
|
|
3552
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
3553
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Font Size:" }),
|
|
3554
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "font-mono", children: [
|
|
3410
3555
|
fontSize,
|
|
3411
3556
|
"px"
|
|
3412
3557
|
] })
|
|
3413
3558
|
] }),
|
|
3414
|
-
/* @__PURE__ */ (0,
|
|
3559
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3415
3560
|
"input",
|
|
3416
3561
|
{
|
|
3417
3562
|
type: "range",
|
|
@@ -3422,14 +3567,14 @@ var ImageEditor = ({
|
|
|
3422
3567
|
className: "w-full accent-indigo-500"
|
|
3423
3568
|
}
|
|
3424
3569
|
),
|
|
3425
|
-
/* @__PURE__ */ (0,
|
|
3426
|
-
/* @__PURE__ */ (0,
|
|
3427
|
-
/* @__PURE__ */ (0,
|
|
3570
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3571
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3572
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "text-slate-400", children: [
|
|
3428
3573
|
"Layers (",
|
|
3429
3574
|
state.annotations.length,
|
|
3430
3575
|
")"
|
|
3431
3576
|
] }),
|
|
3432
|
-
state.selectedAnnotationId && /* @__PURE__ */ (0,
|
|
3577
|
+
state.selectedAnnotationId && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3433
3578
|
"button",
|
|
3434
3579
|
{
|
|
3435
3580
|
type: "button",
|
|
@@ -3438,7 +3583,7 @@ var ImageEditor = ({
|
|
|
3438
3583
|
children: "Delete Selected"
|
|
3439
3584
|
}
|
|
3440
3585
|
),
|
|
3441
|
-
state.annotations.length > 0 && /* @__PURE__ */ (0,
|
|
3586
|
+
state.annotations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3442
3587
|
"button",
|
|
3443
3588
|
{
|
|
3444
3589
|
type: "button",
|
|
@@ -3449,10 +3594,10 @@ var ImageEditor = ({
|
|
|
3449
3594
|
)
|
|
3450
3595
|
] })
|
|
3451
3596
|
] }),
|
|
3452
|
-
activeTab === "depth" && /* @__PURE__ */ (0,
|
|
3453
|
-
/* @__PURE__ */ (0,
|
|
3454
|
-
/* @__PURE__ */ (0,
|
|
3455
|
-
/* @__PURE__ */ (0,
|
|
3597
|
+
activeTab === "depth" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3598
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3599
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
3600
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3456
3601
|
"button",
|
|
3457
3602
|
{
|
|
3458
3603
|
type: "button",
|
|
@@ -3462,8 +3607,8 @@ var ImageEditor = ({
|
|
|
3462
3607
|
}
|
|
3463
3608
|
)
|
|
3464
3609
|
] }),
|
|
3465
|
-
/* @__PURE__ */ (0,
|
|
3466
|
-
/* @__PURE__ */ (0,
|
|
3610
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
3611
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3467
3612
|
"input",
|
|
3468
3613
|
{
|
|
3469
3614
|
type: "checkbox",
|
|
@@ -3472,12 +3617,12 @@ var ImageEditor = ({
|
|
|
3472
3617
|
className: "rounded accent-indigo-500"
|
|
3473
3618
|
}
|
|
3474
3619
|
),
|
|
3475
|
-
/* @__PURE__ */ (0,
|
|
3620
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Enable Depth / Alpha Mask" })
|
|
3476
3621
|
] }),
|
|
3477
|
-
state.depthMask.enabled && /* @__PURE__ */ (0,
|
|
3478
|
-
/* @__PURE__ */ (0,
|
|
3479
|
-
/* @__PURE__ */ (0,
|
|
3480
|
-
/* @__PURE__ */ (0,
|
|
3622
|
+
state.depthMask.enabled && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3623
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
3624
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
3625
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3481
3626
|
"input",
|
|
3482
3627
|
{
|
|
3483
3628
|
type: "text",
|
|
@@ -3488,8 +3633,8 @@ var ImageEditor = ({
|
|
|
3488
3633
|
}
|
|
3489
3634
|
)
|
|
3490
3635
|
] }),
|
|
3491
|
-
/* @__PURE__ */ (0,
|
|
3492
|
-
/* @__PURE__ */ (0,
|
|
3636
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex gap-2", children: [
|
|
3637
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3493
3638
|
"button",
|
|
3494
3639
|
{
|
|
3495
3640
|
type: "button",
|
|
@@ -3498,7 +3643,7 @@ var ImageEditor = ({
|
|
|
3498
3643
|
children: "Threshold Mode"
|
|
3499
3644
|
}
|
|
3500
3645
|
),
|
|
3501
|
-
/* @__PURE__ */ (0,
|
|
3646
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3502
3647
|
"button",
|
|
3503
3648
|
{
|
|
3504
3649
|
type: "button",
|
|
@@ -3508,12 +3653,12 @@ var ImageEditor = ({
|
|
|
3508
3653
|
}
|
|
3509
3654
|
)
|
|
3510
3655
|
] }),
|
|
3511
|
-
/* @__PURE__ */ (0,
|
|
3512
|
-
/* @__PURE__ */ (0,
|
|
3513
|
-
/* @__PURE__ */ (0,
|
|
3514
|
-
/* @__PURE__ */ (0,
|
|
3656
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
3657
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3658
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Depth Start (Lower):" }),
|
|
3659
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
3515
3660
|
] }),
|
|
3516
|
-
/* @__PURE__ */ (0,
|
|
3661
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3517
3662
|
"input",
|
|
3518
3663
|
{
|
|
3519
3664
|
type: "range",
|
|
@@ -3527,12 +3672,12 @@ var ImageEditor = ({
|
|
|
3527
3672
|
}
|
|
3528
3673
|
)
|
|
3529
3674
|
] }),
|
|
3530
|
-
/* @__PURE__ */ (0,
|
|
3531
|
-
/* @__PURE__ */ (0,
|
|
3532
|
-
/* @__PURE__ */ (0,
|
|
3533
|
-
/* @__PURE__ */ (0,
|
|
3675
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
3676
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3677
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Depth Stop (Upper):" }),
|
|
3678
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
3534
3679
|
] }),
|
|
3535
|
-
/* @__PURE__ */ (0,
|
|
3680
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3536
3681
|
"input",
|
|
3537
3682
|
{
|
|
3538
3683
|
type: "range",
|
|
@@ -3546,12 +3691,12 @@ var ImageEditor = ({
|
|
|
3546
3691
|
}
|
|
3547
3692
|
)
|
|
3548
3693
|
] }),
|
|
3549
|
-
/* @__PURE__ */ (0,
|
|
3550
|
-
/* @__PURE__ */ (0,
|
|
3551
|
-
/* @__PURE__ */ (0,
|
|
3552
|
-
/* @__PURE__ */ (0,
|
|
3694
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
3695
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3696
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Softness:" }),
|
|
3697
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "font-mono", children: state.depthMask.softness })
|
|
3553
3698
|
] }),
|
|
3554
|
-
/* @__PURE__ */ (0,
|
|
3699
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3555
3700
|
"input",
|
|
3556
3701
|
{
|
|
3557
3702
|
type: "range",
|
|
@@ -3563,8 +3708,8 @@ var ImageEditor = ({
|
|
|
3563
3708
|
}
|
|
3564
3709
|
)
|
|
3565
3710
|
] }),
|
|
3566
|
-
/* @__PURE__ */ (0,
|
|
3567
|
-
/* @__PURE__ */ (0,
|
|
3711
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
3712
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3568
3713
|
"input",
|
|
3569
3714
|
{
|
|
3570
3715
|
type: "checkbox",
|
|
@@ -3573,12 +3718,12 @@ var ImageEditor = ({
|
|
|
3573
3718
|
className: "rounded accent-indigo-500"
|
|
3574
3719
|
}
|
|
3575
3720
|
),
|
|
3576
|
-
/* @__PURE__ */ (0,
|
|
3721
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Invert Mask" })
|
|
3577
3722
|
] })
|
|
3578
3723
|
] })
|
|
3579
3724
|
] }),
|
|
3580
|
-
activeTab === "select" && /* @__PURE__ */ (0,
|
|
3581
|
-
/* @__PURE__ */ (0,
|
|
3725
|
+
activeTab === "select" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3726
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3582
3727
|
SelectionOptionsBar,
|
|
3583
3728
|
{
|
|
3584
3729
|
controller,
|
|
@@ -3588,9 +3733,9 @@ var ImageEditor = ({
|
|
|
3588
3733
|
quickMask: Boolean(state.quickMask)
|
|
3589
3734
|
}
|
|
3590
3735
|
),
|
|
3591
|
-
selectionError && /* @__PURE__ */ (0,
|
|
3592
|
-
/* @__PURE__ */ (0,
|
|
3593
|
-
/* @__PURE__ */ (0,
|
|
3736
|
+
selectionError && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
3737
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex gap-1", children: [
|
|
3738
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3594
3739
|
"button",
|
|
3595
3740
|
{
|
|
3596
3741
|
type: "button",
|
|
@@ -3601,7 +3746,7 @@ var ImageEditor = ({
|
|
|
3601
3746
|
children: "Transform Selection"
|
|
3602
3747
|
}
|
|
3603
3748
|
),
|
|
3604
|
-
/* @__PURE__ */ (0,
|
|
3749
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3605
3750
|
"button",
|
|
3606
3751
|
{
|
|
3607
3752
|
type: "button",
|
|
@@ -3613,12 +3758,12 @@ var ImageEditor = ({
|
|
|
3613
3758
|
}
|
|
3614
3759
|
)
|
|
3615
3760
|
] }),
|
|
3616
|
-
/* @__PURE__ */ (0,
|
|
3761
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
3617
3762
|
] }),
|
|
3618
|
-
activeTab === "ai" && /* @__PURE__ */ (0,
|
|
3619
|
-
/* @__PURE__ */ (0,
|
|
3620
|
-
/* @__PURE__ */ (0,
|
|
3621
|
-
/* @__PURE__ */ (0,
|
|
3763
|
+
activeTab === "ai" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3764
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
3765
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: "Results go to" }),
|
|
3766
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3622
3767
|
"select",
|
|
3623
3768
|
{
|
|
3624
3769
|
"aria-label": "AI result target",
|
|
@@ -3626,54 +3771,54 @@ var ImageEditor = ({
|
|
|
3626
3771
|
onChange: (e) => setAiTarget(e.target.value),
|
|
3627
3772
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
3628
3773
|
children: [
|
|
3629
|
-
/* @__PURE__ */ (0,
|
|
3630
|
-
/* @__PURE__ */ (0,
|
|
3631
|
-
/* @__PURE__ */ (0,
|
|
3774
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
3775
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "new-layer", children: "New layer / mask" }),
|
|
3776
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("option", { value: "replace", children: "Replace image" })
|
|
3632
3777
|
]
|
|
3633
3778
|
}
|
|
3634
3779
|
)
|
|
3635
3780
|
] }),
|
|
3636
|
-
/* @__PURE__ */ (0,
|
|
3637
|
-
/* @__PURE__ */ (0,
|
|
3638
|
-
/* @__PURE__ */ (0,
|
|
3639
|
-
/* @__PURE__ */ (0,
|
|
3781
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3782
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3783
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3784
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.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_runtime16.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" }) }),
|
|
3640
3785
|
"Background Removal"
|
|
3641
3786
|
] }),
|
|
3642
|
-
isRemovingBg && /* @__PURE__ */ (0,
|
|
3787
|
+
isRemovingBg && /* @__PURE__ */ (0, import_jsx_runtime16.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..." })
|
|
3643
3788
|
] }),
|
|
3644
|
-
/* @__PURE__ */ (0,
|
|
3645
|
-
/* @__PURE__ */ (0,
|
|
3789
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
3790
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3646
3791
|
"button",
|
|
3647
3792
|
{
|
|
3648
3793
|
type: "button",
|
|
3649
3794
|
onClick: handleRemoveBackground,
|
|
3650
3795
|
disabled: isRemovingBg || isInpainting,
|
|
3651
3796
|
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",
|
|
3652
|
-
children: isRemovingBg ? /* @__PURE__ */ (0,
|
|
3653
|
-
/* @__PURE__ */ (0,
|
|
3797
|
+
children: isRemovingBg ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3798
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
3654
3799
|
"Removing Background..."
|
|
3655
|
-
] }) : /* @__PURE__ */ (0,
|
|
3656
|
-
/* @__PURE__ */ (0,
|
|
3800
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3801
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.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_runtime16.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" }) }),
|
|
3657
3802
|
"Remove Background"
|
|
3658
3803
|
] })
|
|
3659
3804
|
}
|
|
3660
3805
|
)
|
|
3661
3806
|
] }),
|
|
3662
|
-
/* @__PURE__ */ (0,
|
|
3663
|
-
/* @__PURE__ */ (0,
|
|
3664
|
-
/* @__PURE__ */ (0,
|
|
3665
|
-
/* @__PURE__ */ (0,
|
|
3666
|
-
/* @__PURE__ */ (0,
|
|
3667
|
-
/* @__PURE__ */ (0,
|
|
3807
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3808
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
3809
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3810
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
3811
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.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" }),
|
|
3812
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "m14 7 3 3" })
|
|
3668
3813
|
] }),
|
|
3669
3814
|
"Generative Inpainting"
|
|
3670
3815
|
] }),
|
|
3671
|
-
isInpainting && /* @__PURE__ */ (0,
|
|
3816
|
+
isInpainting && /* @__PURE__ */ (0, import_jsx_runtime16.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..." })
|
|
3672
3817
|
] }),
|
|
3673
|
-
/* @__PURE__ */ (0,
|
|
3674
|
-
/* @__PURE__ */ (0,
|
|
3675
|
-
/* @__PURE__ */ (0,
|
|
3676
|
-
/* @__PURE__ */ (0,
|
|
3818
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
3819
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3820
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
3821
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3677
3822
|
"textarea",
|
|
3678
3823
|
{
|
|
3679
3824
|
id: "ai-inpaint-prompt-react",
|
|
@@ -3685,10 +3830,10 @@ var ImageEditor = ({
|
|
|
3685
3830
|
}
|
|
3686
3831
|
)
|
|
3687
3832
|
] }),
|
|
3688
|
-
/* @__PURE__ */ (0,
|
|
3689
|
-
/* @__PURE__ */ (0,
|
|
3690
|
-
/* @__PURE__ */ (0,
|
|
3691
|
-
/* @__PURE__ */ (0,
|
|
3833
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
3834
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
3835
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
3836
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3692
3837
|
"button",
|
|
3693
3838
|
{
|
|
3694
3839
|
type: "button",
|
|
@@ -3701,7 +3846,7 @@ var ImageEditor = ({
|
|
|
3701
3846
|
]
|
|
3702
3847
|
}
|
|
3703
3848
|
),
|
|
3704
|
-
/* @__PURE__ */ (0,
|
|
3849
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3705
3850
|
"button",
|
|
3706
3851
|
{
|
|
3707
3852
|
type: "button",
|
|
@@ -3716,25 +3861,25 @@ var ImageEditor = ({
|
|
|
3716
3861
|
)
|
|
3717
3862
|
] })
|
|
3718
3863
|
] }),
|
|
3719
|
-
/* @__PURE__ */ (0,
|
|
3864
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3720
3865
|
"button",
|
|
3721
3866
|
{
|
|
3722
3867
|
type: "button",
|
|
3723
3868
|
onClick: handleInpaint,
|
|
3724
3869
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
3725
3870
|
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",
|
|
3726
|
-
children: isInpainting ? /* @__PURE__ */ (0,
|
|
3727
|
-
/* @__PURE__ */ (0,
|
|
3871
|
+
children: isInpainting ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3872
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
3728
3873
|
"Generating Inpaint..."
|
|
3729
|
-
] }) : /* @__PURE__ */ (0,
|
|
3730
|
-
/* @__PURE__ */ (0,
|
|
3874
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
3875
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.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_runtime16.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" }) }),
|
|
3731
3876
|
"Apply Inpainting"
|
|
3732
3877
|
] })
|
|
3733
3878
|
}
|
|
3734
3879
|
)
|
|
3735
3880
|
] }),
|
|
3736
|
-
aiError && /* @__PURE__ */ (0,
|
|
3737
|
-
aiSuccess && /* @__PURE__ */ (0,
|
|
3881
|
+
aiError && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
3882
|
+
aiSuccess && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
3738
3883
|
] })
|
|
3739
3884
|
] })
|
|
3740
3885
|
] })
|
|
@@ -3754,6 +3899,7 @@ var ImageEditor = ({
|
|
|
3754
3899
|
ImageEditor,
|
|
3755
3900
|
LayerEffectsPanel,
|
|
3756
3901
|
LayersPanel,
|
|
3902
|
+
PaintGradientEditor,
|
|
3757
3903
|
RefineEdgePanel,
|
|
3758
3904
|
SelectionOptionsBar,
|
|
3759
3905
|
ShapeOptionsBar,
|