@pixerate/editor-react 0.76.0 → 0.78.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-LWMUV5TC.js → chunk-2EW42UXC.js} +639 -461
- package/dist/chunk-2EW42UXC.js.map +1 -0
- package/dist/chunk-FX3EREF5.js +206 -0
- package/dist/chunk-FX3EREF5.js.map +1 -0
- package/dist/chunk-MO354USR.js +126 -0
- package/dist/chunk-MO354USR.js.map +1 -0
- package/dist/chunk-ZQZAKUUM.js +416 -0
- package/dist/chunk-ZQZAKUUM.js.map +1 -0
- package/dist/effects/index.cjs +606 -0
- package/dist/effects/index.cjs.map +1 -0
- package/dist/effects/index.d.cts +80 -0
- package/dist/effects/index.d.ts +80 -0
- package/dist/effects/index.js +16 -0
- package/dist/effects/index.js.map +1 -0
- package/dist/image-editor/index.cjs +1388 -534
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +36 -3
- package/dist/image-editor/index.d.ts +36 -3
- package/dist/image-editor/index.js +10 -1
- package/dist/index.cjs +1806 -952
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +10 -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/dist/parameters/index.js +55 -439
- package/dist/parameters/index.js.map +1 -1
- package/dist/video-editor/index.cjs +732 -17
- package/dist/video-editor/index.cjs.map +1 -1
- package/dist/video-editor/index.d.cts +31 -3
- package/dist/video-editor/index.d.ts +31 -3
- package/dist/video-editor/index.js +184 -17
- package/dist/video-editor/index.js.map +1 -1
- package/package.json +8 -3
- package/dist/chunk-LWMUV5TC.js.map +0 -1
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EffectParameters,
|
|
3
|
+
EffectsBrowser,
|
|
4
|
+
useEffectDescription,
|
|
5
|
+
useEffects
|
|
6
|
+
} from "./chunk-FX3EREF5.js";
|
|
7
|
+
import {
|
|
8
|
+
PaintGradientEditorView
|
|
9
|
+
} from "./chunk-MO354USR.js";
|
|
10
|
+
|
|
1
11
|
// src/image-editor/useImageEditor.ts
|
|
2
12
|
import { useRef, useState, useEffect, useCallback, useMemo } from "react";
|
|
3
13
|
import {
|
|
4
|
-
ImageEditorController
|
|
14
|
+
ImageEditorController,
|
|
15
|
+
createImageEffectsToolProvider
|
|
5
16
|
} from "@pixerate/editor/image-editor";
|
|
6
17
|
function useImageEditor(options = {}) {
|
|
7
18
|
const controllerRef = useRef(null);
|
|
@@ -157,9 +168,16 @@ function useImageEditor(options = {}) {
|
|
|
157
168
|
[controller, state, historyTicks, histogram]
|
|
158
169
|
);
|
|
159
170
|
}
|
|
171
|
+
function useImageEffectsTools(registry, controller, options = {}) {
|
|
172
|
+
const { id, namespace, readOnly } = options;
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
if (!registry) return;
|
|
175
|
+
return registry.register(createImageEffectsToolProvider(controller, { id, namespace, readOnly }));
|
|
176
|
+
}, [registry, controller, id, namespace, readOnly]);
|
|
177
|
+
}
|
|
160
178
|
|
|
161
179
|
// src/image-editor/ImageEditor.tsx
|
|
162
|
-
import
|
|
180
|
+
import React14, { useRef as useRef5, useEffect as useEffect12, useState as useState15, useCallback as useCallback2 } from "react";
|
|
163
181
|
import {
|
|
164
182
|
canvasToImagePoint,
|
|
165
183
|
hitTestCrop,
|
|
@@ -1264,8 +1282,139 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
1264
1282
|
] });
|
|
1265
1283
|
};
|
|
1266
1284
|
|
|
1285
|
+
// src/image-editor/ImageProviderEffectsPanel.tsx
|
|
1286
|
+
import React6, { useEffect as useEffect6, useState as useState7 } from "react";
|
|
1287
|
+
import { findLayer } from "@pixerate/editor/image-editor";
|
|
1288
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1289
|
+
var btn = "rounded border border-slate-700 px-1.5 py-0.5 text-[11px] text-slate-300 hover:text-white disabled:opacity-40";
|
|
1290
|
+
function Controls({
|
|
1291
|
+
provider,
|
|
1292
|
+
effect,
|
|
1293
|
+
name,
|
|
1294
|
+
values,
|
|
1295
|
+
onChange,
|
|
1296
|
+
onPreset
|
|
1297
|
+
}) {
|
|
1298
|
+
const { description, error } = useEffectDescription(provider, effect);
|
|
1299
|
+
if (!provider) return /* @__PURE__ */ jsxs7("p", { className: "text-[11px] text-slate-400", children: [
|
|
1300
|
+
'No effects provider: "',
|
|
1301
|
+
name ?? effect,
|
|
1302
|
+
'" is kept but not drawn.'
|
|
1303
|
+
] });
|
|
1304
|
+
if (error) return /* @__PURE__ */ jsx7("p", { className: "text-[11px] text-amber-400", children: error });
|
|
1305
|
+
if (!description) return /* @__PURE__ */ jsx7("p", { className: "text-[11px] text-slate-400", children: "Loading\u2026" });
|
|
1306
|
+
return /* @__PURE__ */ jsx7(EffectParameters, { description, values, onChange, onReset: (k) => onChange(k, description.defaults[k], null), onPreset });
|
|
1307
|
+
}
|
|
1308
|
+
function ImageProviderEffectsPanel({ controller, className = "" }) {
|
|
1309
|
+
const [, setTick] = useState7(0);
|
|
1310
|
+
useEffect6(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1311
|
+
const [browse, setBrowse] = useState7(null);
|
|
1312
|
+
const [message, setMessage] = useState7(null);
|
|
1313
|
+
const [open, setOpen] = useState7(null);
|
|
1314
|
+
const provider = controller.effectsProvider;
|
|
1315
|
+
const state = controller.getState();
|
|
1316
|
+
const layer = state.activeLayerId ? findLayer(state.layers, state.activeLayerId)?.layer ?? null : null;
|
|
1317
|
+
const run = (work) => {
|
|
1318
|
+
setMessage(null);
|
|
1319
|
+
Promise.resolve().then(work).catch((e) => setMessage(e instanceof Error ? e.message : String(e)));
|
|
1320
|
+
};
|
|
1321
|
+
const drags = React6.useRef(/* @__PURE__ */ new Set());
|
|
1322
|
+
const commit = (gesture) => {
|
|
1323
|
+
if (gesture) {
|
|
1324
|
+
if (!drags.current.has(gesture)) {
|
|
1325
|
+
drags.current.add(gesture);
|
|
1326
|
+
return true;
|
|
1327
|
+
}
|
|
1328
|
+
return false;
|
|
1329
|
+
}
|
|
1330
|
+
return true;
|
|
1331
|
+
};
|
|
1332
|
+
const filters = layer?.type === "smart" ? (layer.smartFilters?.filters ?? []).filter((f) => f.kind === "effect") : [];
|
|
1333
|
+
const generator = layer?.type === "pixel" ? layer.generator : void 0;
|
|
1334
|
+
const canFilter = !!layer && layer.type !== "adjustment" && layer.type !== "annotation";
|
|
1335
|
+
return /* @__PURE__ */ jsxs7("section", { className: `flex flex-col gap-2 text-xs ${className}`, "aria-label": "Provider effects", "data-image-provider-effects": "", children: [
|
|
1336
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1", children: [
|
|
1337
|
+
/* @__PURE__ */ jsx7("span", { className: "flex-1 font-semibold uppercase tracking-wider text-[11px] text-slate-200", children: "Effects" }),
|
|
1338
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: btn, disabled: !provider || !canFilter, "aria-pressed": browse === "filter", onClick: () => setBrowse(browse === "filter" ? null : "filter"), children: "Apply effect\u2026" }),
|
|
1339
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: btn, disabled: !provider, "aria-pressed": browse === "layer", onClick: () => setBrowse(browse === "layer" ? null : "layer"), children: "Effect layer\u2026" })
|
|
1340
|
+
] }),
|
|
1341
|
+
!provider && /* @__PURE__ */ jsx7("p", { className: "text-[11px] text-slate-400", children: "No effects provider is registered. Effects in the document are kept." }),
|
|
1342
|
+
browse === "filter" && layer && /* @__PURE__ */ jsx7(EffectsBrowser, { provider, uses: ["filter"], title: "Filters", onPick: (e) => (setBrowse(null), run(() => controller.applyEffectFilter(layer.id, e.id))) }),
|
|
1343
|
+
browse === "layer" && /* @__PURE__ */ jsx7(EffectsBrowser, { provider, uses: ["generator", "overlay", "title"], title: "Generators and overlays", onPick: (e) => (setBrowse(null), run(() => controller.addEffectLayer(e.id))) }),
|
|
1344
|
+
generator && layer && /* @__PURE__ */ jsxs7("div", { className: "space-y-1", "data-effect-part": "generator", children: [
|
|
1345
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1", children: [
|
|
1346
|
+
/* @__PURE__ */ jsx7("span", { className: "flex-1 font-medium text-slate-200", children: generator.name ?? generator.effect }),
|
|
1347
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: btn, title: "Keep the pixels as a plain layer", onClick: () => run(() => controller.rasterizeEffectLayer(layer.id)), children: "Rasterize" })
|
|
1348
|
+
] }),
|
|
1349
|
+
/* @__PURE__ */ jsx7(
|
|
1350
|
+
Controls,
|
|
1351
|
+
{
|
|
1352
|
+
provider,
|
|
1353
|
+
effect: generator.effect,
|
|
1354
|
+
name: generator.name,
|
|
1355
|
+
values: generator.values,
|
|
1356
|
+
onChange: (k, v, gesture) => run(() => controller.updateEffectLayer(layer.id, { values: { [k]: v } }, commit(gesture))),
|
|
1357
|
+
onPreset: (values) => run(() => controller.updateEffectLayer(layer.id, { values }))
|
|
1358
|
+
}
|
|
1359
|
+
)
|
|
1360
|
+
] }),
|
|
1361
|
+
filters.length > 0 && layer && /* @__PURE__ */ jsx7("ol", { className: "space-y-1", "data-effect-part": "filters", children: filters.map((f) => {
|
|
1362
|
+
const label = f.kind === "effect" ? f.name ?? f.effect : f.kind;
|
|
1363
|
+
const all = layer.smartFilters.filters;
|
|
1364
|
+
const index = all.indexOf(f);
|
|
1365
|
+
if (f.kind !== "effect") return null;
|
|
1366
|
+
return /* @__PURE__ */ jsxs7("li", { className: "rounded border border-slate-700 p-1", "data-smart-effect": f.id, children: [
|
|
1367
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1", children: [
|
|
1368
|
+
/* @__PURE__ */ jsx7("input", { type: "checkbox", checked: f.enabled, "aria-label": `${label} on`, onChange: (e) => {
|
|
1369
|
+
const enabled = e.currentTarget.checked;
|
|
1370
|
+
run(() => controller.updateEffectFilter(layer.id, f.id, { enabled }));
|
|
1371
|
+
} }),
|
|
1372
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "min-w-0 flex-1 truncate text-left text-slate-200", "aria-expanded": open === f.id, onClick: () => setOpen(open === f.id ? null : f.id), children: label }),
|
|
1373
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: btn, disabled: index === all.length - 1, "aria-label": "Move up", onClick: () => run(() => controller.updateEffectFilter(layer.id, f.id, { index: index + 1 })), children: "\u2191" }),
|
|
1374
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: btn, disabled: index === 0, "aria-label": "Move down", onClick: () => run(() => controller.updateEffectFilter(layer.id, f.id, { index: index - 1 })), children: "\u2193" }),
|
|
1375
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: btn, "aria-label": `Remove ${label}`, onClick: () => run(() => controller.removeSmartFilter(layer.id, f.id)), children: "\u2715" })
|
|
1376
|
+
] }),
|
|
1377
|
+
open === f.id && /* @__PURE__ */ jsxs7("div", { className: "mt-1 space-y-2", children: [
|
|
1378
|
+
/* @__PURE__ */ jsxs7("label", { className: "flex items-center gap-1", children: [
|
|
1379
|
+
/* @__PURE__ */ jsx7("span", { className: "w-14 text-[11px] text-slate-300", children: "Opacity" }),
|
|
1380
|
+
/* @__PURE__ */ jsx7(
|
|
1381
|
+
"input",
|
|
1382
|
+
{
|
|
1383
|
+
type: "range",
|
|
1384
|
+
min: 0,
|
|
1385
|
+
max: 1,
|
|
1386
|
+
step: 0.01,
|
|
1387
|
+
className: "flex-1",
|
|
1388
|
+
value: f.opacity,
|
|
1389
|
+
"aria-label": `${label} opacity`,
|
|
1390
|
+
onChange: (e) => {
|
|
1391
|
+
const opacity = Number(e.currentTarget.value);
|
|
1392
|
+
run(() => controller.updateEffectFilter(layer.id, f.id, { opacity }));
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
)
|
|
1396
|
+
] }),
|
|
1397
|
+
/* @__PURE__ */ jsx7(
|
|
1398
|
+
Controls,
|
|
1399
|
+
{
|
|
1400
|
+
provider,
|
|
1401
|
+
effect: f.effect,
|
|
1402
|
+
name: f.name,
|
|
1403
|
+
values: f.values,
|
|
1404
|
+
onChange: (k, v, gesture) => run(() => controller.updateEffectFilter(layer.id, f.id, { values: { [k]: v } }, commit(gesture))),
|
|
1405
|
+
onPreset: (values) => run(() => controller.updateEffectFilter(layer.id, f.id, { values }))
|
|
1406
|
+
}
|
|
1407
|
+
)
|
|
1408
|
+
] })
|
|
1409
|
+
] }, f.id);
|
|
1410
|
+
}) }),
|
|
1411
|
+
!layer && /* @__PURE__ */ jsx7("p", { className: "text-[11px] text-slate-400", children: "Select a layer to apply effects to it." }),
|
|
1412
|
+
message && /* @__PURE__ */ jsx7("p", { role: "alert", className: "text-[11px] text-rose-400", children: message })
|
|
1413
|
+
] });
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1267
1416
|
// src/image-editor/BrushOptionsBar.tsx
|
|
1268
|
-
import { useEffect as
|
|
1417
|
+
import { useEffect as useEffect7, useState as useState8 } from "react";
|
|
1269
1418
|
import {
|
|
1270
1419
|
BRUSH_OPTION_CONTROLS,
|
|
1271
1420
|
MIXER_MIXING_OPTIONS,
|
|
@@ -1279,14 +1428,22 @@ import {
|
|
|
1279
1428
|
rgbUnitToHex,
|
|
1280
1429
|
setRetouchChoice
|
|
1281
1430
|
} from "@pixerate/editor/image-editor";
|
|
1282
|
-
import {
|
|
1431
|
+
import { DEFAULT_PAINT_GRADIENT } from "@pixerate/editor/image-editor";
|
|
1432
|
+
|
|
1433
|
+
// src/image-editor/PaintGradientEditor.tsx
|
|
1434
|
+
import { PAINT_GRADIENT_KIT } from "@pixerate/editor/image-editor";
|
|
1435
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1436
|
+
var PaintGradientEditor = (props) => /* @__PURE__ */ jsx8(PaintGradientEditorView, { ...props, kit: PAINT_GRADIENT_KIT });
|
|
1437
|
+
|
|
1438
|
+
// src/image-editor/BrushOptionsBar.tsx
|
|
1439
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1283
1440
|
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"}`;
|
|
1284
1441
|
var BrushOptionsBar = ({ controller, className }) => {
|
|
1285
|
-
const [, setTick] =
|
|
1286
|
-
|
|
1287
|
-
const [error, setError] =
|
|
1442
|
+
const [, setTick] = useState8(0);
|
|
1443
|
+
useEffect7(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1444
|
+
const [error, setError] = useState8(null);
|
|
1288
1445
|
const state = controller.getState();
|
|
1289
|
-
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource } = state.paint;
|
|
1446
|
+
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource, paint } = state.paint;
|
|
1290
1447
|
const tool = state.activeTool;
|
|
1291
1448
|
const attempt = (fn) => {
|
|
1292
1449
|
try {
|
|
@@ -1296,8 +1453,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1296
1453
|
setError(err instanceof Error ? err.message : String(err));
|
|
1297
1454
|
}
|
|
1298
1455
|
};
|
|
1299
|
-
return /* @__PURE__ */
|
|
1300
|
-
/* @__PURE__ */
|
|
1456
|
+
return /* @__PURE__ */ jsxs8("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "brush-options", children: [
|
|
1457
|
+
/* @__PURE__ */ jsx9("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Paint tools", children: PAINT_TOOLS.map((t) => /* @__PURE__ */ jsx9(
|
|
1301
1458
|
"button",
|
|
1302
1459
|
{
|
|
1303
1460
|
type: "button",
|
|
@@ -1309,9 +1466,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1309
1466
|
},
|
|
1310
1467
|
t.id
|
|
1311
1468
|
)) }),
|
|
1312
|
-
/* @__PURE__ */
|
|
1313
|
-
/* @__PURE__ */
|
|
1314
|
-
/* @__PURE__ */
|
|
1469
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", role: "group", "aria-label": "Colours", children: [
|
|
1470
|
+
/* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1", children: [
|
|
1471
|
+
/* @__PURE__ */ jsx9(
|
|
1315
1472
|
"input",
|
|
1316
1473
|
{
|
|
1317
1474
|
type: "color",
|
|
@@ -1321,10 +1478,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1321
1478
|
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
1322
1479
|
}
|
|
1323
1480
|
),
|
|
1324
|
-
/* @__PURE__ */
|
|
1481
|
+
/* @__PURE__ */ jsx9("span", { className: "text-slate-400", children: "FG" })
|
|
1325
1482
|
] }),
|
|
1326
|
-
/* @__PURE__ */
|
|
1327
|
-
/* @__PURE__ */
|
|
1483
|
+
/* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1", children: [
|
|
1484
|
+
/* @__PURE__ */ jsx9(
|
|
1328
1485
|
"input",
|
|
1329
1486
|
{
|
|
1330
1487
|
type: "color",
|
|
@@ -1334,12 +1491,24 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1334
1491
|
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
1335
1492
|
}
|
|
1336
1493
|
),
|
|
1337
|
-
/* @__PURE__ */
|
|
1494
|
+
/* @__PURE__ */ jsx9("span", { className: "text-slate-400", children: "BG" })
|
|
1338
1495
|
] }),
|
|
1339
|
-
/* @__PURE__ */
|
|
1340
|
-
/* @__PURE__ */
|
|
1496
|
+
/* @__PURE__ */ jsx9("button", { type: "button", title: "Swap colours (X)", className: chip(false), onClick: () => controller.swapPaintColors(), children: "Swap" }),
|
|
1497
|
+
/* @__PURE__ */ jsx9("button", { type: "button", title: "Default colours (D)", className: chip(false), onClick: () => controller.resetPaintColors(), children: "Default" }),
|
|
1498
|
+
state.activeTool === "brush" && /* @__PURE__ */ jsx9(
|
|
1499
|
+
"button",
|
|
1500
|
+
{
|
|
1501
|
+
type: "button",
|
|
1502
|
+
"aria-pressed": paint.type === "gradient",
|
|
1503
|
+
title: "Gradient paint: the brush changes colour as the stroke goes",
|
|
1504
|
+
className: chip(paint.type === "gradient"),
|
|
1505
|
+
onClick: () => attempt(() => controller.setPaintOptions(paint.type === "gradient" ? { foreground } : { paint: DEFAULT_PAINT_GRADIENT })),
|
|
1506
|
+
children: "Gradient"
|
|
1507
|
+
}
|
|
1508
|
+
)
|
|
1341
1509
|
] }),
|
|
1342
|
-
|
|
1510
|
+
state.activeTool === "brush" && paint.type === "gradient" && /* @__PURE__ */ jsx9(PaintGradientEditor, { value: paint, colors: { paint: foreground, secondary: background }, onChange: (g) => attempt(() => controller.setPaintOptions({ paint: g })) }),
|
|
1511
|
+
BRUSH_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ jsx9(
|
|
1343
1512
|
ControlSlider,
|
|
1344
1513
|
{
|
|
1345
1514
|
spec,
|
|
@@ -1348,9 +1517,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1348
1517
|
},
|
|
1349
1518
|
spec.id
|
|
1350
1519
|
)),
|
|
1351
|
-
state.activeTool === "mixer" && /* @__PURE__ */
|
|
1352
|
-
/* @__PURE__ */
|
|
1353
|
-
/* @__PURE__ */
|
|
1520
|
+
state.activeTool === "mixer" && /* @__PURE__ */ jsxs8("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: [
|
|
1521
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
1522
|
+
/* @__PURE__ */ jsx9(
|
|
1354
1523
|
"span",
|
|
1355
1524
|
{
|
|
1356
1525
|
"aria-label": "Brush load",
|
|
@@ -1359,10 +1528,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1359
1528
|
style: { background: mixerLoad.reservoir ? rgbUnitToHex(mixerLoad.reservoir) : "transparent" }
|
|
1360
1529
|
}
|
|
1361
1530
|
),
|
|
1362
|
-
/* @__PURE__ */
|
|
1363
|
-
/* @__PURE__ */
|
|
1531
|
+
/* @__PURE__ */ jsx9("button", { type: "button", title: "Fill the reservoir with the foreground colour", className: chip(false), onClick: () => controller.loadMixerBrush(), children: "Load brush" }),
|
|
1532
|
+
/* @__PURE__ */ jsx9("button", { type: "button", title: "Empty the picked-up colour", className: chip(false), onClick: () => controller.cleanMixerBrush(), children: "Clean brush" })
|
|
1364
1533
|
] }),
|
|
1365
|
-
/* @__PURE__ */
|
|
1534
|
+
/* @__PURE__ */ jsx9("div", { className: "flex gap-1", role: "group", "aria-label": "Mixing", children: MIXER_MIXING_OPTIONS.map((m) => /* @__PURE__ */ jsx9(
|
|
1366
1535
|
"button",
|
|
1367
1536
|
{
|
|
1368
1537
|
type: "button",
|
|
@@ -1374,10 +1543,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1374
1543
|
},
|
|
1375
1544
|
m.id
|
|
1376
1545
|
)) }),
|
|
1377
|
-
MIXER_OPTION_CONTROLS.map((spec) => /* @__PURE__ */
|
|
1378
|
-
/* @__PURE__ */
|
|
1379
|
-
/* @__PURE__ */
|
|
1380
|
-
/* @__PURE__ */
|
|
1546
|
+
MIXER_OPTION_CONTROLS.map((spec) => /* @__PURE__ */ jsx9(ControlSlider, { spec, value: mixer[spec.id], onChange: (v) => controller.setPaintOptions({ mixer: { [spec.id]: v } }) }, spec.id)),
|
|
1547
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap gap-3 text-slate-300", children: [
|
|
1548
|
+
/* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
|
|
1549
|
+
/* @__PURE__ */ jsx9(
|
|
1381
1550
|
"input",
|
|
1382
1551
|
{
|
|
1383
1552
|
type: "checkbox",
|
|
@@ -1389,8 +1558,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1389
1558
|
),
|
|
1390
1559
|
"Load each stroke"
|
|
1391
1560
|
] }),
|
|
1392
|
-
/* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1561
|
+
/* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
|
|
1562
|
+
/* @__PURE__ */ jsx9(
|
|
1394
1563
|
"input",
|
|
1395
1564
|
{
|
|
1396
1565
|
type: "checkbox",
|
|
@@ -1404,14 +1573,14 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1404
1573
|
] })
|
|
1405
1574
|
] })
|
|
1406
1575
|
] }),
|
|
1407
|
-
isRetouchPaintTool(tool) && /* @__PURE__ */
|
|
1408
|
-
(tool === "clone" || tool === "heal") && /* @__PURE__ */
|
|
1409
|
-
/* @__PURE__ */
|
|
1410
|
-
cloneSource && /* @__PURE__ */
|
|
1576
|
+
isRetouchPaintTool(tool) && /* @__PURE__ */ jsxs8("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: [
|
|
1577
|
+
(tool === "clone" || tool === "heal") && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
1578
|
+
/* @__PURE__ */ jsx9("span", { className: "text-slate-400", "data-testid": "clone-source", children: cloneSourceLabel(controller) }),
|
|
1579
|
+
cloneSource && /* @__PURE__ */ jsx9("button", { type: "button", title: "Forget the source point", className: chip(false), onClick: () => controller.setCloneSource(null), children: "Clear source" })
|
|
1411
1580
|
] }),
|
|
1412
|
-
RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */
|
|
1413
|
-
/* @__PURE__ */
|
|
1414
|
-
choice.options.map((o) => /* @__PURE__ */
|
|
1581
|
+
RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": choice.label, children: [
|
|
1582
|
+
/* @__PURE__ */ jsx9("span", { className: "text-slate-400", children: choice.label }),
|
|
1583
|
+
choice.options.map((o) => /* @__PURE__ */ jsx9(
|
|
1415
1584
|
"button",
|
|
1416
1585
|
{
|
|
1417
1586
|
type: "button",
|
|
@@ -1424,9 +1593,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1424
1593
|
o.id
|
|
1425
1594
|
))
|
|
1426
1595
|
] }, choice.id)),
|
|
1427
|
-
RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */
|
|
1428
|
-
/* @__PURE__ */
|
|
1429
|
-
/* @__PURE__ */
|
|
1596
|
+
RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */ jsx9(ControlSlider, { spec, value: retouch[spec.id], onChange: (v) => controller.setPaintOptions({ retouch: { [spec.id]: v } }) }, spec.id)),
|
|
1597
|
+
/* @__PURE__ */ jsx9("div", { className: "flex flex-wrap gap-3 text-slate-300", children: RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => /* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
|
|
1598
|
+
/* @__PURE__ */ jsx9(
|
|
1430
1599
|
"input",
|
|
1431
1600
|
{
|
|
1432
1601
|
type: "checkbox",
|
|
@@ -1439,9 +1608,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1439
1608
|
t.label
|
|
1440
1609
|
] }, t.id)) })
|
|
1441
1610
|
] }),
|
|
1442
|
-
/* @__PURE__ */
|
|
1443
|
-
/* @__PURE__ */
|
|
1444
|
-
/* @__PURE__ */
|
|
1611
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap gap-3 text-slate-300", role: "group", "aria-label": "Pressure", children: [
|
|
1612
|
+
/* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
|
|
1613
|
+
/* @__PURE__ */ jsx9(
|
|
1445
1614
|
"input",
|
|
1446
1615
|
{
|
|
1447
1616
|
type: "checkbox",
|
|
@@ -1453,8 +1622,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1453
1622
|
),
|
|
1454
1623
|
"Pressure size"
|
|
1455
1624
|
] }),
|
|
1456
|
-
/* @__PURE__ */
|
|
1457
|
-
/* @__PURE__ */
|
|
1625
|
+
/* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
|
|
1626
|
+
/* @__PURE__ */ jsx9(
|
|
1458
1627
|
"input",
|
|
1459
1628
|
{
|
|
1460
1629
|
type: "checkbox",
|
|
@@ -1467,27 +1636,27 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1467
1636
|
"Pressure opacity"
|
|
1468
1637
|
] })
|
|
1469
1638
|
] }),
|
|
1470
|
-
/* @__PURE__ */
|
|
1471
|
-
/* @__PURE__ */
|
|
1472
|
-
/* @__PURE__ */
|
|
1639
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex gap-1", children: [
|
|
1640
|
+
/* @__PURE__ */ jsx9("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.fillPixels()), children: "Fill" }),
|
|
1641
|
+
/* @__PURE__ */ jsx9("button", { type: "button", className: chip(false), onClick: () => attempt(() => controller.clearPixels()), children: "Clear" })
|
|
1473
1642
|
] }),
|
|
1474
|
-
error && /* @__PURE__ */
|
|
1643
|
+
error && /* @__PURE__ */ jsx9("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1475
1644
|
] });
|
|
1476
1645
|
};
|
|
1477
1646
|
|
|
1478
1647
|
// src/image-editor/ColorProfilePanel.tsx
|
|
1479
|
-
import { useEffect as
|
|
1648
|
+
import { useEffect as useEffect8, useState as useState9 } from "react";
|
|
1480
1649
|
import { COLOR_MODE_OPTIONS, INTENT_OPTIONS, PROOF_PROFILE_OPTIONS, WORKING_SPACE_OPTIONS, colorPanelView } from "@pixerate/editor/image-editor";
|
|
1481
|
-
import { Fragment as Fragment2, jsx as
|
|
1650
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1482
1651
|
var chip2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white";
|
|
1483
1652
|
var select = "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200";
|
|
1484
1653
|
var ColorProfilePanel = ({ controller, className }) => {
|
|
1485
|
-
const [, setTick] =
|
|
1486
|
-
|
|
1487
|
-
const [target, setTarget] =
|
|
1488
|
-
const [intent, setIntent] =
|
|
1489
|
-
const [bpc, setBpc] =
|
|
1490
|
-
const [error, setError] =
|
|
1654
|
+
const [, setTick] = useState9(0);
|
|
1655
|
+
useEffect8(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1656
|
+
const [target, setTarget] = useState9("display-p3");
|
|
1657
|
+
const [intent, setIntent] = useState9("relative");
|
|
1658
|
+
const [bpc, setBpc] = useState9(true);
|
|
1659
|
+
const [error, setError] = useState9(null);
|
|
1491
1660
|
const view = colorPanelView(controller);
|
|
1492
1661
|
const attempt = (fn) => {
|
|
1493
1662
|
try {
|
|
@@ -1509,29 +1678,29 @@ var ColorProfilePanel = ({ controller, className }) => {
|
|
|
1509
1678
|
})
|
|
1510
1679
|
);
|
|
1511
1680
|
};
|
|
1512
|
-
return /* @__PURE__ */
|
|
1513
|
-
/* @__PURE__ */
|
|
1514
|
-
/* @__PURE__ */
|
|
1515
|
-
/* @__PURE__ */
|
|
1681
|
+
return /* @__PURE__ */ jsxs9("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "color-profile-panel", children: [
|
|
1682
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
1683
|
+
/* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: "Profile" }),
|
|
1684
|
+
/* @__PURE__ */ jsx10("span", { "data-testid": "color-profile-name", children: view.profileName })
|
|
1516
1685
|
] }),
|
|
1517
|
-
/* @__PURE__ */
|
|
1518
|
-
/* @__PURE__ */
|
|
1519
|
-
/* @__PURE__ */
|
|
1520
|
-
view.cmykProfileName && /* @__PURE__ */
|
|
1686
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Colour mode", children: [
|
|
1687
|
+
/* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: "Mode" }),
|
|
1688
|
+
/* @__PURE__ */ jsx10("select", { "aria-label": "Colour mode", className: select, value: view.mode, onChange: (e) => attempt(() => controller.setColorMode(e.target.value)), children: COLOR_MODE_OPTIONS.map((o) => /* @__PURE__ */ jsx10("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
|
|
1689
|
+
view.cmykProfileName && /* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: view.cmykProfileName })
|
|
1521
1690
|
] }),
|
|
1522
|
-
/* @__PURE__ */
|
|
1523
|
-
/* @__PURE__ */
|
|
1524
|
-
/* @__PURE__ */
|
|
1525
|
-
/* @__PURE__ */
|
|
1526
|
-
/* @__PURE__ */
|
|
1691
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Assign or convert", children: [
|
|
1692
|
+
/* @__PURE__ */ jsx10("select", { "aria-label": "Target profile", className: select, value: target, onChange: (e) => setTarget(e.target.value), children: WORKING_SPACE_OPTIONS.map((o) => /* @__PURE__ */ jsx10("option", { value: o.id, children: o.label }, o.id)) }),
|
|
1693
|
+
/* @__PURE__ */ jsx10("select", { "aria-label": "Rendering intent", className: select, value: intent, onChange: (e) => setIntent(e.target.value), children: INTENT_OPTIONS.map((o) => /* @__PURE__ */ jsx10("option", { value: o.id, title: o.title, children: o.label }, o.id)) }),
|
|
1694
|
+
/* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-1", children: [
|
|
1695
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", "aria-label": "Black point compensation", checked: bpc, onChange: (e) => setBpc(e.target.checked), className: "accent-indigo-500" }),
|
|
1527
1696
|
"BPC"
|
|
1528
1697
|
] }),
|
|
1529
|
-
/* @__PURE__ */
|
|
1530
|
-
/* @__PURE__ */
|
|
1698
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: chip2, title: "Edit \u203A Assign Profile: keep the numbers", onClick: () => attempt(() => controller.assignProfile(target)), children: "Assign" }),
|
|
1699
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: chip2, title: "Edit \u203A Convert to Profile: keep the look", onClick: () => attempt(() => controller.convertToProfile(target, { intent, bpc })), children: "Convert" })
|
|
1531
1700
|
] }),
|
|
1532
|
-
/* @__PURE__ */
|
|
1533
|
-
/* @__PURE__ */
|
|
1534
|
-
/* @__PURE__ */
|
|
1701
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-1", role: "group", "aria-label": "Proof setup", children: [
|
|
1702
|
+
/* @__PURE__ */ jsx10("span", { className: "text-slate-400", children: "Proof" }),
|
|
1703
|
+
/* @__PURE__ */ jsxs9(
|
|
1535
1704
|
"select",
|
|
1536
1705
|
{
|
|
1537
1706
|
"aria-label": "Proof profile",
|
|
@@ -1539,36 +1708,36 @@ var ColorProfilePanel = ({ controller, className }) => {
|
|
|
1539
1708
|
value: view.proof?.id ?? "",
|
|
1540
1709
|
onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
|
|
1541
1710
|
children: [
|
|
1542
|
-
/* @__PURE__ */
|
|
1543
|
-
PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */
|
|
1711
|
+
/* @__PURE__ */ jsx10("option", { value: "", children: "Off" }),
|
|
1712
|
+
PROOF_PROFILE_OPTIONS.map((o) => /* @__PURE__ */ jsx10("option", { value: o.id, children: o.label }, o.id))
|
|
1544
1713
|
]
|
|
1545
1714
|
}
|
|
1546
1715
|
),
|
|
1547
|
-
view.proof && /* @__PURE__ */
|
|
1548
|
-
/* @__PURE__ */
|
|
1549
|
-
/* @__PURE__ */
|
|
1550
|
-
/* @__PURE__ */
|
|
1716
|
+
view.proof && /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
1717
|
+
/* @__PURE__ */ jsx10("select", { "aria-label": "Proof intent", className: select, value: view.proof.intent, onChange: (e) => proofWith({ intent: e.target.value }), children: INTENT_OPTIONS.map((o) => /* @__PURE__ */ jsx10("option", { value: o.id, children: o.label }, o.id)) }),
|
|
1718
|
+
/* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-1", children: [
|
|
1719
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", "aria-label": "Simulate paper colour", checked: view.proof.simulatePaper, onChange: (e) => proofWith({ simulatePaper: e.target.checked }), className: "accent-indigo-500" }),
|
|
1551
1720
|
"Paper"
|
|
1552
1721
|
] }),
|
|
1553
|
-
/* @__PURE__ */
|
|
1554
|
-
/* @__PURE__ */
|
|
1722
|
+
/* @__PURE__ */ jsxs9("label", { className: "flex items-center gap-1", children: [
|
|
1723
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", "aria-label": "Gamut warning", checked: view.proof.gamutWarning, onChange: (e) => proofWith({ gamutWarning: e.target.checked }), className: "accent-indigo-500" }),
|
|
1555
1724
|
"Gamut warning"
|
|
1556
1725
|
] })
|
|
1557
1726
|
] })
|
|
1558
1727
|
] }),
|
|
1559
|
-
error && /* @__PURE__ */
|
|
1728
|
+
error && /* @__PURE__ */ jsx10("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1560
1729
|
] });
|
|
1561
1730
|
};
|
|
1562
1731
|
|
|
1563
1732
|
// src/image-editor/SelectionOptionsBar.tsx
|
|
1564
|
-
import { useState as
|
|
1733
|
+
import { useState as useState10 } from "react";
|
|
1565
1734
|
import {
|
|
1566
1735
|
SELECTION_MODES,
|
|
1567
1736
|
SELECTION_MODE_LABELS,
|
|
1568
1737
|
SELECTION_TOOLS,
|
|
1569
1738
|
describeSelection
|
|
1570
1739
|
} from "@pixerate/editor/image-editor";
|
|
1571
|
-
import { jsx as
|
|
1740
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1572
1741
|
var MODIFY_OPS = [
|
|
1573
1742
|
{ op: "grow", label: "Grow" },
|
|
1574
1743
|
{ op: "shrink", label: "Shrink" },
|
|
@@ -1576,7 +1745,7 @@ var MODIFY_OPS = [
|
|
|
1576
1745
|
{ op: "border", label: "Border" },
|
|
1577
1746
|
{ op: "smooth", label: "Smooth" }
|
|
1578
1747
|
];
|
|
1579
|
-
var
|
|
1748
|
+
var btn2 = (on) => `px-2 py-1 rounded-md border text-[11px] transition-colors ${on ? "bg-indigo-600 border-indigo-500 text-white" : "bg-slate-950 border-slate-800 text-slate-300 hover:text-white"}`;
|
|
1580
1749
|
var SelectionOptionsBar = ({
|
|
1581
1750
|
controller,
|
|
1582
1751
|
options,
|
|
@@ -1585,20 +1754,20 @@ var SelectionOptionsBar = ({
|
|
|
1585
1754
|
quickMask,
|
|
1586
1755
|
className = ""
|
|
1587
1756
|
}) => {
|
|
1588
|
-
const [radius, setRadius] =
|
|
1757
|
+
const [radius, setRadius] = useState10(2);
|
|
1589
1758
|
const set = (patch) => onOptionsChange({ ...options, ...patch });
|
|
1590
1759
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
1591
1760
|
const qm = quickMask ?? Boolean(controller.getState().quickMask);
|
|
1592
|
-
return /* @__PURE__ */
|
|
1593
|
-
/* @__PURE__ */
|
|
1594
|
-
/* @__PURE__ */
|
|
1595
|
-
options.tool === "wand" && /* @__PURE__ */
|
|
1596
|
-
/* @__PURE__ */
|
|
1597
|
-
/* @__PURE__ */
|
|
1598
|
-
/* @__PURE__ */
|
|
1599
|
-
/* @__PURE__ */
|
|
1761
|
+
return /* @__PURE__ */ jsxs10("div", { "data-testid": "selection-options-bar", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
1762
|
+
/* @__PURE__ */ jsx11("div", { role: "group", "aria-label": "Selection tool", className: "flex flex-wrap gap-1", children: SELECTION_TOOLS.map((t) => /* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": options.tool === t.id, className: btn2(options.tool === t.id), onClick: () => set({ tool: t.id }), children: t.label }, t.id)) }),
|
|
1763
|
+
/* @__PURE__ */ jsx11("div", { role: "group", "aria-label": "Selection mode", className: "flex flex-wrap gap-1", children: SELECTION_MODES.map((m) => /* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": options.mode === m, className: btn2(options.mode === m), onClick: () => set({ mode: m }), children: SELECTION_MODE_LABELS[m] }, m)) }),
|
|
1764
|
+
options.tool === "wand" && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-2", children: [
|
|
1765
|
+
/* @__PURE__ */ jsxs10("label", { className: "flex flex-col gap-1", children: [
|
|
1766
|
+
/* @__PURE__ */ jsxs10("span", { className: "flex justify-between text-slate-400", children: [
|
|
1767
|
+
/* @__PURE__ */ jsx11("span", { children: "Tolerance" }),
|
|
1768
|
+
/* @__PURE__ */ jsx11("span", { className: "font-mono", children: options.tolerance })
|
|
1600
1769
|
] }),
|
|
1601
|
-
/* @__PURE__ */
|
|
1770
|
+
/* @__PURE__ */ jsx11(
|
|
1602
1771
|
"input",
|
|
1603
1772
|
{
|
|
1604
1773
|
type: "range",
|
|
@@ -1612,17 +1781,17 @@ var SelectionOptionsBar = ({
|
|
|
1612
1781
|
}
|
|
1613
1782
|
)
|
|
1614
1783
|
] }),
|
|
1615
|
-
/* @__PURE__ */
|
|
1616
|
-
/* @__PURE__ */
|
|
1784
|
+
/* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1785
|
+
/* @__PURE__ */ jsx11("input", { type: "checkbox", checked: options.contiguous, onChange: (e) => set({ contiguous: e.target.checked }) }),
|
|
1617
1786
|
"Contiguous"
|
|
1618
1787
|
] }),
|
|
1619
|
-
/* @__PURE__ */
|
|
1620
|
-
/* @__PURE__ */
|
|
1788
|
+
/* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1789
|
+
/* @__PURE__ */ jsx11("input", { type: "checkbox", checked: options.sampleMerged, onChange: (e) => set({ sampleMerged: e.target.checked }) }),
|
|
1621
1790
|
"Sample adjusted image"
|
|
1622
1791
|
] }),
|
|
1623
|
-
/* @__PURE__ */
|
|
1792
|
+
/* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1624
1793
|
"Sample",
|
|
1625
|
-
/* @__PURE__ */
|
|
1794
|
+
/* @__PURE__ */ jsxs10(
|
|
1626
1795
|
"select",
|
|
1627
1796
|
{
|
|
1628
1797
|
"aria-label": "Sample from",
|
|
@@ -1630,27 +1799,27 @@ var SelectionOptionsBar = ({
|
|
|
1630
1799
|
onChange: (e) => set({ sample: e.target.value }),
|
|
1631
1800
|
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
1632
1801
|
children: [
|
|
1633
|
-
/* @__PURE__ */
|
|
1634
|
-
/* @__PURE__ */
|
|
1802
|
+
/* @__PURE__ */ jsx11("option", { value: "composite", children: "All layers" }),
|
|
1803
|
+
/* @__PURE__ */ jsx11("option", { value: "active-layer", children: "Active layer" })
|
|
1635
1804
|
]
|
|
1636
1805
|
}
|
|
1637
1806
|
)
|
|
1638
1807
|
] })
|
|
1639
1808
|
] }),
|
|
1640
|
-
/* @__PURE__ */
|
|
1641
|
-
/* @__PURE__ */
|
|
1809
|
+
/* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1810
|
+
/* @__PURE__ */ jsx11("input", { type: "checkbox", checked: options.antiAlias, onChange: (e) => set({ antiAlias: e.target.checked }) }),
|
|
1642
1811
|
"Anti-alias"
|
|
1643
1812
|
] }),
|
|
1644
|
-
/* @__PURE__ */
|
|
1645
|
-
/* @__PURE__ */
|
|
1646
|
-
/* @__PURE__ */
|
|
1647
|
-
/* @__PURE__ */
|
|
1648
|
-
/* @__PURE__ */
|
|
1813
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap gap-1", children: [
|
|
1814
|
+
/* @__PURE__ */ jsx11("button", { type: "button", className: btn2(false), onClick: () => controller.selectAll(), children: "Select All" }),
|
|
1815
|
+
/* @__PURE__ */ jsx11("button", { type: "button", className: btn2(false), disabled: !sel, onClick: () => controller.deselect(), children: "Deselect" }),
|
|
1816
|
+
/* @__PURE__ */ jsx11("button", { type: "button", className: btn2(false), onClick: () => controller.invertSelection(), children: "Inverse" }),
|
|
1817
|
+
/* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": qm, className: btn2(qm), onClick: () => controller.setQuickMask(!qm), children: "Quick Mask" })
|
|
1649
1818
|
] }),
|
|
1650
|
-
/* @__PURE__ */
|
|
1651
|
-
/* @__PURE__ */
|
|
1819
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-1", children: [
|
|
1820
|
+
/* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-1 text-slate-400", children: [
|
|
1652
1821
|
"Radius",
|
|
1653
|
-
/* @__PURE__ */
|
|
1822
|
+
/* @__PURE__ */ jsx11(
|
|
1654
1823
|
"input",
|
|
1655
1824
|
{
|
|
1656
1825
|
type: "number",
|
|
@@ -1664,29 +1833,29 @@ var SelectionOptionsBar = ({
|
|
|
1664
1833
|
}
|
|
1665
1834
|
)
|
|
1666
1835
|
] }),
|
|
1667
|
-
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */
|
|
1836
|
+
MODIFY_OPS.map(({ op, label }) => /* @__PURE__ */ jsx11("button", { type: "button", className: btn2(false), disabled: !sel, onClick: () => controller.modifySelection(op, radius), children: label }, op))
|
|
1668
1837
|
] }),
|
|
1669
|
-
/* @__PURE__ */
|
|
1838
|
+
/* @__PURE__ */ jsx11("p", { "data-testid": "selection-status", className: "text-slate-400", children: describeSelection(sel) })
|
|
1670
1839
|
] });
|
|
1671
1840
|
};
|
|
1672
1841
|
|
|
1673
1842
|
// src/image-editor/RefineEdgePanel.tsx
|
|
1674
|
-
import { useState as
|
|
1843
|
+
import { useState as useState11 } from "react";
|
|
1675
1844
|
import {
|
|
1676
1845
|
ADJUSTMENT_KINDS as ADJUSTMENT_KINDS2,
|
|
1677
1846
|
REFINE_EDGE_CONTROLS,
|
|
1678
1847
|
adjustmentKindLabel as adjustmentKindLabel2,
|
|
1679
1848
|
layerMaskFromSelection
|
|
1680
1849
|
} from "@pixerate/editor/image-editor";
|
|
1681
|
-
import { Fragment as Fragment3, jsx as
|
|
1850
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1682
1851
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
1683
1852
|
var button2 = "px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40";
|
|
1684
1853
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
1685
|
-
const [params, setParams] =
|
|
1686
|
-
const [busy, setBusy] =
|
|
1687
|
-
const [error, setError] =
|
|
1688
|
-
const [layerId, setLayerId] =
|
|
1689
|
-
const [newKind, setNewKind] =
|
|
1854
|
+
const [params, setParams] = useState11(DEFAULT_PARAMS);
|
|
1855
|
+
const [busy, setBusy] = useState11(false);
|
|
1856
|
+
const [error, setError] = useState11(null);
|
|
1857
|
+
const [layerId, setLayerId] = useState11("");
|
|
1858
|
+
const [newKind, setNewKind] = useState11("hueSaturation");
|
|
1690
1859
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
1691
1860
|
const list = layers ?? controller.getAdjustmentLayers();
|
|
1692
1861
|
const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
|
|
@@ -1701,17 +1870,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1701
1870
|
setBusy(false);
|
|
1702
1871
|
}
|
|
1703
1872
|
};
|
|
1704
|
-
return /* @__PURE__ */
|
|
1705
|
-
/* @__PURE__ */
|
|
1706
|
-
REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */
|
|
1707
|
-
/* @__PURE__ */
|
|
1708
|
-
/* @__PURE__ */
|
|
1709
|
-
/* @__PURE__ */
|
|
1873
|
+
return /* @__PURE__ */ jsxs11("div", { "data-testid": "refine-edge-panel", className: `flex flex-col gap-3 text-xs ${className}`, children: [
|
|
1874
|
+
/* @__PURE__ */ jsx12("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Refine Edge" }),
|
|
1875
|
+
REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */ jsxs11("label", { className: "flex flex-col gap-1", children: [
|
|
1876
|
+
/* @__PURE__ */ jsxs11("span", { className: "flex justify-between text-slate-400", children: [
|
|
1877
|
+
/* @__PURE__ */ jsx12("span", { children: c.label }),
|
|
1878
|
+
/* @__PURE__ */ jsxs11("span", { className: "font-mono", children: [
|
|
1710
1879
|
params[c.id],
|
|
1711
1880
|
c.unit
|
|
1712
1881
|
] })
|
|
1713
1882
|
] }),
|
|
1714
|
-
/* @__PURE__ */
|
|
1883
|
+
/* @__PURE__ */ jsx12(
|
|
1715
1884
|
"input",
|
|
1716
1885
|
{
|
|
1717
1886
|
type: "range",
|
|
@@ -1725,28 +1894,28 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1725
1894
|
}
|
|
1726
1895
|
)
|
|
1727
1896
|
] }, c.id)),
|
|
1728
|
-
/* @__PURE__ */
|
|
1729
|
-
/* @__PURE__ */
|
|
1897
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1898
|
+
/* @__PURE__ */ jsx12("input", { type: "checkbox", checked: params.smartRadius, onChange: (e) => setParams({ ...params, smartRadius: e.target.checked }) }),
|
|
1730
1899
|
"Smart Radius"
|
|
1731
1900
|
] }),
|
|
1732
|
-
/* @__PURE__ */
|
|
1733
|
-
/* @__PURE__ */
|
|
1734
|
-
/* @__PURE__ */
|
|
1901
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex gap-1", children: [
|
|
1902
|
+
/* @__PURE__ */ jsx12("button", { type: "button", className: button2, disabled: !sel || busy, onClick: refine, children: "Refine Edge" }),
|
|
1903
|
+
/* @__PURE__ */ jsx12("button", { type: "button", className: button2, onClick: () => setParams(DEFAULT_PARAMS), children: "Reset" })
|
|
1735
1904
|
] }),
|
|
1736
|
-
error && /* @__PURE__ */
|
|
1737
|
-
/* @__PURE__ */
|
|
1738
|
-
/* @__PURE__ */
|
|
1739
|
-
/* @__PURE__ */
|
|
1905
|
+
error && /* @__PURE__ */ jsx12("p", { role: "alert", className: "text-rose-400", children: error }),
|
|
1906
|
+
/* @__PURE__ */ jsx12("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2", children: "Layer Mask" }),
|
|
1907
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex gap-1 items-center", children: [
|
|
1908
|
+
/* @__PURE__ */ jsx12(
|
|
1740
1909
|
"select",
|
|
1741
1910
|
{
|
|
1742
1911
|
"aria-label": "New masked layer kind",
|
|
1743
1912
|
value: newKind,
|
|
1744
1913
|
onChange: (e) => setNewKind(e.target.value),
|
|
1745
1914
|
className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
1746
|
-
children: ADJUSTMENT_KINDS2.map((k) => /* @__PURE__ */
|
|
1915
|
+
children: ADJUSTMENT_KINDS2.map((k) => /* @__PURE__ */ jsx12("option", { value: k.kind, children: k.label }, k.kind))
|
|
1747
1916
|
}
|
|
1748
1917
|
),
|
|
1749
|
-
/* @__PURE__ */
|
|
1918
|
+
/* @__PURE__ */ jsx12(
|
|
1750
1919
|
"button",
|
|
1751
1920
|
{
|
|
1752
1921
|
type: "button",
|
|
@@ -1757,35 +1926,35 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1757
1926
|
}
|
|
1758
1927
|
)
|
|
1759
1928
|
] }),
|
|
1760
|
-
list.length > 0 && target && /* @__PURE__ */
|
|
1761
|
-
/* @__PURE__ */
|
|
1929
|
+
list.length > 0 && target && /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-2", children: [
|
|
1930
|
+
/* @__PURE__ */ jsx12(
|
|
1762
1931
|
"select",
|
|
1763
1932
|
{
|
|
1764
1933
|
"aria-label": "Mask layer",
|
|
1765
1934
|
value: target.id,
|
|
1766
1935
|
onChange: (e) => setLayerId(e.target.value),
|
|
1767
1936
|
className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
1768
|
-
children: list.map((l) => /* @__PURE__ */
|
|
1937
|
+
children: list.map((l) => /* @__PURE__ */ jsxs11("option", { value: l.id, children: [
|
|
1769
1938
|
l.name || adjustmentKindLabel2(l.kind),
|
|
1770
1939
|
l.mask ? " (masked)" : ""
|
|
1771
1940
|
] }, l.id))
|
|
1772
1941
|
}
|
|
1773
1942
|
),
|
|
1774
|
-
/* @__PURE__ */
|
|
1775
|
-
/* @__PURE__ */
|
|
1776
|
-
/* @__PURE__ */
|
|
1777
|
-
/* @__PURE__ */
|
|
1943
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap gap-1", children: [
|
|
1944
|
+
/* @__PURE__ */ jsx12("button", { type: "button", className: button2, disabled: !sel, onClick: () => controller.applySelectionAsLayerMask(target.id), children: "Mask with Selection" }),
|
|
1945
|
+
/* @__PURE__ */ jsx12("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.selectionFromLayerMask(target.id), children: "Load as Selection" }),
|
|
1946
|
+
/* @__PURE__ */ jsx12("button", { type: "button", className: button2, disabled: !target.mask, onClick: () => controller.setAdjustmentLayerMask(target.id, null), children: "Remove Mask" })
|
|
1778
1947
|
] }),
|
|
1779
|
-
target.mask && /* @__PURE__ */
|
|
1780
|
-
/* @__PURE__ */
|
|
1781
|
-
/* @__PURE__ */
|
|
1782
|
-
/* @__PURE__ */
|
|
1783
|
-
/* @__PURE__ */
|
|
1948
|
+
target.mask && /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
1949
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex flex-col gap-1", children: [
|
|
1950
|
+
/* @__PURE__ */ jsxs11("span", { className: "flex justify-between text-slate-400", children: [
|
|
1951
|
+
/* @__PURE__ */ jsx12("span", { children: "Density" }),
|
|
1952
|
+
/* @__PURE__ */ jsxs11("span", { className: "font-mono", children: [
|
|
1784
1953
|
Math.round((target.mask.density ?? 1) * 100),
|
|
1785
1954
|
"%"
|
|
1786
1955
|
] })
|
|
1787
1956
|
] }),
|
|
1788
|
-
/* @__PURE__ */
|
|
1957
|
+
/* @__PURE__ */ jsx12(
|
|
1789
1958
|
"input",
|
|
1790
1959
|
{
|
|
1791
1960
|
type: "range",
|
|
@@ -1799,15 +1968,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1799
1968
|
}
|
|
1800
1969
|
)
|
|
1801
1970
|
] }),
|
|
1802
|
-
/* @__PURE__ */
|
|
1803
|
-
/* @__PURE__ */
|
|
1804
|
-
/* @__PURE__ */
|
|
1805
|
-
/* @__PURE__ */
|
|
1971
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex flex-col gap-1", children: [
|
|
1972
|
+
/* @__PURE__ */ jsxs11("span", { className: "flex justify-between text-slate-400", children: [
|
|
1973
|
+
/* @__PURE__ */ jsx12("span", { children: "Mask Feather" }),
|
|
1974
|
+
/* @__PURE__ */ jsxs11("span", { className: "font-mono", children: [
|
|
1806
1975
|
target.mask.feather ?? 0,
|
|
1807
1976
|
"px"
|
|
1808
1977
|
] })
|
|
1809
1978
|
] }),
|
|
1810
|
-
/* @__PURE__ */
|
|
1979
|
+
/* @__PURE__ */ jsx12(
|
|
1811
1980
|
"input",
|
|
1812
1981
|
{
|
|
1813
1982
|
type: "range",
|
|
@@ -1827,14 +1996,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1827
1996
|
};
|
|
1828
1997
|
|
|
1829
1998
|
// src/image-editor/FreeTransformOptionsBar.tsx
|
|
1830
|
-
import { useEffect as
|
|
1999
|
+
import { useEffect as useEffect9, useState as useState12 } from "react";
|
|
1831
2000
|
import { FREE_TRANSFORM_FIELDS, FREE_TRANSFORM_MODE_OPTIONS, INTERPOLATIONS, TRANSFORM_ANCHORS, WARP_GRID_OPTIONS, WARP_STYLE_OPTIONS } from "@pixerate/editor/image-editor";
|
|
1832
|
-
import { jsx as
|
|
2001
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1833
2002
|
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"}`;
|
|
1834
2003
|
var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
|
|
1835
2004
|
var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
1836
|
-
const [, setTick] =
|
|
1837
|
-
|
|
2005
|
+
const [, setTick] = useState12(0);
|
|
2006
|
+
useEffect9(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
|
|
1838
2007
|
const bar = tool.bar();
|
|
1839
2008
|
if (!tool.active || !bar) return null;
|
|
1840
2009
|
const warp = tool.warpBar();
|
|
@@ -1846,17 +2015,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1846
2015
|
const v = Number(raw);
|
|
1847
2016
|
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
1848
2017
|
};
|
|
1849
|
-
return /* @__PURE__ */
|
|
1850
|
-
/* @__PURE__ */
|
|
1851
|
-
/* @__PURE__ */
|
|
1852
|
-
tool.mode === "warp" && /* @__PURE__ */
|
|
1853
|
-
/* @__PURE__ */
|
|
1854
|
-
/* @__PURE__ */
|
|
1855
|
-
/* @__PURE__ */
|
|
2018
|
+
return /* @__PURE__ */ jsxs12("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: [
|
|
2019
|
+
/* @__PURE__ */ jsx13("div", { className: "flex gap-1", role: "group", "aria-label": "Transform mode", children: FREE_TRANSFORM_MODE_OPTIONS.map((m) => /* @__PURE__ */ jsx13("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)) }),
|
|
2020
|
+
/* @__PURE__ */ jsx13("div", { className: "grid grid-cols-3 gap-px", role: "group", "aria-label": "Reference point", children: TRANSFORM_ANCHORS.map((a) => /* @__PURE__ */ jsx13("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)) }),
|
|
2021
|
+
tool.mode === "warp" && /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": "Warp options", children: [
|
|
2022
|
+
/* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
|
|
2023
|
+
/* @__PURE__ */ jsx13("span", { className: "text-slate-400", children: "Warp" }),
|
|
2024
|
+
/* @__PURE__ */ jsx13("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: WARP_STYLE_OPTIONS.map((o) => /* @__PURE__ */ jsx13("option", { value: o.id, children: o.label }, o.id)) })
|
|
1856
2025
|
] }),
|
|
1857
|
-
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */
|
|
1858
|
-
/* @__PURE__ */
|
|
1859
|
-
/* @__PURE__ */
|
|
2026
|
+
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
|
|
2027
|
+
/* @__PURE__ */ jsx13("span", { className: "text-slate-400", children: k === "bend" ? "Bend" : k === "horizontal" ? "H" : "V" }),
|
|
2028
|
+
/* @__PURE__ */ jsx13(
|
|
1860
2029
|
"input",
|
|
1861
2030
|
{
|
|
1862
2031
|
type: "number",
|
|
@@ -1877,9 +2046,9 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1877
2046
|
},
|
|
1878
2047
|
`${k}:${warp[k]}`
|
|
1879
2048
|
),
|
|
1880
|
-
/* @__PURE__ */
|
|
2049
|
+
/* @__PURE__ */ jsx13("span", { className: "text-slate-500", children: "%" })
|
|
1881
2050
|
] }, k)),
|
|
1882
|
-
/* @__PURE__ */
|
|
2051
|
+
/* @__PURE__ */ jsx13(
|
|
1883
2052
|
"button",
|
|
1884
2053
|
{
|
|
1885
2054
|
type: "button",
|
|
@@ -1891,9 +2060,9 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1891
2060
|
children: "Vertical"
|
|
1892
2061
|
}
|
|
1893
2062
|
),
|
|
1894
|
-
/* @__PURE__ */
|
|
1895
|
-
/* @__PURE__ */
|
|
1896
|
-
/* @__PURE__ */
|
|
2063
|
+
/* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
|
|
2064
|
+
/* @__PURE__ */ jsx13("span", { className: "text-slate-400", children: "Grid" }),
|
|
2065
|
+
/* @__PURE__ */ jsx13(
|
|
1897
2066
|
"select",
|
|
1898
2067
|
{
|
|
1899
2068
|
"aria-label": "Warp grid",
|
|
@@ -1903,14 +2072,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1903
2072
|
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
1904
2073
|
},
|
|
1905
2074
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1906
|
-
children: WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */
|
|
2075
|
+
children: WARP_GRID_OPTIONS.map((g) => /* @__PURE__ */ jsx13("option", { value: g.id, children: g.label }, g.id))
|
|
1907
2076
|
}
|
|
1908
2077
|
)
|
|
1909
2078
|
] })
|
|
1910
2079
|
] }),
|
|
1911
|
-
tool.mode !== "warp" && FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */
|
|
1912
|
-
/* @__PURE__ */
|
|
1913
|
-
/* @__PURE__ */
|
|
2080
|
+
tool.mode !== "warp" && FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", title: f.title, children: [
|
|
2081
|
+
/* @__PURE__ */ jsx13("span", { className: "text-slate-400", children: f.label }),
|
|
2082
|
+
/* @__PURE__ */ jsx13(
|
|
1914
2083
|
"input",
|
|
1915
2084
|
{
|
|
1916
2085
|
type: "number",
|
|
@@ -1930,8 +2099,8 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1930
2099
|
},
|
|
1931
2100
|
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
1932
2101
|
),
|
|
1933
|
-
/* @__PURE__ */
|
|
1934
|
-
f.id === "scaleX" && /* @__PURE__ */
|
|
2102
|
+
/* @__PURE__ */ jsx13("span", { className: "text-slate-500", children: f.unit }),
|
|
2103
|
+
f.id === "scaleX" && /* @__PURE__ */ jsx13(
|
|
1935
2104
|
"button",
|
|
1936
2105
|
{
|
|
1937
2106
|
type: "button",
|
|
@@ -1946,34 +2115,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1946
2115
|
}
|
|
1947
2116
|
)
|
|
1948
2117
|
] }, f.id)),
|
|
1949
|
-
/* @__PURE__ */
|
|
1950
|
-
/* @__PURE__ */
|
|
1951
|
-
/* @__PURE__ */
|
|
2118
|
+
/* @__PURE__ */ jsxs12("label", { className: "flex items-center gap-1", children: [
|
|
2119
|
+
/* @__PURE__ */ jsx13("span", { className: "text-slate-400", children: "Interpolation" }),
|
|
2120
|
+
/* @__PURE__ */ jsx13(
|
|
1952
2121
|
"select",
|
|
1953
2122
|
{
|
|
1954
2123
|
"aria-label": "Interpolation",
|
|
1955
2124
|
value: tool.interpolation,
|
|
1956
2125
|
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
1957
2126
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1958
|
-
children: INTERPOLATIONS.map((i) => /* @__PURE__ */
|
|
2127
|
+
children: INTERPOLATIONS.map((i) => /* @__PURE__ */ jsx13("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
1959
2128
|
}
|
|
1960
2129
|
)
|
|
1961
2130
|
] }),
|
|
1962
|
-
/* @__PURE__ */
|
|
1963
|
-
/* @__PURE__ */
|
|
1964
|
-
tool.error && /* @__PURE__ */
|
|
2131
|
+
/* @__PURE__ */ jsx13("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" }),
|
|
2132
|
+
/* @__PURE__ */ jsx13("button", { type: "button", title: "Cancel (Esc)", className: chip3(false), onClick: () => tool.cancel(), children: "Cancel" }),
|
|
2133
|
+
tool.error && /* @__PURE__ */ jsx13("span", { role: "alert", className: "text-rose-400", children: tool.error })
|
|
1965
2134
|
] });
|
|
1966
2135
|
};
|
|
1967
2136
|
|
|
1968
2137
|
// src/image-editor/ShapeOptionsBar.tsx
|
|
1969
|
-
import { useEffect as
|
|
2138
|
+
import { useEffect as useEffect10, useState as useState13 } from "react";
|
|
1970
2139
|
import { LIVE_SHAPE_KINDS, SHAPE_KIND_LABELS, applyShapeOptions } from "@pixerate/editor/image-editor";
|
|
1971
|
-
import { Fragment as Fragment4, jsx as
|
|
2140
|
+
import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1972
2141
|
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"}`;
|
|
1973
2142
|
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
1974
|
-
const [, setTick] =
|
|
1975
|
-
|
|
1976
|
-
const [error, setError] =
|
|
2143
|
+
const [, setTick] = useState13(0);
|
|
2144
|
+
useEffect10(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
2145
|
+
const [error, setError] = useState13(null);
|
|
1977
2146
|
const active = controller.getActiveLayer();
|
|
1978
2147
|
const shapeId = active?.type === "shape" ? active.id : null;
|
|
1979
2148
|
const set = (change) => {
|
|
@@ -1987,13 +2156,13 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
1987
2156
|
}
|
|
1988
2157
|
};
|
|
1989
2158
|
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
1990
|
-
return /* @__PURE__ */
|
|
1991
|
-
/* @__PURE__ */
|
|
1992
|
-
/* @__PURE__ */
|
|
1993
|
-
/* @__PURE__ */
|
|
1994
|
-
/* @__PURE__ */
|
|
2159
|
+
return /* @__PURE__ */ jsxs13("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "shape-options", children: [
|
|
2160
|
+
/* @__PURE__ */ jsx14("div", { className: "flex flex-wrap gap-1", role: "toolbar", "aria-label": "Shape kind", children: LIVE_SHAPE_KINDS.map((k) => /* @__PURE__ */ jsx14("button", { type: "button", "aria-pressed": options.kind === k, className: chip4(options.kind === k), onClick: () => onChange({ ...options, kind: k }), children: SHAPE_KIND_LABELS[k] }, k)) }),
|
|
2161
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
2162
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2163
|
+
/* @__PURE__ */ jsx14("input", { type: "checkbox", "aria-label": "Fill", checked: options.fill !== null, onChange: (e) => set({ fill: e.target.checked ? "#4f46e5" : null }) }),
|
|
1995
2164
|
"Fill",
|
|
1996
|
-
/* @__PURE__ */
|
|
2165
|
+
/* @__PURE__ */ jsx14(
|
|
1997
2166
|
"input",
|
|
1998
2167
|
{
|
|
1999
2168
|
type: "color",
|
|
@@ -2005,10 +2174,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2005
2174
|
}
|
|
2006
2175
|
)
|
|
2007
2176
|
] }),
|
|
2008
|
-
/* @__PURE__ */
|
|
2009
|
-
/* @__PURE__ */
|
|
2177
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2178
|
+
/* @__PURE__ */ jsx14("input", { type: "checkbox", "aria-label": "Stroke", checked: options.stroke !== null, onChange: (e) => set({ stroke: e.target.checked ? "#000000" : null }) }),
|
|
2010
2179
|
"Stroke",
|
|
2011
|
-
/* @__PURE__ */
|
|
2180
|
+
/* @__PURE__ */ jsx14(
|
|
2012
2181
|
"input",
|
|
2013
2182
|
{
|
|
2014
2183
|
type: "color",
|
|
@@ -2020,9 +2189,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2020
2189
|
}
|
|
2021
2190
|
)
|
|
2022
2191
|
] }),
|
|
2023
|
-
/* @__PURE__ */
|
|
2192
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2024
2193
|
"Width",
|
|
2025
|
-
/* @__PURE__ */
|
|
2194
|
+
/* @__PURE__ */ jsx14(
|
|
2026
2195
|
"input",
|
|
2027
2196
|
{
|
|
2028
2197
|
type: "number",
|
|
@@ -2036,23 +2205,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2036
2205
|
)
|
|
2037
2206
|
] })
|
|
2038
2207
|
] }),
|
|
2039
|
-
/* @__PURE__ */
|
|
2040
|
-
options.kind === "rect" && /* @__PURE__ */
|
|
2208
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
2209
|
+
options.kind === "rect" && /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2041
2210
|
"Radius",
|
|
2042
|
-
/* @__PURE__ */
|
|
2211
|
+
/* @__PURE__ */ jsx14("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" })
|
|
2043
2212
|
] }),
|
|
2044
|
-
options.kind === "polygon" && /* @__PURE__ */
|
|
2213
|
+
options.kind === "polygon" && /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2045
2214
|
"Sides",
|
|
2046
|
-
/* @__PURE__ */
|
|
2215
|
+
/* @__PURE__ */ jsx14("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" })
|
|
2047
2216
|
] }),
|
|
2048
|
-
options.kind === "star" && /* @__PURE__ */
|
|
2049
|
-
/* @__PURE__ */
|
|
2217
|
+
options.kind === "star" && /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
2218
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2050
2219
|
"Points",
|
|
2051
|
-
/* @__PURE__ */
|
|
2220
|
+
/* @__PURE__ */ jsx14("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" })
|
|
2052
2221
|
] }),
|
|
2053
|
-
/* @__PURE__ */
|
|
2222
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2054
2223
|
"Inner",
|
|
2055
|
-
/* @__PURE__ */
|
|
2224
|
+
/* @__PURE__ */ jsx14(
|
|
2056
2225
|
"input",
|
|
2057
2226
|
{
|
|
2058
2227
|
type: "range",
|
|
@@ -2067,33 +2236,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2067
2236
|
)
|
|
2068
2237
|
] })
|
|
2069
2238
|
] }),
|
|
2070
|
-
options.kind === "line" && /* @__PURE__ */
|
|
2071
|
-
/* @__PURE__ */
|
|
2239
|
+
options.kind === "line" && /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
2240
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2072
2241
|
"Weight",
|
|
2073
|
-
/* @__PURE__ */
|
|
2242
|
+
/* @__PURE__ */ jsx14("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" })
|
|
2074
2243
|
] }),
|
|
2075
|
-
/* @__PURE__ */
|
|
2076
|
-
/* @__PURE__ */
|
|
2244
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2245
|
+
/* @__PURE__ */ jsx14("input", { type: "checkbox", "aria-label": "Arrowhead", checked: options.arrow, onChange: (e) => set({ arrow: e.target.checked }) }),
|
|
2077
2246
|
"Arrowhead"
|
|
2078
2247
|
] })
|
|
2079
2248
|
] })
|
|
2080
2249
|
] }),
|
|
2081
|
-
/* @__PURE__ */
|
|
2082
|
-
error && /* @__PURE__ */
|
|
2250
|
+
/* @__PURE__ */ jsx14("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." }),
|
|
2251
|
+
error && /* @__PURE__ */ jsx14("p", { role: "alert", className: "text-rose-400", children: error })
|
|
2083
2252
|
] });
|
|
2084
2253
|
};
|
|
2085
2254
|
|
|
2086
2255
|
// src/image-editor/TypeOptionsBar.tsx
|
|
2087
|
-
import { useEffect as
|
|
2256
|
+
import { useEffect as useEffect11, useState as useState14 } from "react";
|
|
2088
2257
|
import { TEXT_ALIGNS } from "@pixerate/editor/image-editor";
|
|
2089
|
-
import { jsx as
|
|
2258
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2090
2259
|
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"}`;
|
|
2091
2260
|
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
2092
2261
|
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
2093
|
-
const [, setTick] =
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
const [error, setError] =
|
|
2262
|
+
const [, setTick] = useState14(0);
|
|
2263
|
+
useEffect11(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
2264
|
+
useEffect11(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);
|
|
2265
|
+
const [error, setError] = useState14(null);
|
|
2097
2266
|
const active = controller.getActiveLayer();
|
|
2098
2267
|
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
2099
2268
|
const here = session?.alive ? session.styleHere() : {};
|
|
@@ -2125,11 +2294,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2125
2294
|
setError(e instanceof Error ? e.message : String(e));
|
|
2126
2295
|
}
|
|
2127
2296
|
};
|
|
2128
|
-
return /* @__PURE__ */
|
|
2129
|
-
/* @__PURE__ */
|
|
2130
|
-
/* @__PURE__ */
|
|
2297
|
+
return /* @__PURE__ */ jsxs14("div", { className: `flex flex-col gap-2 text-xs text-slate-200 ${className ?? ""}`, "data-testid": "type-options", children: [
|
|
2298
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2299
|
+
/* @__PURE__ */ jsxs14("label", { className: "flex items-center gap-1", children: [
|
|
2131
2300
|
"Font",
|
|
2132
|
-
/* @__PURE__ */
|
|
2301
|
+
/* @__PURE__ */ jsx15(
|
|
2133
2302
|
"input",
|
|
2134
2303
|
{
|
|
2135
2304
|
list: "pixerate-type-fonts",
|
|
@@ -2139,11 +2308,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2139
2308
|
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
2140
2309
|
}
|
|
2141
2310
|
),
|
|
2142
|
-
/* @__PURE__ */
|
|
2311
|
+
/* @__PURE__ */ jsx15("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ jsx15("option", { value: f }, f)) })
|
|
2143
2312
|
] }),
|
|
2144
|
-
/* @__PURE__ */
|
|
2313
|
+
/* @__PURE__ */ jsxs14("label", { className: "flex items-center gap-1", children: [
|
|
2145
2314
|
"Size",
|
|
2146
|
-
/* @__PURE__ */
|
|
2315
|
+
/* @__PURE__ */ jsx15(
|
|
2147
2316
|
"input",
|
|
2148
2317
|
{
|
|
2149
2318
|
type: "number",
|
|
@@ -2156,24 +2325,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2156
2325
|
}
|
|
2157
2326
|
)
|
|
2158
2327
|
] }),
|
|
2159
|
-
/* @__PURE__ */
|
|
2160
|
-
/* @__PURE__ */
|
|
2161
|
-
/* @__PURE__ */
|
|
2328
|
+
/* @__PURE__ */ jsx15("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" }),
|
|
2329
|
+
/* @__PURE__ */ jsx15("button", { type: "button", "aria-pressed": shown.italic, className: `${chip5(shown.italic)} italic`, onClick: () => style({ italic: !shown.italic }), children: "I" }),
|
|
2330
|
+
/* @__PURE__ */ jsx15("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" })
|
|
2162
2331
|
] }),
|
|
2163
|
-
/* @__PURE__ */
|
|
2164
|
-
/* @__PURE__ */
|
|
2165
|
-
missing.length > 0 && /* @__PURE__ */
|
|
2332
|
+
/* @__PURE__ */ jsx15("div", { className: "flex gap-1", role: "toolbar", "aria-label": "Alignment", children: TEXT_ALIGNS.map((a) => /* @__PURE__ */ jsx15("button", { type: "button", "aria-pressed": options.align === a, className: chip5(options.align === a), onClick: () => style({ align: a }), children: ALIGN_LABELS[a] }, a)) }),
|
|
2333
|
+
/* @__PURE__ */ jsx15("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." }),
|
|
2334
|
+
missing.length > 0 && /* @__PURE__ */ jsxs14("p", { role: "status", className: "text-amber-400", "data-testid": "type-missing-fonts", children: [
|
|
2166
2335
|
"Missing ",
|
|
2167
2336
|
missing.length === 1 ? "font" : "fonts",
|
|
2168
2337
|
": ",
|
|
2169
2338
|
missing.join(", ")
|
|
2170
2339
|
] }),
|
|
2171
|
-
error && /* @__PURE__ */
|
|
2340
|
+
error && /* @__PURE__ */ jsx15("p", { role: "alert", className: "text-rose-400", children: error })
|
|
2172
2341
|
] });
|
|
2173
2342
|
};
|
|
2174
2343
|
|
|
2175
2344
|
// src/image-editor/ImageEditor.tsx
|
|
2176
|
-
import { Fragment as Fragment5, jsx as
|
|
2345
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2177
2346
|
var ImageEditor = ({
|
|
2178
2347
|
editor: externalEditor,
|
|
2179
2348
|
src,
|
|
@@ -2183,17 +2352,22 @@ var ImageEditor = ({
|
|
|
2183
2352
|
exportOptions,
|
|
2184
2353
|
onInpaint,
|
|
2185
2354
|
onRemoveBackground,
|
|
2186
|
-
aiHooks
|
|
2355
|
+
aiHooks,
|
|
2356
|
+
effects
|
|
2187
2357
|
}) => {
|
|
2188
2358
|
const internalEditor = useImageEditor({ image: src });
|
|
2189
2359
|
const editor = externalEditor || internalEditor;
|
|
2190
2360
|
const { state, controller } = editor;
|
|
2361
|
+
useEffects(controller, effects);
|
|
2362
|
+
const effectsShown = !!controller.effectsProvider || state.layers.some(function has(l) {
|
|
2363
|
+
return l.type === "pixel" && !!l.generator || l.type === "smart" && !!l.smartFilters?.filters.some((f) => f.kind === "effect") || l.type === "group" && l.children.some(has);
|
|
2364
|
+
});
|
|
2191
2365
|
const legacyProcess = normalizeProcessVersion(state.adjustments.process) < LATEST_PROCESS_VERSION;
|
|
2192
2366
|
const canvasRef = useRef5(null);
|
|
2193
2367
|
const containerRef = useRef5(null);
|
|
2194
|
-
const [activeTab, setActiveTab] =
|
|
2195
|
-
const [activeCropRatio, setActiveCropRatio] =
|
|
2196
|
-
const [selectionOptions, setSelectionOptions] =
|
|
2368
|
+
const [activeTab, setActiveTab] = useState15("crop");
|
|
2369
|
+
const [activeCropRatio, setActiveCropRatio] = useState15(null);
|
|
2370
|
+
const [selectionOptions, setSelectionOptions] = useState15(DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
2197
2371
|
const selectionOptionsRef = useRef5(selectionOptions);
|
|
2198
2372
|
selectionOptionsRef.current = selectionOptions;
|
|
2199
2373
|
const selectionGestureRef = useRef5(null);
|
|
@@ -2201,7 +2375,7 @@ var ImageEditor = ({
|
|
|
2201
2375
|
selectionGestureRef.current = new SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
2202
2376
|
}
|
|
2203
2377
|
const selectionDraftRef = useRef5(null);
|
|
2204
|
-
const [selectionError, setSelectionError] =
|
|
2378
|
+
const [selectionError, setSelectionError] = useState15(null);
|
|
2205
2379
|
const paintGestureRef = useRef5(null);
|
|
2206
2380
|
const paintControllerRef = useRef5(controller);
|
|
2207
2381
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
@@ -2209,7 +2383,7 @@ var ImageEditor = ({
|
|
|
2209
2383
|
paintControllerRef.current = controller;
|
|
2210
2384
|
}
|
|
2211
2385
|
const brushCursorRef = useRef5(null);
|
|
2212
|
-
const [paintError, setPaintError] =
|
|
2386
|
+
const [paintError, setPaintError] = useState15(null);
|
|
2213
2387
|
const transformToolRef = useRef5(null);
|
|
2214
2388
|
const transformControllerRef = useRef5(controller);
|
|
2215
2389
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
@@ -2220,12 +2394,12 @@ var ImageEditor = ({
|
|
|
2220
2394
|
transformControllerRef.current = controller;
|
|
2221
2395
|
}
|
|
2222
2396
|
const transformTool = transformToolRef.current;
|
|
2223
|
-
const [, setTransformTick] =
|
|
2224
|
-
const [transformCursor, setTransformCursor] =
|
|
2225
|
-
const [shapeOptions, setShapeOptions] =
|
|
2397
|
+
const [, setTransformTick] = useState15(0);
|
|
2398
|
+
const [transformCursor, setTransformCursor] = useState15("default");
|
|
2399
|
+
const [shapeOptions, setShapeOptions] = useState15(DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
2226
2400
|
const shapeOptionsRef = useRef5(shapeOptions);
|
|
2227
2401
|
shapeOptionsRef.current = shapeOptions;
|
|
2228
|
-
const [typeOptions, setTypeOptions] =
|
|
2402
|
+
const [typeOptions, setTypeOptions] = useState15(DEFAULT_TYPE_TOOL_OPTIONS);
|
|
2229
2403
|
const typeOptionsRef = useRef5(typeOptions);
|
|
2230
2404
|
typeOptionsRef.current = typeOptions;
|
|
2231
2405
|
const shapeGestureRef = useRef5(null);
|
|
@@ -2238,15 +2412,15 @@ var ImageEditor = ({
|
|
|
2238
2412
|
shapeTypeControllerRef.current = controller;
|
|
2239
2413
|
}
|
|
2240
2414
|
const typeInputRef = useRef5(null);
|
|
2241
|
-
const [typeSession, setTypeSession] =
|
|
2242
|
-
const [shapeTypeError, setShapeTypeError] =
|
|
2243
|
-
const [inpaintPrompt, setInpaintPrompt] =
|
|
2244
|
-
const [inpaintMaskMode, setInpaintMaskMode] =
|
|
2245
|
-
const [isRemovingBg, setIsRemovingBg] =
|
|
2246
|
-
const [isInpainting, setIsInpainting] =
|
|
2247
|
-
const [aiError, setAiError] =
|
|
2248
|
-
const [aiSuccess, setAiSuccess] =
|
|
2249
|
-
const [aiTarget, setAiTarget] =
|
|
2415
|
+
const [typeSession, setTypeSession] = useState15(typeToolRef.current.session);
|
|
2416
|
+
const [shapeTypeError, setShapeTypeError] = useState15(null);
|
|
2417
|
+
const [inpaintPrompt, setInpaintPrompt] = useState15("");
|
|
2418
|
+
const [inpaintMaskMode, setInpaintMaskMode] = useState15("annotations");
|
|
2419
|
+
const [isRemovingBg, setIsRemovingBg] = useState15(false);
|
|
2420
|
+
const [isInpainting, setIsInpainting] = useState15(false);
|
|
2421
|
+
const [aiError, setAiError] = useState15(null);
|
|
2422
|
+
const [aiSuccess, setAiSuccess] = useState15(null);
|
|
2423
|
+
const [aiTarget, setAiTarget] = useState15("auto");
|
|
2250
2424
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
2251
2425
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
2252
2426
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -2309,10 +2483,10 @@ var ImageEditor = ({
|
|
|
2309
2483
|
setIsInpainting(false);
|
|
2310
2484
|
}
|
|
2311
2485
|
};
|
|
2312
|
-
const [activeColor, setActiveColor] =
|
|
2313
|
-
const [strokeWidth, setStrokeWidth] =
|
|
2314
|
-
const [fontSize, setFontSize] =
|
|
2315
|
-
const [textInput, setTextInput] =
|
|
2486
|
+
const [activeColor, setActiveColor] = useState15("#ef4444");
|
|
2487
|
+
const [strokeWidth, setStrokeWidth] = useState15(3);
|
|
2488
|
+
const [fontSize, setFontSize] = useState15(24);
|
|
2489
|
+
const [textInput, setTextInput] = useState15("");
|
|
2316
2490
|
const draftAnnotationRef = useRef5(null);
|
|
2317
2491
|
const draftCropRef = useRef5(null);
|
|
2318
2492
|
const cropDragInfoRef = useRef5(null);
|
|
@@ -2343,8 +2517,8 @@ var ImageEditor = ({
|
|
|
2343
2517
|
},
|
|
2344
2518
|
[controller, activeTab, transformTool]
|
|
2345
2519
|
);
|
|
2346
|
-
|
|
2347
|
-
|
|
2520
|
+
useEffect12(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
2521
|
+
useEffect12(() => {
|
|
2348
2522
|
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
2349
2523
|
if (typeToolRef.current?.session) {
|
|
2350
2524
|
typeToolRef.current.finish();
|
|
@@ -2379,7 +2553,7 @@ var ImageEditor = ({
|
|
|
2379
2553
|
el.value = "";
|
|
2380
2554
|
}
|
|
2381
2555
|
};
|
|
2382
|
-
|
|
2556
|
+
useEffect12(() => transformTool.subscribe(() => {
|
|
2383
2557
|
setTransformTick((n) => n + 1);
|
|
2384
2558
|
void renderCanvas();
|
|
2385
2559
|
}), [transformTool, renderCanvas]);
|
|
@@ -2422,7 +2596,7 @@ var ImageEditor = ({
|
|
|
2422
2596
|
transformTool.up();
|
|
2423
2597
|
return true;
|
|
2424
2598
|
};
|
|
2425
|
-
|
|
2599
|
+
useEffect12(() => {
|
|
2426
2600
|
if (typeof window === "undefined") return;
|
|
2427
2601
|
const onKey = (e) => {
|
|
2428
2602
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -2430,7 +2604,7 @@ var ImageEditor = ({
|
|
|
2430
2604
|
window.addEventListener("keydown", onKey);
|
|
2431
2605
|
return () => window.removeEventListener("keydown", onKey);
|
|
2432
2606
|
}, [transformTool]);
|
|
2433
|
-
|
|
2607
|
+
useEffect12(() => {
|
|
2434
2608
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
2435
2609
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
2436
2610
|
const animId = raf(() => {
|
|
@@ -2438,12 +2612,12 @@ var ImageEditor = ({
|
|
|
2438
2612
|
});
|
|
2439
2613
|
return () => caf(animId);
|
|
2440
2614
|
}, [renderCanvas, state]);
|
|
2441
|
-
|
|
2615
|
+
useEffect12(() => {
|
|
2442
2616
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
2443
2617
|
editor.setTool("crop");
|
|
2444
2618
|
}
|
|
2445
2619
|
}, [activeTab, editor]);
|
|
2446
|
-
|
|
2620
|
+
useEffect12(() => {
|
|
2447
2621
|
const container = containerRef.current;
|
|
2448
2622
|
if (!container) return;
|
|
2449
2623
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -2511,7 +2685,7 @@ var ImageEditor = ({
|
|
|
2511
2685
|
if (g.error) setPaintError(g.error);
|
|
2512
2686
|
}
|
|
2513
2687
|
};
|
|
2514
|
-
|
|
2688
|
+
useEffect12(() => {
|
|
2515
2689
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
2516
2690
|
const onKey = (e) => {
|
|
2517
2691
|
if (handlePaintShortcut(controller, e)) e.preventDefault();
|
|
@@ -2906,15 +3080,15 @@ var ImageEditor = ({
|
|
|
2906
3080
|
link.click();
|
|
2907
3081
|
}
|
|
2908
3082
|
};
|
|
2909
|
-
return /* @__PURE__ */
|
|
3083
|
+
return /* @__PURE__ */ jsxs15(
|
|
2910
3084
|
"div",
|
|
2911
3085
|
{
|
|
2912
3086
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
2913
3087
|
style,
|
|
2914
3088
|
children: [
|
|
2915
|
-
/* @__PURE__ */
|
|
2916
|
-
/* @__PURE__ */
|
|
2917
|
-
/* @__PURE__ */
|
|
3089
|
+
/* @__PURE__ */ jsxs15("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: [
|
|
3090
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs", children: [
|
|
3091
|
+
/* @__PURE__ */ jsx16(
|
|
2918
3092
|
"button",
|
|
2919
3093
|
{
|
|
2920
3094
|
type: "button",
|
|
@@ -2926,7 +3100,7 @@ var ImageEditor = ({
|
|
|
2926
3100
|
children: "Transform & Crop"
|
|
2927
3101
|
}
|
|
2928
3102
|
),
|
|
2929
|
-
/* @__PURE__ */
|
|
3103
|
+
/* @__PURE__ */ jsx16(
|
|
2930
3104
|
"button",
|
|
2931
3105
|
{
|
|
2932
3106
|
type: "button",
|
|
@@ -2938,7 +3112,7 @@ var ImageEditor = ({
|
|
|
2938
3112
|
children: "Adjustments"
|
|
2939
3113
|
}
|
|
2940
3114
|
),
|
|
2941
|
-
/* @__PURE__ */
|
|
3115
|
+
/* @__PURE__ */ jsx16(
|
|
2942
3116
|
"button",
|
|
2943
3117
|
{
|
|
2944
3118
|
type: "button",
|
|
@@ -2950,7 +3124,7 @@ var ImageEditor = ({
|
|
|
2950
3124
|
children: "Layers"
|
|
2951
3125
|
}
|
|
2952
3126
|
),
|
|
2953
|
-
/* @__PURE__ */
|
|
3127
|
+
/* @__PURE__ */ jsx16(
|
|
2954
3128
|
"button",
|
|
2955
3129
|
{
|
|
2956
3130
|
type: "button",
|
|
@@ -2962,7 +3136,7 @@ var ImageEditor = ({
|
|
|
2962
3136
|
children: "Paint"
|
|
2963
3137
|
}
|
|
2964
3138
|
),
|
|
2965
|
-
/* @__PURE__ */
|
|
3139
|
+
/* @__PURE__ */ jsx16(
|
|
2966
3140
|
"button",
|
|
2967
3141
|
{
|
|
2968
3142
|
type: "button",
|
|
@@ -2974,7 +3148,7 @@ var ImageEditor = ({
|
|
|
2974
3148
|
children: "Select & Mask"
|
|
2975
3149
|
}
|
|
2976
3150
|
),
|
|
2977
|
-
/* @__PURE__ */
|
|
3151
|
+
/* @__PURE__ */ jsx16(
|
|
2978
3152
|
"button",
|
|
2979
3153
|
{
|
|
2980
3154
|
type: "button",
|
|
@@ -2986,7 +3160,7 @@ var ImageEditor = ({
|
|
|
2986
3160
|
children: "Annotations"
|
|
2987
3161
|
}
|
|
2988
3162
|
),
|
|
2989
|
-
/* @__PURE__ */
|
|
3163
|
+
/* @__PURE__ */ jsx16(
|
|
2990
3164
|
"button",
|
|
2991
3165
|
{
|
|
2992
3166
|
type: "button",
|
|
@@ -2998,7 +3172,7 @@ var ImageEditor = ({
|
|
|
2998
3172
|
children: "Depth Mask"
|
|
2999
3173
|
}
|
|
3000
3174
|
),
|
|
3001
|
-
/* @__PURE__ */
|
|
3175
|
+
/* @__PURE__ */ jsxs15(
|
|
3002
3176
|
"button",
|
|
3003
3177
|
{
|
|
3004
3178
|
type: "button",
|
|
@@ -3008,14 +3182,14 @@ var ImageEditor = ({
|
|
|
3008
3182
|
},
|
|
3009
3183
|
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"}`,
|
|
3010
3184
|
children: [
|
|
3011
|
-
/* @__PURE__ */
|
|
3185
|
+
/* @__PURE__ */ jsx16("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx16("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" }) }),
|
|
3012
3186
|
"AI Tools"
|
|
3013
3187
|
]
|
|
3014
3188
|
}
|
|
3015
3189
|
)
|
|
3016
3190
|
] }),
|
|
3017
|
-
/* @__PURE__ */
|
|
3018
|
-
/* @__PURE__ */
|
|
3191
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
3192
|
+
/* @__PURE__ */ jsx16(
|
|
3019
3193
|
"button",
|
|
3020
3194
|
{
|
|
3021
3195
|
type: "button",
|
|
@@ -3026,7 +3200,7 @@ var ImageEditor = ({
|
|
|
3026
3200
|
children: "\u21A9"
|
|
3027
3201
|
}
|
|
3028
3202
|
),
|
|
3029
|
-
/* @__PURE__ */
|
|
3203
|
+
/* @__PURE__ */ jsx16(
|
|
3030
3204
|
"button",
|
|
3031
3205
|
{
|
|
3032
3206
|
type: "button",
|
|
@@ -3037,7 +3211,7 @@ var ImageEditor = ({
|
|
|
3037
3211
|
children: "\u21AA"
|
|
3038
3212
|
}
|
|
3039
3213
|
),
|
|
3040
|
-
/* @__PURE__ */
|
|
3214
|
+
/* @__PURE__ */ jsx16(
|
|
3041
3215
|
"button",
|
|
3042
3216
|
{
|
|
3043
3217
|
type: "button",
|
|
@@ -3046,8 +3220,8 @@ var ImageEditor = ({
|
|
|
3046
3220
|
children: "Reset"
|
|
3047
3221
|
}
|
|
3048
3222
|
),
|
|
3049
|
-
/* @__PURE__ */
|
|
3050
|
-
/* @__PURE__ */
|
|
3223
|
+
/* @__PURE__ */ jsx16("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
3224
|
+
/* @__PURE__ */ jsx16(
|
|
3051
3225
|
"button",
|
|
3052
3226
|
{
|
|
3053
3227
|
type: "button",
|
|
@@ -3057,11 +3231,11 @@ var ImageEditor = ({
|
|
|
3057
3231
|
children: "-"
|
|
3058
3232
|
}
|
|
3059
3233
|
),
|
|
3060
|
-
/* @__PURE__ */
|
|
3234
|
+
/* @__PURE__ */ jsxs15("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
3061
3235
|
Math.round(state.zoom * 100),
|
|
3062
3236
|
"%"
|
|
3063
3237
|
] }),
|
|
3064
|
-
/* @__PURE__ */
|
|
3238
|
+
/* @__PURE__ */ jsx16(
|
|
3065
3239
|
"button",
|
|
3066
3240
|
{
|
|
3067
3241
|
type: "button",
|
|
@@ -3071,8 +3245,8 @@ var ImageEditor = ({
|
|
|
3071
3245
|
children: "+"
|
|
3072
3246
|
}
|
|
3073
3247
|
),
|
|
3074
|
-
/* @__PURE__ */
|
|
3075
|
-
/* @__PURE__ */
|
|
3248
|
+
/* @__PURE__ */ jsx16("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
3249
|
+
/* @__PURE__ */ jsx16(
|
|
3076
3250
|
"button",
|
|
3077
3251
|
{
|
|
3078
3252
|
type: "button",
|
|
@@ -3083,7 +3257,7 @@ var ImageEditor = ({
|
|
|
3083
3257
|
children: "Hold Compare"
|
|
3084
3258
|
}
|
|
3085
3259
|
),
|
|
3086
|
-
/* @__PURE__ */
|
|
3260
|
+
/* @__PURE__ */ jsx16(
|
|
3087
3261
|
"button",
|
|
3088
3262
|
{
|
|
3089
3263
|
type: "button",
|
|
@@ -3094,16 +3268,16 @@ var ImageEditor = ({
|
|
|
3094
3268
|
)
|
|
3095
3269
|
] })
|
|
3096
3270
|
] }),
|
|
3097
|
-
transformTool.active && /* @__PURE__ */
|
|
3098
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */
|
|
3099
|
-
/* @__PURE__ */
|
|
3100
|
-
/* @__PURE__ */
|
|
3271
|
+
transformTool.active && /* @__PURE__ */ jsx16(FreeTransformOptionsBar, { tool: transformTool, className: "border-b border-slate-800 bg-slate-900/95 px-4 py-2" }),
|
|
3272
|
+
!transformTool.active && transformTool.error && /* @__PURE__ */ jsx16("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 }),
|
|
3273
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]", children: [
|
|
3274
|
+
/* @__PURE__ */ jsxs15(
|
|
3101
3275
|
"div",
|
|
3102
3276
|
{
|
|
3103
3277
|
ref: containerRef,
|
|
3104
3278
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
3105
3279
|
children: [
|
|
3106
|
-
/* @__PURE__ */
|
|
3280
|
+
/* @__PURE__ */ jsx16(
|
|
3107
3281
|
"canvas",
|
|
3108
3282
|
{
|
|
3109
3283
|
ref: canvasRef,
|
|
@@ -3120,7 +3294,7 @@ var ImageEditor = ({
|
|
|
3120
3294
|
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" : ""}`
|
|
3121
3295
|
}
|
|
3122
3296
|
),
|
|
3123
|
-
typeSession && /* @__PURE__ */
|
|
3297
|
+
typeSession && /* @__PURE__ */ jsx16(
|
|
3124
3298
|
"textarea",
|
|
3125
3299
|
{
|
|
3126
3300
|
ref: typeInputRef,
|
|
@@ -3142,11 +3316,11 @@ var ImageEditor = ({
|
|
|
3142
3316
|
]
|
|
3143
3317
|
}
|
|
3144
3318
|
),
|
|
3145
|
-
/* @__PURE__ */
|
|
3146
|
-
activeTab === "crop" && /* @__PURE__ */
|
|
3147
|
-
/* @__PURE__ */
|
|
3148
|
-
/* @__PURE__ */
|
|
3149
|
-
/* @__PURE__ */
|
|
3319
|
+
/* @__PURE__ */ jsxs15("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: [
|
|
3320
|
+
activeTab === "crop" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3321
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Aspect Ratio Presets" }),
|
|
3322
|
+
/* @__PURE__ */ jsxs15("div", { className: "grid grid-cols-3 gap-2", children: [
|
|
3323
|
+
/* @__PURE__ */ jsx16(
|
|
3150
3324
|
"button",
|
|
3151
3325
|
{
|
|
3152
3326
|
type: "button",
|
|
@@ -3158,7 +3332,7 @@ var ImageEditor = ({
|
|
|
3158
3332
|
children: "Freeform"
|
|
3159
3333
|
}
|
|
3160
3334
|
),
|
|
3161
|
-
/* @__PURE__ */
|
|
3335
|
+
/* @__PURE__ */ jsx16(
|
|
3162
3336
|
"button",
|
|
3163
3337
|
{
|
|
3164
3338
|
type: "button",
|
|
@@ -3170,7 +3344,7 @@ var ImageEditor = ({
|
|
|
3170
3344
|
children: "1:1 Square"
|
|
3171
3345
|
}
|
|
3172
3346
|
),
|
|
3173
|
-
/* @__PURE__ */
|
|
3347
|
+
/* @__PURE__ */ jsx16(
|
|
3174
3348
|
"button",
|
|
3175
3349
|
{
|
|
3176
3350
|
type: "button",
|
|
@@ -3182,7 +3356,7 @@ var ImageEditor = ({
|
|
|
3182
3356
|
children: "4:3 Standard"
|
|
3183
3357
|
}
|
|
3184
3358
|
),
|
|
3185
|
-
/* @__PURE__ */
|
|
3359
|
+
/* @__PURE__ */ jsx16(
|
|
3186
3360
|
"button",
|
|
3187
3361
|
{
|
|
3188
3362
|
type: "button",
|
|
@@ -3194,7 +3368,7 @@ var ImageEditor = ({
|
|
|
3194
3368
|
children: "16:9 Wide"
|
|
3195
3369
|
}
|
|
3196
3370
|
),
|
|
3197
|
-
/* @__PURE__ */
|
|
3371
|
+
/* @__PURE__ */ jsx16(
|
|
3198
3372
|
"button",
|
|
3199
3373
|
{
|
|
3200
3374
|
type: "button",
|
|
@@ -3206,7 +3380,7 @@ var ImageEditor = ({
|
|
|
3206
3380
|
children: "3:2 Photo"
|
|
3207
3381
|
}
|
|
3208
3382
|
),
|
|
3209
|
-
/* @__PURE__ */
|
|
3383
|
+
/* @__PURE__ */ jsx16(
|
|
3210
3384
|
"button",
|
|
3211
3385
|
{
|
|
3212
3386
|
type: "button",
|
|
@@ -3219,10 +3393,10 @@ var ImageEditor = ({
|
|
|
3219
3393
|
}
|
|
3220
3394
|
)
|
|
3221
3395
|
] }),
|
|
3222
|
-
/* @__PURE__ */
|
|
3223
|
-
/* @__PURE__ */
|
|
3224
|
-
/* @__PURE__ */
|
|
3225
|
-
/* @__PURE__ */
|
|
3396
|
+
/* @__PURE__ */ jsx16("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3397
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Orientation & Flips" }),
|
|
3398
|
+
/* @__PURE__ */ jsxs15("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
3399
|
+
/* @__PURE__ */ jsx16(
|
|
3226
3400
|
"button",
|
|
3227
3401
|
{
|
|
3228
3402
|
type: "button",
|
|
@@ -3231,7 +3405,7 @@ var ImageEditor = ({
|
|
|
3231
3405
|
children: "Rotate -90\xB0"
|
|
3232
3406
|
}
|
|
3233
3407
|
),
|
|
3234
|
-
/* @__PURE__ */
|
|
3408
|
+
/* @__PURE__ */ jsx16(
|
|
3235
3409
|
"button",
|
|
3236
3410
|
{
|
|
3237
3411
|
type: "button",
|
|
@@ -3240,7 +3414,7 @@ var ImageEditor = ({
|
|
|
3240
3414
|
children: "Rotate +90\xB0"
|
|
3241
3415
|
}
|
|
3242
3416
|
),
|
|
3243
|
-
/* @__PURE__ */
|
|
3417
|
+
/* @__PURE__ */ jsx16(
|
|
3244
3418
|
"button",
|
|
3245
3419
|
{
|
|
3246
3420
|
type: "button",
|
|
@@ -3249,7 +3423,7 @@ var ImageEditor = ({
|
|
|
3249
3423
|
children: "Flip Horizontal"
|
|
3250
3424
|
}
|
|
3251
3425
|
),
|
|
3252
|
-
/* @__PURE__ */
|
|
3426
|
+
/* @__PURE__ */ jsx16(
|
|
3253
3427
|
"button",
|
|
3254
3428
|
{
|
|
3255
3429
|
type: "button",
|
|
@@ -3260,10 +3434,10 @@ var ImageEditor = ({
|
|
|
3260
3434
|
)
|
|
3261
3435
|
] })
|
|
3262
3436
|
] }),
|
|
3263
|
-
activeTab === "adjust" && /* @__PURE__ */
|
|
3264
|
-
/* @__PURE__ */
|
|
3265
|
-
/* @__PURE__ */
|
|
3266
|
-
/* @__PURE__ */
|
|
3437
|
+
activeTab === "adjust" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3438
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
|
|
3439
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Color Adjustments" }),
|
|
3440
|
+
/* @__PURE__ */ jsx16(
|
|
3267
3441
|
"button",
|
|
3268
3442
|
{
|
|
3269
3443
|
type: "button",
|
|
@@ -3273,9 +3447,9 @@ var ImageEditor = ({
|
|
|
3273
3447
|
}
|
|
3274
3448
|
)
|
|
3275
3449
|
] }),
|
|
3276
|
-
/* @__PURE__ */
|
|
3277
|
-
IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */
|
|
3278
|
-
/* @__PURE__ */
|
|
3450
|
+
/* @__PURE__ */ jsx16(Histogram, { histogram: editor.histogram }),
|
|
3451
|
+
IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ jsxs15(React14.Fragment, { children: [
|
|
3452
|
+
/* @__PURE__ */ jsx16(
|
|
3279
3453
|
ControlSlider,
|
|
3280
3454
|
{
|
|
3281
3455
|
spec,
|
|
@@ -3284,14 +3458,14 @@ var ImageEditor = ({
|
|
|
3284
3458
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
3285
3459
|
}
|
|
3286
3460
|
),
|
|
3287
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */
|
|
3461
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ jsxs15(
|
|
3288
3462
|
"div",
|
|
3289
3463
|
{
|
|
3290
3464
|
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",
|
|
3291
3465
|
"data-testid": "image-editor-process-notice",
|
|
3292
3466
|
children: [
|
|
3293
|
-
/* @__PURE__ */
|
|
3294
|
-
/* @__PURE__ */
|
|
3467
|
+
/* @__PURE__ */ jsx16("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
3468
|
+
/* @__PURE__ */ jsx16(
|
|
3295
3469
|
"button",
|
|
3296
3470
|
{
|
|
3297
3471
|
type: "button",
|
|
@@ -3304,7 +3478,7 @@ var ImageEditor = ({
|
|
|
3304
3478
|
}
|
|
3305
3479
|
)
|
|
3306
3480
|
] }, spec.id)),
|
|
3307
|
-
/* @__PURE__ */
|
|
3481
|
+
/* @__PURE__ */ jsx16("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx16(
|
|
3308
3482
|
AdjustmentLayersPanel,
|
|
3309
3483
|
{
|
|
3310
3484
|
controller,
|
|
@@ -3313,9 +3487,9 @@ var ImageEditor = ({
|
|
|
3313
3487
|
}
|
|
3314
3488
|
) })
|
|
3315
3489
|
] }),
|
|
3316
|
-
activeTab === "layers" && /* @__PURE__ */
|
|
3317
|
-
/* @__PURE__ */
|
|
3318
|
-
/* @__PURE__ */
|
|
3490
|
+
activeTab === "layers" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3491
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Layers" }),
|
|
3492
|
+
/* @__PURE__ */ jsx16(
|
|
3319
3493
|
"button",
|
|
3320
3494
|
{
|
|
3321
3495
|
type: "button",
|
|
@@ -3326,14 +3500,15 @@ var ImageEditor = ({
|
|
|
3326
3500
|
children: "Free Transform"
|
|
3327
3501
|
}
|
|
3328
3502
|
),
|
|
3329
|
-
/* @__PURE__ */
|
|
3330
|
-
/* @__PURE__ */
|
|
3331
|
-
/* @__PURE__ */
|
|
3503
|
+
/* @__PURE__ */ jsx16(LayersPanel, { controller }),
|
|
3504
|
+
effectsShown && /* @__PURE__ */ jsx16(ImageProviderEffectsPanel, { controller, className: "border-t border-slate-700/60 pt-3" }),
|
|
3505
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Colour" }),
|
|
3506
|
+
/* @__PURE__ */ jsx16(ColorProfilePanel, { controller })
|
|
3332
3507
|
] }),
|
|
3333
|
-
activeTab === "paint" && /* @__PURE__ */
|
|
3334
|
-
/* @__PURE__ */
|
|
3335
|
-
/* @__PURE__ */
|
|
3336
|
-
/* @__PURE__ */
|
|
3508
|
+
activeTab === "paint" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3509
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Paint" }),
|
|
3510
|
+
/* @__PURE__ */ jsx16(BrushOptionsBar, { controller }),
|
|
3511
|
+
/* @__PURE__ */ jsx16(
|
|
3337
3512
|
"button",
|
|
3338
3513
|
{
|
|
3339
3514
|
type: "button",
|
|
@@ -3344,12 +3519,12 @@ var ImageEditor = ({
|
|
|
3344
3519
|
children: "Free Transform"
|
|
3345
3520
|
}
|
|
3346
3521
|
),
|
|
3347
|
-
paintError && /* @__PURE__ */
|
|
3348
|
-
/* @__PURE__ */
|
|
3522
|
+
paintError && /* @__PURE__ */ jsx16("p", { role: "alert", className: "text-rose-400", "data-testid": "paint-error", children: paintError }),
|
|
3523
|
+
/* @__PURE__ */ jsx16("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx16(LayersPanel, { controller }) })
|
|
3349
3524
|
] }),
|
|
3350
|
-
activeTab === "annotate" && /* @__PURE__ */
|
|
3351
|
-
/* @__PURE__ */
|
|
3352
|
-
/* @__PURE__ */
|
|
3525
|
+
activeTab === "annotate" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3526
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Shape & Type Layers" }),
|
|
3527
|
+
/* @__PURE__ */ jsx16("div", { className: "grid grid-cols-2 gap-1.5", children: ["shape", "type"].map((t) => /* @__PURE__ */ jsx16(
|
|
3353
3528
|
"button",
|
|
3354
3529
|
{
|
|
3355
3530
|
type: "button",
|
|
@@ -3360,13 +3535,13 @@ var ImageEditor = ({
|
|
|
3360
3535
|
},
|
|
3361
3536
|
t
|
|
3362
3537
|
)) }),
|
|
3363
|
-
state.activeTool === "shape" && /* @__PURE__ */
|
|
3364
|
-
state.activeTool === "type" && /* @__PURE__ */
|
|
3365
|
-
state.activeTool === "type" && typeSession && /* @__PURE__ */
|
|
3366
|
-
shapeTypeError && /* @__PURE__ */
|
|
3367
|
-
/* @__PURE__ */
|
|
3368
|
-
/* @__PURE__ */
|
|
3369
|
-
/* @__PURE__ */
|
|
3538
|
+
state.activeTool === "shape" && /* @__PURE__ */ jsx16(ShapeOptionsBar, { controller, options: shapeOptions, onChange: setShapeOptions }),
|
|
3539
|
+
state.activeTool === "type" && /* @__PURE__ */ jsx16(TypeOptionsBar, { controller, options: typeOptions, onChange: setTypeOptions, session: typeSession }),
|
|
3540
|
+
state.activeTool === "type" && typeSession && /* @__PURE__ */ jsx16("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" }),
|
|
3541
|
+
shapeTypeError && /* @__PURE__ */ jsx16("p", { role: "alert", className: "text-rose-400", "data-testid": "shape-type-error", children: shapeTypeError }),
|
|
3542
|
+
/* @__PURE__ */ jsx16("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3543
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Draw & Annotate" }),
|
|
3544
|
+
/* @__PURE__ */ jsx16("div", { className: "grid grid-cols-3 gap-1.5", children: ["pen", "rect", "circle", "arrow", "line"].map((t) => /* @__PURE__ */ jsx16(
|
|
3370
3545
|
"button",
|
|
3371
3546
|
{
|
|
3372
3547
|
type: "button",
|
|
@@ -3376,9 +3551,9 @@ var ImageEditor = ({
|
|
|
3376
3551
|
},
|
|
3377
3552
|
t
|
|
3378
3553
|
)) }),
|
|
3379
|
-
/* @__PURE__ */
|
|
3380
|
-
/* @__PURE__ */
|
|
3381
|
-
/* @__PURE__ */
|
|
3554
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 mt-2", children: [
|
|
3555
|
+
/* @__PURE__ */ jsx16("label", { className: "text-slate-400", children: "Color:" }),
|
|
3556
|
+
/* @__PURE__ */ jsx16(
|
|
3382
3557
|
"input",
|
|
3383
3558
|
{
|
|
3384
3559
|
type: "color",
|
|
@@ -3387,15 +3562,15 @@ var ImageEditor = ({
|
|
|
3387
3562
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
3388
3563
|
}
|
|
3389
3564
|
),
|
|
3390
|
-
/* @__PURE__ */
|
|
3391
|
-
/* @__PURE__ */
|
|
3392
|
-
/* @__PURE__ */
|
|
3393
|
-
/* @__PURE__ */
|
|
3565
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex-1 ml-2", children: [
|
|
3566
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex justify-between text-slate-400 mb-0.5", children: [
|
|
3567
|
+
/* @__PURE__ */ jsx16("span", { children: "Width:" }),
|
|
3568
|
+
/* @__PURE__ */ jsxs15("span", { className: "font-mono", children: [
|
|
3394
3569
|
strokeWidth,
|
|
3395
3570
|
"px"
|
|
3396
3571
|
] })
|
|
3397
3572
|
] }),
|
|
3398
|
-
/* @__PURE__ */
|
|
3573
|
+
/* @__PURE__ */ jsx16(
|
|
3399
3574
|
"input",
|
|
3400
3575
|
{
|
|
3401
3576
|
type: "range",
|
|
@@ -3408,10 +3583,10 @@ var ImageEditor = ({
|
|
|
3408
3583
|
)
|
|
3409
3584
|
] })
|
|
3410
3585
|
] }),
|
|
3411
|
-
/* @__PURE__ */
|
|
3412
|
-
/* @__PURE__ */
|
|
3413
|
-
/* @__PURE__ */
|
|
3414
|
-
/* @__PURE__ */
|
|
3586
|
+
/* @__PURE__ */ jsx16("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3587
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Add Text" }),
|
|
3588
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex gap-2", children: [
|
|
3589
|
+
/* @__PURE__ */ jsx16(
|
|
3415
3590
|
"input",
|
|
3416
3591
|
{
|
|
3417
3592
|
type: "text",
|
|
@@ -3422,7 +3597,7 @@ var ImageEditor = ({
|
|
|
3422
3597
|
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"
|
|
3423
3598
|
}
|
|
3424
3599
|
),
|
|
3425
|
-
/* @__PURE__ */
|
|
3600
|
+
/* @__PURE__ */ jsx16(
|
|
3426
3601
|
"button",
|
|
3427
3602
|
{
|
|
3428
3603
|
type: "button",
|
|
@@ -3432,14 +3607,14 @@ var ImageEditor = ({
|
|
|
3432
3607
|
}
|
|
3433
3608
|
)
|
|
3434
3609
|
] }),
|
|
3435
|
-
/* @__PURE__ */
|
|
3436
|
-
/* @__PURE__ */
|
|
3437
|
-
/* @__PURE__ */
|
|
3610
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between text-slate-400", children: [
|
|
3611
|
+
/* @__PURE__ */ jsx16("span", { children: "Font Size:" }),
|
|
3612
|
+
/* @__PURE__ */ jsxs15("span", { className: "font-mono", children: [
|
|
3438
3613
|
fontSize,
|
|
3439
3614
|
"px"
|
|
3440
3615
|
] })
|
|
3441
3616
|
] }),
|
|
3442
|
-
/* @__PURE__ */
|
|
3617
|
+
/* @__PURE__ */ jsx16(
|
|
3443
3618
|
"input",
|
|
3444
3619
|
{
|
|
3445
3620
|
type: "range",
|
|
@@ -3450,14 +3625,14 @@ var ImageEditor = ({
|
|
|
3450
3625
|
className: "w-full accent-indigo-500"
|
|
3451
3626
|
}
|
|
3452
3627
|
),
|
|
3453
|
-
/* @__PURE__ */
|
|
3454
|
-
/* @__PURE__ */
|
|
3455
|
-
/* @__PURE__ */
|
|
3628
|
+
/* @__PURE__ */ jsx16("div", { className: "h-px bg-slate-800 my-1" }),
|
|
3629
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
|
|
3630
|
+
/* @__PURE__ */ jsxs15("span", { className: "text-slate-400", children: [
|
|
3456
3631
|
"Layers (",
|
|
3457
3632
|
state.annotations.length,
|
|
3458
3633
|
")"
|
|
3459
3634
|
] }),
|
|
3460
|
-
state.selectedAnnotationId && /* @__PURE__ */
|
|
3635
|
+
state.selectedAnnotationId && /* @__PURE__ */ jsx16(
|
|
3461
3636
|
"button",
|
|
3462
3637
|
{
|
|
3463
3638
|
type: "button",
|
|
@@ -3466,7 +3641,7 @@ var ImageEditor = ({
|
|
|
3466
3641
|
children: "Delete Selected"
|
|
3467
3642
|
}
|
|
3468
3643
|
),
|
|
3469
|
-
state.annotations.length > 0 && /* @__PURE__ */
|
|
3644
|
+
state.annotations.length > 0 && /* @__PURE__ */ jsx16(
|
|
3470
3645
|
"button",
|
|
3471
3646
|
{
|
|
3472
3647
|
type: "button",
|
|
@@ -3477,10 +3652,10 @@ var ImageEditor = ({
|
|
|
3477
3652
|
)
|
|
3478
3653
|
] })
|
|
3479
3654
|
] }),
|
|
3480
|
-
activeTab === "depth" && /* @__PURE__ */
|
|
3481
|
-
/* @__PURE__ */
|
|
3482
|
-
/* @__PURE__ */
|
|
3483
|
-
/* @__PURE__ */
|
|
3655
|
+
activeTab === "depth" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-3 text-xs", children: [
|
|
3656
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
|
|
3657
|
+
/* @__PURE__ */ jsx16("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px]", children: "Depth Masking" }),
|
|
3658
|
+
/* @__PURE__ */ jsx16(
|
|
3484
3659
|
"button",
|
|
3485
3660
|
{
|
|
3486
3661
|
type: "button",
|
|
@@ -3490,8 +3665,8 @@ var ImageEditor = ({
|
|
|
3490
3665
|
}
|
|
3491
3666
|
)
|
|
3492
3667
|
] }),
|
|
3493
|
-
/* @__PURE__ */
|
|
3494
|
-
/* @__PURE__ */
|
|
3668
|
+
/* @__PURE__ */ jsxs15("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
3669
|
+
/* @__PURE__ */ jsx16(
|
|
3495
3670
|
"input",
|
|
3496
3671
|
{
|
|
3497
3672
|
type: "checkbox",
|
|
@@ -3500,12 +3675,12 @@ var ImageEditor = ({
|
|
|
3500
3675
|
className: "rounded accent-indigo-500"
|
|
3501
3676
|
}
|
|
3502
3677
|
),
|
|
3503
|
-
/* @__PURE__ */
|
|
3678
|
+
/* @__PURE__ */ jsx16("span", { children: "Enable Depth / Alpha Mask" })
|
|
3504
3679
|
] }),
|
|
3505
|
-
state.depthMask.enabled && /* @__PURE__ */
|
|
3506
|
-
/* @__PURE__ */
|
|
3507
|
-
/* @__PURE__ */
|
|
3508
|
-
/* @__PURE__ */
|
|
3680
|
+
state.depthMask.enabled && /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
3681
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
3682
|
+
/* @__PURE__ */ jsx16("label", { className: "text-slate-400 block mb-1", children: "Mask Image URL:" }),
|
|
3683
|
+
/* @__PURE__ */ jsx16(
|
|
3509
3684
|
"input",
|
|
3510
3685
|
{
|
|
3511
3686
|
type: "text",
|
|
@@ -3516,8 +3691,8 @@ var ImageEditor = ({
|
|
|
3516
3691
|
}
|
|
3517
3692
|
)
|
|
3518
3693
|
] }),
|
|
3519
|
-
/* @__PURE__ */
|
|
3520
|
-
/* @__PURE__ */
|
|
3694
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex gap-2", children: [
|
|
3695
|
+
/* @__PURE__ */ jsx16(
|
|
3521
3696
|
"button",
|
|
3522
3697
|
{
|
|
3523
3698
|
type: "button",
|
|
@@ -3526,7 +3701,7 @@ var ImageEditor = ({
|
|
|
3526
3701
|
children: "Threshold Mode"
|
|
3527
3702
|
}
|
|
3528
3703
|
),
|
|
3529
|
-
/* @__PURE__ */
|
|
3704
|
+
/* @__PURE__ */ jsx16(
|
|
3530
3705
|
"button",
|
|
3531
3706
|
{
|
|
3532
3707
|
type: "button",
|
|
@@ -3536,12 +3711,12 @@ var ImageEditor = ({
|
|
|
3536
3711
|
}
|
|
3537
3712
|
)
|
|
3538
3713
|
] }),
|
|
3539
|
-
/* @__PURE__ */
|
|
3540
|
-
/* @__PURE__ */
|
|
3541
|
-
/* @__PURE__ */
|
|
3542
|
-
/* @__PURE__ */
|
|
3714
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
3715
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3716
|
+
/* @__PURE__ */ jsx16("span", { children: "Depth Start (Lower):" }),
|
|
3717
|
+
/* @__PURE__ */ jsx16("span", { className: "font-mono", children: state.depthMask.depthRange[0] })
|
|
3543
3718
|
] }),
|
|
3544
|
-
/* @__PURE__ */
|
|
3719
|
+
/* @__PURE__ */ jsx16(
|
|
3545
3720
|
"input",
|
|
3546
3721
|
{
|
|
3547
3722
|
type: "range",
|
|
@@ -3555,12 +3730,12 @@ var ImageEditor = ({
|
|
|
3555
3730
|
}
|
|
3556
3731
|
)
|
|
3557
3732
|
] }),
|
|
3558
|
-
/* @__PURE__ */
|
|
3559
|
-
/* @__PURE__ */
|
|
3560
|
-
/* @__PURE__ */
|
|
3561
|
-
/* @__PURE__ */
|
|
3733
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
3734
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3735
|
+
/* @__PURE__ */ jsx16("span", { children: "Depth Stop (Upper):" }),
|
|
3736
|
+
/* @__PURE__ */ jsx16("span", { className: "font-mono", children: state.depthMask.depthRange[1] })
|
|
3562
3737
|
] }),
|
|
3563
|
-
/* @__PURE__ */
|
|
3738
|
+
/* @__PURE__ */ jsx16(
|
|
3564
3739
|
"input",
|
|
3565
3740
|
{
|
|
3566
3741
|
type: "range",
|
|
@@ -3574,12 +3749,12 @@ var ImageEditor = ({
|
|
|
3574
3749
|
}
|
|
3575
3750
|
)
|
|
3576
3751
|
] }),
|
|
3577
|
-
/* @__PURE__ */
|
|
3578
|
-
/* @__PURE__ */
|
|
3579
|
-
/* @__PURE__ */
|
|
3580
|
-
/* @__PURE__ */
|
|
3752
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
3753
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex justify-between text-slate-400 mb-1", children: [
|
|
3754
|
+
/* @__PURE__ */ jsx16("span", { children: "Softness:" }),
|
|
3755
|
+
/* @__PURE__ */ jsx16("span", { className: "font-mono", children: state.depthMask.softness })
|
|
3581
3756
|
] }),
|
|
3582
|
-
/* @__PURE__ */
|
|
3757
|
+
/* @__PURE__ */ jsx16(
|
|
3583
3758
|
"input",
|
|
3584
3759
|
{
|
|
3585
3760
|
type: "range",
|
|
@@ -3591,8 +3766,8 @@ var ImageEditor = ({
|
|
|
3591
3766
|
}
|
|
3592
3767
|
)
|
|
3593
3768
|
] }),
|
|
3594
|
-
/* @__PURE__ */
|
|
3595
|
-
/* @__PURE__ */
|
|
3769
|
+
/* @__PURE__ */ jsxs15("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
3770
|
+
/* @__PURE__ */ jsx16(
|
|
3596
3771
|
"input",
|
|
3597
3772
|
{
|
|
3598
3773
|
type: "checkbox",
|
|
@@ -3601,12 +3776,12 @@ var ImageEditor = ({
|
|
|
3601
3776
|
className: "rounded accent-indigo-500"
|
|
3602
3777
|
}
|
|
3603
3778
|
),
|
|
3604
|
-
/* @__PURE__ */
|
|
3779
|
+
/* @__PURE__ */ jsx16("span", { children: "Invert Mask" })
|
|
3605
3780
|
] })
|
|
3606
3781
|
] })
|
|
3607
3782
|
] }),
|
|
3608
|
-
activeTab === "select" && /* @__PURE__ */
|
|
3609
|
-
/* @__PURE__ */
|
|
3783
|
+
activeTab === "select" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3784
|
+
/* @__PURE__ */ jsx16(
|
|
3610
3785
|
SelectionOptionsBar,
|
|
3611
3786
|
{
|
|
3612
3787
|
controller,
|
|
@@ -3616,9 +3791,9 @@ var ImageEditor = ({
|
|
|
3616
3791
|
quickMask: Boolean(state.quickMask)
|
|
3617
3792
|
}
|
|
3618
3793
|
),
|
|
3619
|
-
selectionError && /* @__PURE__ */
|
|
3620
|
-
/* @__PURE__ */
|
|
3621
|
-
/* @__PURE__ */
|
|
3794
|
+
selectionError && /* @__PURE__ */ jsx16("p", { role: "alert", className: "text-rose-400", children: selectionError }),
|
|
3795
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex gap-1", children: [
|
|
3796
|
+
/* @__PURE__ */ jsx16(
|
|
3622
3797
|
"button",
|
|
3623
3798
|
{
|
|
3624
3799
|
type: "button",
|
|
@@ -3629,7 +3804,7 @@ var ImageEditor = ({
|
|
|
3629
3804
|
children: "Transform Selection"
|
|
3630
3805
|
}
|
|
3631
3806
|
),
|
|
3632
|
-
/* @__PURE__ */
|
|
3807
|
+
/* @__PURE__ */ jsx16(
|
|
3633
3808
|
"button",
|
|
3634
3809
|
{
|
|
3635
3810
|
type: "button",
|
|
@@ -3641,12 +3816,12 @@ var ImageEditor = ({
|
|
|
3641
3816
|
}
|
|
3642
3817
|
)
|
|
3643
3818
|
] }),
|
|
3644
|
-
/* @__PURE__ */
|
|
3819
|
+
/* @__PURE__ */ jsx16(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
3645
3820
|
] }),
|
|
3646
|
-
activeTab === "ai" && /* @__PURE__ */
|
|
3647
|
-
/* @__PURE__ */
|
|
3648
|
-
/* @__PURE__ */
|
|
3649
|
-
/* @__PURE__ */
|
|
3821
|
+
activeTab === "ai" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3822
|
+
/* @__PURE__ */ jsxs15("label", { className: "flex items-center justify-between gap-2 text-slate-300", children: [
|
|
3823
|
+
/* @__PURE__ */ jsx16("span", { children: "Results go to" }),
|
|
3824
|
+
/* @__PURE__ */ jsxs15(
|
|
3650
3825
|
"select",
|
|
3651
3826
|
{
|
|
3652
3827
|
"aria-label": "AI result target",
|
|
@@ -3654,54 +3829,54 @@ var ImageEditor = ({
|
|
|
3654
3829
|
onChange: (e) => setAiTarget(e.target.value),
|
|
3655
3830
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
3656
3831
|
children: [
|
|
3657
|
-
/* @__PURE__ */
|
|
3658
|
-
/* @__PURE__ */
|
|
3659
|
-
/* @__PURE__ */
|
|
3832
|
+
/* @__PURE__ */ jsx16("option", { value: "auto", children: controller.isMultiLayer ? "Auto (new layer)" : "Auto (replace image)" }),
|
|
3833
|
+
/* @__PURE__ */ jsx16("option", { value: "new-layer", children: "New layer / mask" }),
|
|
3834
|
+
/* @__PURE__ */ jsx16("option", { value: "replace", children: "Replace image" })
|
|
3660
3835
|
]
|
|
3661
3836
|
}
|
|
3662
3837
|
)
|
|
3663
3838
|
] }),
|
|
3664
|
-
/* @__PURE__ */
|
|
3665
|
-
/* @__PURE__ */
|
|
3666
|
-
/* @__PURE__ */
|
|
3667
|
-
/* @__PURE__ */
|
|
3839
|
+
/* @__PURE__ */ jsxs15("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3840
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
|
|
3841
|
+
/* @__PURE__ */ jsxs15("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3842
|
+
/* @__PURE__ */ jsx16("svg", { className: "w-3.5 h-3.5 text-indigo-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx16("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" }) }),
|
|
3668
3843
|
"Background Removal"
|
|
3669
3844
|
] }),
|
|
3670
|
-
isRemovingBg && /* @__PURE__ */
|
|
3845
|
+
isRemovingBg && /* @__PURE__ */ jsx16("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..." })
|
|
3671
3846
|
] }),
|
|
3672
|
-
/* @__PURE__ */
|
|
3673
|
-
/* @__PURE__ */
|
|
3847
|
+
/* @__PURE__ */ jsx16("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Isolate foreground subject with AI alpha transparency segmentation." }),
|
|
3848
|
+
/* @__PURE__ */ jsx16(
|
|
3674
3849
|
"button",
|
|
3675
3850
|
{
|
|
3676
3851
|
type: "button",
|
|
3677
3852
|
onClick: handleRemoveBackground,
|
|
3678
3853
|
disabled: isRemovingBg || isInpainting,
|
|
3679
3854
|
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",
|
|
3680
|
-
children: isRemovingBg ? /* @__PURE__ */
|
|
3681
|
-
/* @__PURE__ */
|
|
3855
|
+
children: isRemovingBg ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
3856
|
+
/* @__PURE__ */ jsx16("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
3682
3857
|
"Removing Background..."
|
|
3683
|
-
] }) : /* @__PURE__ */
|
|
3684
|
-
/* @__PURE__ */
|
|
3858
|
+
] }) : /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
3859
|
+
/* @__PURE__ */ jsx16("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx16("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" }) }),
|
|
3685
3860
|
"Remove Background"
|
|
3686
3861
|
] })
|
|
3687
3862
|
}
|
|
3688
3863
|
)
|
|
3689
3864
|
] }),
|
|
3690
|
-
/* @__PURE__ */
|
|
3691
|
-
/* @__PURE__ */
|
|
3692
|
-
/* @__PURE__ */
|
|
3693
|
-
/* @__PURE__ */
|
|
3694
|
-
/* @__PURE__ */
|
|
3695
|
-
/* @__PURE__ */
|
|
3865
|
+
/* @__PURE__ */ jsxs15("div", { className: "p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5", children: [
|
|
3866
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between", children: [
|
|
3867
|
+
/* @__PURE__ */ jsxs15("span", { className: "font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5", children: [
|
|
3868
|
+
/* @__PURE__ */ jsxs15("svg", { className: "w-3.5 h-3.5 text-purple-400", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
|
|
3869
|
+
/* @__PURE__ */ jsx16("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" }),
|
|
3870
|
+
/* @__PURE__ */ jsx16("path", { d: "m14 7 3 3" })
|
|
3696
3871
|
] }),
|
|
3697
3872
|
"Generative Inpainting"
|
|
3698
3873
|
] }),
|
|
3699
|
-
isInpainting && /* @__PURE__ */
|
|
3874
|
+
isInpainting && /* @__PURE__ */ jsx16("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..." })
|
|
3700
3875
|
] }),
|
|
3701
|
-
/* @__PURE__ */
|
|
3702
|
-
/* @__PURE__ */
|
|
3703
|
-
/* @__PURE__ */
|
|
3704
|
-
/* @__PURE__ */
|
|
3876
|
+
/* @__PURE__ */ jsx16("p", { className: "text-slate-400 text-[11px] leading-relaxed", children: "Replace, modify, or fill selected regions using prompt-guided generative inpainting." }),
|
|
3877
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
|
|
3878
|
+
/* @__PURE__ */ jsx16("label", { htmlFor: "ai-inpaint-prompt-react", className: "text-slate-300 text-[11px] font-medium", children: "Prompt" }),
|
|
3879
|
+
/* @__PURE__ */ jsx16(
|
|
3705
3880
|
"textarea",
|
|
3706
3881
|
{
|
|
3707
3882
|
id: "ai-inpaint-prompt-react",
|
|
@@ -3713,10 +3888,10 @@ var ImageEditor = ({
|
|
|
3713
3888
|
}
|
|
3714
3889
|
)
|
|
3715
3890
|
] }),
|
|
3716
|
-
/* @__PURE__ */
|
|
3717
|
-
/* @__PURE__ */
|
|
3718
|
-
/* @__PURE__ */
|
|
3719
|
-
/* @__PURE__ */
|
|
3891
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
|
|
3892
|
+
/* @__PURE__ */ jsx16("span", { className: "text-slate-300 text-[11px] font-medium", children: "Target Mask Region" }),
|
|
3893
|
+
/* @__PURE__ */ jsxs15("div", { className: "grid grid-cols-2 gap-1.5", children: [
|
|
3894
|
+
/* @__PURE__ */ jsxs15(
|
|
3720
3895
|
"button",
|
|
3721
3896
|
{
|
|
3722
3897
|
type: "button",
|
|
@@ -3729,7 +3904,7 @@ var ImageEditor = ({
|
|
|
3729
3904
|
]
|
|
3730
3905
|
}
|
|
3731
3906
|
),
|
|
3732
|
-
/* @__PURE__ */
|
|
3907
|
+
/* @__PURE__ */ jsxs15(
|
|
3733
3908
|
"button",
|
|
3734
3909
|
{
|
|
3735
3910
|
type: "button",
|
|
@@ -3744,25 +3919,25 @@ var ImageEditor = ({
|
|
|
3744
3919
|
)
|
|
3745
3920
|
] })
|
|
3746
3921
|
] }),
|
|
3747
|
-
/* @__PURE__ */
|
|
3922
|
+
/* @__PURE__ */ jsx16(
|
|
3748
3923
|
"button",
|
|
3749
3924
|
{
|
|
3750
3925
|
type: "button",
|
|
3751
3926
|
onClick: handleInpaint,
|
|
3752
3927
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
3753
3928
|
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",
|
|
3754
|
-
children: isInpainting ? /* @__PURE__ */
|
|
3755
|
-
/* @__PURE__ */
|
|
3929
|
+
children: isInpainting ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
3930
|
+
/* @__PURE__ */ jsx16("div", { className: "w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
3756
3931
|
"Generating Inpaint..."
|
|
3757
|
-
] }) : /* @__PURE__ */
|
|
3758
|
-
/* @__PURE__ */
|
|
3932
|
+
] }) : /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
3933
|
+
/* @__PURE__ */ jsx16("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx16("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" }) }),
|
|
3759
3934
|
"Apply Inpainting"
|
|
3760
3935
|
] })
|
|
3761
3936
|
}
|
|
3762
3937
|
)
|
|
3763
3938
|
] }),
|
|
3764
|
-
aiError && /* @__PURE__ */
|
|
3765
|
-
aiSuccess && /* @__PURE__ */
|
|
3939
|
+
aiError && /* @__PURE__ */ jsx16("div", { className: "p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]", children: aiError }),
|
|
3940
|
+
aiSuccess && /* @__PURE__ */ jsx16("div", { className: "p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]", children: aiSuccess })
|
|
3766
3941
|
] })
|
|
3767
3942
|
] })
|
|
3768
3943
|
] })
|
|
@@ -3773,6 +3948,7 @@ var ImageEditor = ({
|
|
|
3773
3948
|
|
|
3774
3949
|
export {
|
|
3775
3950
|
useImageEditor,
|
|
3951
|
+
useImageEffectsTools,
|
|
3776
3952
|
ControlSlider,
|
|
3777
3953
|
Histogram,
|
|
3778
3954
|
useImageHistogram,
|
|
@@ -3780,6 +3956,8 @@ export {
|
|
|
3780
3956
|
AdjustmentLayersPanel,
|
|
3781
3957
|
LayerEffectsPanel,
|
|
3782
3958
|
LayersPanel,
|
|
3959
|
+
ImageProviderEffectsPanel,
|
|
3960
|
+
PaintGradientEditor,
|
|
3783
3961
|
BrushOptionsBar,
|
|
3784
3962
|
ColorProfilePanel,
|
|
3785
3963
|
SelectionOptionsBar,
|
|
@@ -3789,4 +3967,4 @@ export {
|
|
|
3789
3967
|
TypeOptionsBar,
|
|
3790
3968
|
ImageEditor
|
|
3791
3969
|
};
|
|
3792
|
-
//# sourceMappingURL=chunk-
|
|
3970
|
+
//# sourceMappingURL=chunk-2EW42UXC.js.map
|