@pixerate/editor-react 0.77.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/{chunk-QARGR5E5.js → chunk-2EW42UXC.js} +617 -464
- 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-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 +1282 -574
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +29 -2
- package/dist/image-editor/index.d.ts +29 -2
- package/dist/image-editor/index.js +7 -1
- package/dist/index.cjs +1695 -987
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -1
- package/dist/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-QARGR5E5.js.map +0 -1
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EffectParameters,
|
|
3
|
+
EffectsBrowser,
|
|
4
|
+
useEffectDescription,
|
|
5
|
+
useEffects
|
|
6
|
+
} from "./chunk-FX3EREF5.js";
|
|
1
7
|
import {
|
|
2
8
|
PaintGradientEditorView
|
|
3
9
|
} from "./chunk-MO354USR.js";
|
|
@@ -5,7 +11,8 @@ import {
|
|
|
5
11
|
// src/image-editor/useImageEditor.ts
|
|
6
12
|
import { useRef, useState, useEffect, useCallback, useMemo } from "react";
|
|
7
13
|
import {
|
|
8
|
-
ImageEditorController
|
|
14
|
+
ImageEditorController,
|
|
15
|
+
createImageEffectsToolProvider
|
|
9
16
|
} from "@pixerate/editor/image-editor";
|
|
10
17
|
function useImageEditor(options = {}) {
|
|
11
18
|
const controllerRef = useRef(null);
|
|
@@ -161,9 +168,16 @@ function useImageEditor(options = {}) {
|
|
|
161
168
|
[controller, state, historyTicks, histogram]
|
|
162
169
|
);
|
|
163
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
|
+
}
|
|
164
178
|
|
|
165
179
|
// src/image-editor/ImageEditor.tsx
|
|
166
|
-
import
|
|
180
|
+
import React14, { useRef as useRef5, useEffect as useEffect12, useState as useState15, useCallback as useCallback2 } from "react";
|
|
167
181
|
import {
|
|
168
182
|
canvasToImagePoint,
|
|
169
183
|
hitTestCrop,
|
|
@@ -1268,8 +1282,139 @@ var LayersPanel = ({ controller, thumbnailSize = 32, psd = true, psdFileName = "
|
|
|
1268
1282
|
] });
|
|
1269
1283
|
};
|
|
1270
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
|
+
|
|
1271
1416
|
// src/image-editor/BrushOptionsBar.tsx
|
|
1272
|
-
import { useEffect as
|
|
1417
|
+
import { useEffect as useEffect7, useState as useState8 } from "react";
|
|
1273
1418
|
import {
|
|
1274
1419
|
BRUSH_OPTION_CONTROLS,
|
|
1275
1420
|
MIXER_MIXING_OPTIONS,
|
|
@@ -1287,16 +1432,16 @@ import { DEFAULT_PAINT_GRADIENT } from "@pixerate/editor/image-editor";
|
|
|
1287
1432
|
|
|
1288
1433
|
// src/image-editor/PaintGradientEditor.tsx
|
|
1289
1434
|
import { PAINT_GRADIENT_KIT } from "@pixerate/editor/image-editor";
|
|
1290
|
-
import { jsx as
|
|
1291
|
-
var PaintGradientEditor = (props) => /* @__PURE__ */
|
|
1435
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1436
|
+
var PaintGradientEditor = (props) => /* @__PURE__ */ jsx8(PaintGradientEditorView, { ...props, kit: PAINT_GRADIENT_KIT });
|
|
1292
1437
|
|
|
1293
1438
|
// src/image-editor/BrushOptionsBar.tsx
|
|
1294
|
-
import { jsx as
|
|
1439
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1295
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"}`;
|
|
1296
1441
|
var BrushOptionsBar = ({ controller, className }) => {
|
|
1297
|
-
const [, setTick] =
|
|
1298
|
-
|
|
1299
|
-
const [error, setError] =
|
|
1442
|
+
const [, setTick] = useState8(0);
|
|
1443
|
+
useEffect7(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
1444
|
+
const [error, setError] = useState8(null);
|
|
1300
1445
|
const state = controller.getState();
|
|
1301
1446
|
const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource, paint } = state.paint;
|
|
1302
1447
|
const tool = state.activeTool;
|
|
@@ -1308,8 +1453,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1308
1453
|
setError(err instanceof Error ? err.message : String(err));
|
|
1309
1454
|
}
|
|
1310
1455
|
};
|
|
1311
|
-
return /* @__PURE__ */
|
|
1312
|
-
/* @__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(
|
|
1313
1458
|
"button",
|
|
1314
1459
|
{
|
|
1315
1460
|
type: "button",
|
|
@@ -1321,9 +1466,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1321
1466
|
},
|
|
1322
1467
|
t.id
|
|
1323
1468
|
)) }),
|
|
1324
|
-
/* @__PURE__ */
|
|
1325
|
-
/* @__PURE__ */
|
|
1326
|
-
/* @__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(
|
|
1327
1472
|
"input",
|
|
1328
1473
|
{
|
|
1329
1474
|
type: "color",
|
|
@@ -1333,10 +1478,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1333
1478
|
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
1334
1479
|
}
|
|
1335
1480
|
),
|
|
1336
|
-
/* @__PURE__ */
|
|
1481
|
+
/* @__PURE__ */ jsx9("span", { className: "text-slate-400", children: "FG" })
|
|
1337
1482
|
] }),
|
|
1338
|
-
/* @__PURE__ */
|
|
1339
|
-
/* @__PURE__ */
|
|
1483
|
+
/* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1", children: [
|
|
1484
|
+
/* @__PURE__ */ jsx9(
|
|
1340
1485
|
"input",
|
|
1341
1486
|
{
|
|
1342
1487
|
type: "color",
|
|
@@ -1346,11 +1491,11 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1346
1491
|
className: "h-6 w-8 rounded border border-slate-700 bg-transparent"
|
|
1347
1492
|
}
|
|
1348
1493
|
),
|
|
1349
|
-
/* @__PURE__ */
|
|
1494
|
+
/* @__PURE__ */ jsx9("span", { className: "text-slate-400", children: "BG" })
|
|
1350
1495
|
] }),
|
|
1351
|
-
/* @__PURE__ */
|
|
1352
|
-
/* @__PURE__ */
|
|
1353
|
-
state.activeTool === "brush" && /* @__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(
|
|
1354
1499
|
"button",
|
|
1355
1500
|
{
|
|
1356
1501
|
type: "button",
|
|
@@ -1362,8 +1507,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1362
1507
|
}
|
|
1363
1508
|
)
|
|
1364
1509
|
] }),
|
|
1365
|
-
state.activeTool === "brush" && paint.type === "gradient" && /* @__PURE__ */
|
|
1366
|
-
BRUSH_OPTION_CONTROLS.map((spec) => /* @__PURE__ */
|
|
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(
|
|
1367
1512
|
ControlSlider,
|
|
1368
1513
|
{
|
|
1369
1514
|
spec,
|
|
@@ -1372,9 +1517,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1372
1517
|
},
|
|
1373
1518
|
spec.id
|
|
1374
1519
|
)),
|
|
1375
|
-
state.activeTool === "mixer" && /* @__PURE__ */
|
|
1376
|
-
/* @__PURE__ */
|
|
1377
|
-
/* @__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(
|
|
1378
1523
|
"span",
|
|
1379
1524
|
{
|
|
1380
1525
|
"aria-label": "Brush load",
|
|
@@ -1383,10 +1528,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1383
1528
|
style: { background: mixerLoad.reservoir ? rgbUnitToHex(mixerLoad.reservoir) : "transparent" }
|
|
1384
1529
|
}
|
|
1385
1530
|
),
|
|
1386
|
-
/* @__PURE__ */
|
|
1387
|
-
/* @__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" })
|
|
1388
1533
|
] }),
|
|
1389
|
-
/* @__PURE__ */
|
|
1534
|
+
/* @__PURE__ */ jsx9("div", { className: "flex gap-1", role: "group", "aria-label": "Mixing", children: MIXER_MIXING_OPTIONS.map((m) => /* @__PURE__ */ jsx9(
|
|
1390
1535
|
"button",
|
|
1391
1536
|
{
|
|
1392
1537
|
type: "button",
|
|
@@ -1398,10 +1543,10 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1398
1543
|
},
|
|
1399
1544
|
m.id
|
|
1400
1545
|
)) }),
|
|
1401
|
-
MIXER_OPTION_CONTROLS.map((spec) => /* @__PURE__ */
|
|
1402
|
-
/* @__PURE__ */
|
|
1403
|
-
/* @__PURE__ */
|
|
1404
|
-
/* @__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(
|
|
1405
1550
|
"input",
|
|
1406
1551
|
{
|
|
1407
1552
|
type: "checkbox",
|
|
@@ -1413,8 +1558,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1413
1558
|
),
|
|
1414
1559
|
"Load each stroke"
|
|
1415
1560
|
] }),
|
|
1416
|
-
/* @__PURE__ */
|
|
1417
|
-
/* @__PURE__ */
|
|
1561
|
+
/* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
|
|
1562
|
+
/* @__PURE__ */ jsx9(
|
|
1418
1563
|
"input",
|
|
1419
1564
|
{
|
|
1420
1565
|
type: "checkbox",
|
|
@@ -1428,14 +1573,14 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1428
1573
|
] })
|
|
1429
1574
|
] })
|
|
1430
1575
|
] }),
|
|
1431
|
-
isRetouchPaintTool(tool) && /* @__PURE__ */
|
|
1432
|
-
(tool === "clone" || tool === "heal") && /* @__PURE__ */
|
|
1433
|
-
/* @__PURE__ */
|
|
1434
|
-
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" })
|
|
1435
1580
|
] }),
|
|
1436
|
-
RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => /* @__PURE__ */
|
|
1437
|
-
/* @__PURE__ */
|
|
1438
|
-
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(
|
|
1439
1584
|
"button",
|
|
1440
1585
|
{
|
|
1441
1586
|
type: "button",
|
|
@@ -1448,9 +1593,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1448
1593
|
o.id
|
|
1449
1594
|
))
|
|
1450
1595
|
] }, choice.id)),
|
|
1451
|
-
RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => /* @__PURE__ */
|
|
1452
|
-
/* @__PURE__ */
|
|
1453
|
-
/* @__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(
|
|
1454
1599
|
"input",
|
|
1455
1600
|
{
|
|
1456
1601
|
type: "checkbox",
|
|
@@ -1463,9 +1608,9 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1463
1608
|
t.label
|
|
1464
1609
|
] }, t.id)) })
|
|
1465
1610
|
] }),
|
|
1466
|
-
/* @__PURE__ */
|
|
1467
|
-
/* @__PURE__ */
|
|
1468
|
-
/* @__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(
|
|
1469
1614
|
"input",
|
|
1470
1615
|
{
|
|
1471
1616
|
type: "checkbox",
|
|
@@ -1477,8 +1622,8 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1477
1622
|
),
|
|
1478
1623
|
"Pressure size"
|
|
1479
1624
|
] }),
|
|
1480
|
-
/* @__PURE__ */
|
|
1481
|
-
/* @__PURE__ */
|
|
1625
|
+
/* @__PURE__ */ jsxs8("label", { className: "flex items-center gap-1.5", children: [
|
|
1626
|
+
/* @__PURE__ */ jsx9(
|
|
1482
1627
|
"input",
|
|
1483
1628
|
{
|
|
1484
1629
|
type: "checkbox",
|
|
@@ -1491,27 +1636,27 @@ var BrushOptionsBar = ({ controller, className }) => {
|
|
|
1491
1636
|
"Pressure opacity"
|
|
1492
1637
|
] })
|
|
1493
1638
|
] }),
|
|
1494
|
-
/* @__PURE__ */
|
|
1495
|
-
/* @__PURE__ */
|
|
1496
|
-
/* @__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" })
|
|
1497
1642
|
] }),
|
|
1498
|
-
error && /* @__PURE__ */
|
|
1643
|
+
error && /* @__PURE__ */ jsx9("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1499
1644
|
] });
|
|
1500
1645
|
};
|
|
1501
1646
|
|
|
1502
1647
|
// src/image-editor/ColorProfilePanel.tsx
|
|
1503
|
-
import { useEffect as
|
|
1648
|
+
import { useEffect as useEffect8, useState as useState9 } from "react";
|
|
1504
1649
|
import { COLOR_MODE_OPTIONS, INTENT_OPTIONS, PROOF_PROFILE_OPTIONS, WORKING_SPACE_OPTIONS, colorPanelView } from "@pixerate/editor/image-editor";
|
|
1505
|
-
import { Fragment as Fragment2, jsx as
|
|
1650
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1506
1651
|
var chip2 = "px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white";
|
|
1507
1652
|
var select = "rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200";
|
|
1508
1653
|
var ColorProfilePanel = ({ controller, className }) => {
|
|
1509
|
-
const [, setTick] =
|
|
1510
|
-
|
|
1511
|
-
const [target, setTarget] =
|
|
1512
|
-
const [intent, setIntent] =
|
|
1513
|
-
const [bpc, setBpc] =
|
|
1514
|
-
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);
|
|
1515
1660
|
const view = colorPanelView(controller);
|
|
1516
1661
|
const attempt = (fn) => {
|
|
1517
1662
|
try {
|
|
@@ -1533,29 +1678,29 @@ var ColorProfilePanel = ({ controller, className }) => {
|
|
|
1533
1678
|
})
|
|
1534
1679
|
);
|
|
1535
1680
|
};
|
|
1536
|
-
return /* @__PURE__ */
|
|
1537
|
-
/* @__PURE__ */
|
|
1538
|
-
/* @__PURE__ */
|
|
1539
|
-
/* @__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 })
|
|
1540
1685
|
] }),
|
|
1541
|
-
/* @__PURE__ */
|
|
1542
|
-
/* @__PURE__ */
|
|
1543
|
-
/* @__PURE__ */
|
|
1544
|
-
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 })
|
|
1545
1690
|
] }),
|
|
1546
|
-
/* @__PURE__ */
|
|
1547
|
-
/* @__PURE__ */
|
|
1548
|
-
/* @__PURE__ */
|
|
1549
|
-
/* @__PURE__ */
|
|
1550
|
-
/* @__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" }),
|
|
1551
1696
|
"BPC"
|
|
1552
1697
|
] }),
|
|
1553
|
-
/* @__PURE__ */
|
|
1554
|
-
/* @__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" })
|
|
1555
1700
|
] }),
|
|
1556
|
-
/* @__PURE__ */
|
|
1557
|
-
/* @__PURE__ */
|
|
1558
|
-
/* @__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(
|
|
1559
1704
|
"select",
|
|
1560
1705
|
{
|
|
1561
1706
|
"aria-label": "Proof profile",
|
|
@@ -1563,36 +1708,36 @@ var ColorProfilePanel = ({ controller, className }) => {
|
|
|
1563
1708
|
value: view.proof?.id ?? "",
|
|
1564
1709
|
onChange: (e) => e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)),
|
|
1565
1710
|
children: [
|
|
1566
|
-
/* @__PURE__ */
|
|
1567
|
-
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))
|
|
1568
1713
|
]
|
|
1569
1714
|
}
|
|
1570
1715
|
),
|
|
1571
|
-
view.proof && /* @__PURE__ */
|
|
1572
|
-
/* @__PURE__ */
|
|
1573
|
-
/* @__PURE__ */
|
|
1574
|
-
/* @__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" }),
|
|
1575
1720
|
"Paper"
|
|
1576
1721
|
] }),
|
|
1577
|
-
/* @__PURE__ */
|
|
1578
|
-
/* @__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" }),
|
|
1579
1724
|
"Gamut warning"
|
|
1580
1725
|
] })
|
|
1581
1726
|
] })
|
|
1582
1727
|
] }),
|
|
1583
|
-
error && /* @__PURE__ */
|
|
1728
|
+
error && /* @__PURE__ */ jsx10("p", { role: "alert", className: "text-rose-400", children: error })
|
|
1584
1729
|
] });
|
|
1585
1730
|
};
|
|
1586
1731
|
|
|
1587
1732
|
// src/image-editor/SelectionOptionsBar.tsx
|
|
1588
|
-
import { useState as
|
|
1733
|
+
import { useState as useState10 } from "react";
|
|
1589
1734
|
import {
|
|
1590
1735
|
SELECTION_MODES,
|
|
1591
1736
|
SELECTION_MODE_LABELS,
|
|
1592
1737
|
SELECTION_TOOLS,
|
|
1593
1738
|
describeSelection
|
|
1594
1739
|
} from "@pixerate/editor/image-editor";
|
|
1595
|
-
import { jsx as
|
|
1740
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1596
1741
|
var MODIFY_OPS = [
|
|
1597
1742
|
{ op: "grow", label: "Grow" },
|
|
1598
1743
|
{ op: "shrink", label: "Shrink" },
|
|
@@ -1600,7 +1745,7 @@ var MODIFY_OPS = [
|
|
|
1600
1745
|
{ op: "border", label: "Border" },
|
|
1601
1746
|
{ op: "smooth", label: "Smooth" }
|
|
1602
1747
|
];
|
|
1603
|
-
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"}`;
|
|
1604
1749
|
var SelectionOptionsBar = ({
|
|
1605
1750
|
controller,
|
|
1606
1751
|
options,
|
|
@@ -1609,20 +1754,20 @@ var SelectionOptionsBar = ({
|
|
|
1609
1754
|
quickMask,
|
|
1610
1755
|
className = ""
|
|
1611
1756
|
}) => {
|
|
1612
|
-
const [radius, setRadius] =
|
|
1757
|
+
const [radius, setRadius] = useState10(2);
|
|
1613
1758
|
const set = (patch) => onOptionsChange({ ...options, ...patch });
|
|
1614
1759
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
1615
1760
|
const qm = quickMask ?? Boolean(controller.getState().quickMask);
|
|
1616
|
-
return /* @__PURE__ */
|
|
1617
|
-
/* @__PURE__ */
|
|
1618
|
-
/* @__PURE__ */
|
|
1619
|
-
options.tool === "wand" && /* @__PURE__ */
|
|
1620
|
-
/* @__PURE__ */
|
|
1621
|
-
/* @__PURE__ */
|
|
1622
|
-
/* @__PURE__ */
|
|
1623
|
-
/* @__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 })
|
|
1624
1769
|
] }),
|
|
1625
|
-
/* @__PURE__ */
|
|
1770
|
+
/* @__PURE__ */ jsx11(
|
|
1626
1771
|
"input",
|
|
1627
1772
|
{
|
|
1628
1773
|
type: "range",
|
|
@@ -1636,17 +1781,17 @@ var SelectionOptionsBar = ({
|
|
|
1636
1781
|
}
|
|
1637
1782
|
)
|
|
1638
1783
|
] }),
|
|
1639
|
-
/* @__PURE__ */
|
|
1640
|
-
/* @__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 }) }),
|
|
1641
1786
|
"Contiguous"
|
|
1642
1787
|
] }),
|
|
1643
|
-
/* @__PURE__ */
|
|
1644
|
-
/* @__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 }) }),
|
|
1645
1790
|
"Sample adjusted image"
|
|
1646
1791
|
] }),
|
|
1647
|
-
/* @__PURE__ */
|
|
1792
|
+
/* @__PURE__ */ jsxs10("label", { className: "flex items-center gap-2 text-slate-300", children: [
|
|
1648
1793
|
"Sample",
|
|
1649
|
-
/* @__PURE__ */
|
|
1794
|
+
/* @__PURE__ */ jsxs10(
|
|
1650
1795
|
"select",
|
|
1651
1796
|
{
|
|
1652
1797
|
"aria-label": "Sample from",
|
|
@@ -1654,27 +1799,27 @@ var SelectionOptionsBar = ({
|
|
|
1654
1799
|
onChange: (e) => set({ sample: e.target.value }),
|
|
1655
1800
|
className: "bg-slate-800 border border-slate-700 rounded px-1 py-0.5",
|
|
1656
1801
|
children: [
|
|
1657
|
-
/* @__PURE__ */
|
|
1658
|
-
/* @__PURE__ */
|
|
1802
|
+
/* @__PURE__ */ jsx11("option", { value: "composite", children: "All layers" }),
|
|
1803
|
+
/* @__PURE__ */ jsx11("option", { value: "active-layer", children: "Active layer" })
|
|
1659
1804
|
]
|
|
1660
1805
|
}
|
|
1661
1806
|
)
|
|
1662
1807
|
] })
|
|
1663
1808
|
] }),
|
|
1664
|
-
/* @__PURE__ */
|
|
1665
|
-
/* @__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 }) }),
|
|
1666
1811
|
"Anti-alias"
|
|
1667
1812
|
] }),
|
|
1668
|
-
/* @__PURE__ */
|
|
1669
|
-
/* @__PURE__ */
|
|
1670
|
-
/* @__PURE__ */
|
|
1671
|
-
/* @__PURE__ */
|
|
1672
|
-
/* @__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" })
|
|
1673
1818
|
] }),
|
|
1674
|
-
/* @__PURE__ */
|
|
1675
|
-
/* @__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: [
|
|
1676
1821
|
"Radius",
|
|
1677
|
-
/* @__PURE__ */
|
|
1822
|
+
/* @__PURE__ */ jsx11(
|
|
1678
1823
|
"input",
|
|
1679
1824
|
{
|
|
1680
1825
|
type: "number",
|
|
@@ -1688,29 +1833,29 @@ var SelectionOptionsBar = ({
|
|
|
1688
1833
|
}
|
|
1689
1834
|
)
|
|
1690
1835
|
] }),
|
|
1691
|
-
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))
|
|
1692
1837
|
] }),
|
|
1693
|
-
/* @__PURE__ */
|
|
1838
|
+
/* @__PURE__ */ jsx11("p", { "data-testid": "selection-status", className: "text-slate-400", children: describeSelection(sel) })
|
|
1694
1839
|
] });
|
|
1695
1840
|
};
|
|
1696
1841
|
|
|
1697
1842
|
// src/image-editor/RefineEdgePanel.tsx
|
|
1698
|
-
import { useState as
|
|
1843
|
+
import { useState as useState11 } from "react";
|
|
1699
1844
|
import {
|
|
1700
1845
|
ADJUSTMENT_KINDS as ADJUSTMENT_KINDS2,
|
|
1701
1846
|
REFINE_EDGE_CONTROLS,
|
|
1702
1847
|
adjustmentKindLabel as adjustmentKindLabel2,
|
|
1703
1848
|
layerMaskFromSelection
|
|
1704
1849
|
} from "@pixerate/editor/image-editor";
|
|
1705
|
-
import { Fragment as Fragment3, jsx as
|
|
1850
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1706
1851
|
var DEFAULT_PARAMS = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };
|
|
1707
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";
|
|
1708
1853
|
var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
1709
|
-
const [params, setParams] =
|
|
1710
|
-
const [busy, setBusy] =
|
|
1711
|
-
const [error, setError] =
|
|
1712
|
-
const [layerId, setLayerId] =
|
|
1713
|
-
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");
|
|
1714
1859
|
const sel = selection === void 0 ? controller.getSelection() : selection;
|
|
1715
1860
|
const list = layers ?? controller.getAdjustmentLayers();
|
|
1716
1861
|
const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];
|
|
@@ -1725,17 +1870,17 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1725
1870
|
setBusy(false);
|
|
1726
1871
|
}
|
|
1727
1872
|
};
|
|
1728
|
-
return /* @__PURE__ */
|
|
1729
|
-
/* @__PURE__ */
|
|
1730
|
-
REFINE_EDGE_CONTROLS.map((c) => /* @__PURE__ */
|
|
1731
|
-
/* @__PURE__ */
|
|
1732
|
-
/* @__PURE__ */
|
|
1733
|
-
/* @__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: [
|
|
1734
1879
|
params[c.id],
|
|
1735
1880
|
c.unit
|
|
1736
1881
|
] })
|
|
1737
1882
|
] }),
|
|
1738
|
-
/* @__PURE__ */
|
|
1883
|
+
/* @__PURE__ */ jsx12(
|
|
1739
1884
|
"input",
|
|
1740
1885
|
{
|
|
1741
1886
|
type: "range",
|
|
@@ -1749,28 +1894,28 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1749
1894
|
}
|
|
1750
1895
|
)
|
|
1751
1896
|
] }, c.id)),
|
|
1752
|
-
/* @__PURE__ */
|
|
1753
|
-
/* @__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 }) }),
|
|
1754
1899
|
"Smart Radius"
|
|
1755
1900
|
] }),
|
|
1756
|
-
/* @__PURE__ */
|
|
1757
|
-
/* @__PURE__ */
|
|
1758
|
-
/* @__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" })
|
|
1759
1904
|
] }),
|
|
1760
|
-
error && /* @__PURE__ */
|
|
1761
|
-
/* @__PURE__ */
|
|
1762
|
-
/* @__PURE__ */
|
|
1763
|
-
/* @__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(
|
|
1764
1909
|
"select",
|
|
1765
1910
|
{
|
|
1766
1911
|
"aria-label": "New masked layer kind",
|
|
1767
1912
|
value: newKind,
|
|
1768
1913
|
onChange: (e) => setNewKind(e.target.value),
|
|
1769
1914
|
className: "flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
1770
|
-
children: ADJUSTMENT_KINDS2.map((k) => /* @__PURE__ */
|
|
1915
|
+
children: ADJUSTMENT_KINDS2.map((k) => /* @__PURE__ */ jsx12("option", { value: k.kind, children: k.label }, k.kind))
|
|
1771
1916
|
}
|
|
1772
1917
|
),
|
|
1773
|
-
/* @__PURE__ */
|
|
1918
|
+
/* @__PURE__ */ jsx12(
|
|
1774
1919
|
"button",
|
|
1775
1920
|
{
|
|
1776
1921
|
type: "button",
|
|
@@ -1781,35 +1926,35 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1781
1926
|
}
|
|
1782
1927
|
)
|
|
1783
1928
|
] }),
|
|
1784
|
-
list.length > 0 && target && /* @__PURE__ */
|
|
1785
|
-
/* @__PURE__ */
|
|
1929
|
+
list.length > 0 && target && /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-2", children: [
|
|
1930
|
+
/* @__PURE__ */ jsx12(
|
|
1786
1931
|
"select",
|
|
1787
1932
|
{
|
|
1788
1933
|
"aria-label": "Mask layer",
|
|
1789
1934
|
value: target.id,
|
|
1790
1935
|
onChange: (e) => setLayerId(e.target.value),
|
|
1791
1936
|
className: "bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200",
|
|
1792
|
-
children: list.map((l) => /* @__PURE__ */
|
|
1937
|
+
children: list.map((l) => /* @__PURE__ */ jsxs11("option", { value: l.id, children: [
|
|
1793
1938
|
l.name || adjustmentKindLabel2(l.kind),
|
|
1794
1939
|
l.mask ? " (masked)" : ""
|
|
1795
1940
|
] }, l.id))
|
|
1796
1941
|
}
|
|
1797
1942
|
),
|
|
1798
|
-
/* @__PURE__ */
|
|
1799
|
-
/* @__PURE__ */
|
|
1800
|
-
/* @__PURE__ */
|
|
1801
|
-
/* @__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" })
|
|
1802
1947
|
] }),
|
|
1803
|
-
target.mask && /* @__PURE__ */
|
|
1804
|
-
/* @__PURE__ */
|
|
1805
|
-
/* @__PURE__ */
|
|
1806
|
-
/* @__PURE__ */
|
|
1807
|
-
/* @__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: [
|
|
1808
1953
|
Math.round((target.mask.density ?? 1) * 100),
|
|
1809
1954
|
"%"
|
|
1810
1955
|
] })
|
|
1811
1956
|
] }),
|
|
1812
|
-
/* @__PURE__ */
|
|
1957
|
+
/* @__PURE__ */ jsx12(
|
|
1813
1958
|
"input",
|
|
1814
1959
|
{
|
|
1815
1960
|
type: "range",
|
|
@@ -1823,15 +1968,15 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1823
1968
|
}
|
|
1824
1969
|
)
|
|
1825
1970
|
] }),
|
|
1826
|
-
/* @__PURE__ */
|
|
1827
|
-
/* @__PURE__ */
|
|
1828
|
-
/* @__PURE__ */
|
|
1829
|
-
/* @__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: [
|
|
1830
1975
|
target.mask.feather ?? 0,
|
|
1831
1976
|
"px"
|
|
1832
1977
|
] })
|
|
1833
1978
|
] }),
|
|
1834
|
-
/* @__PURE__ */
|
|
1979
|
+
/* @__PURE__ */ jsx12(
|
|
1835
1980
|
"input",
|
|
1836
1981
|
{
|
|
1837
1982
|
type: "range",
|
|
@@ -1851,14 +1996,14 @@ var RefineEdgePanel = ({ controller, selection, layers, className = "" }) => {
|
|
|
1851
1996
|
};
|
|
1852
1997
|
|
|
1853
1998
|
// src/image-editor/FreeTransformOptionsBar.tsx
|
|
1854
|
-
import { useEffect as
|
|
1999
|
+
import { useEffect as useEffect9, useState as useState12 } from "react";
|
|
1855
2000
|
import { FREE_TRANSFORM_FIELDS, FREE_TRANSFORM_MODE_OPTIONS, INTERPOLATIONS, TRANSFORM_ANCHORS, WARP_GRID_OPTIONS, WARP_STYLE_OPTIONS } from "@pixerate/editor/image-editor";
|
|
1856
|
-
import { jsx as
|
|
2001
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1857
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"}`;
|
|
1858
2003
|
var round = (v, unit) => unit === "px" ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100;
|
|
1859
2004
|
var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
1860
|
-
const [, setTick] =
|
|
1861
|
-
|
|
2005
|
+
const [, setTick] = useState12(0);
|
|
2006
|
+
useEffect9(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);
|
|
1862
2007
|
const bar = tool.bar();
|
|
1863
2008
|
if (!tool.active || !bar) return null;
|
|
1864
2009
|
const warp = tool.warpBar();
|
|
@@ -1870,17 +2015,17 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1870
2015
|
const v = Number(raw);
|
|
1871
2016
|
if (raw.trim() !== "" && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);
|
|
1872
2017
|
};
|
|
1873
|
-
return /* @__PURE__ */
|
|
1874
|
-
/* @__PURE__ */
|
|
1875
|
-
/* @__PURE__ */
|
|
1876
|
-
tool.mode === "warp" && /* @__PURE__ */
|
|
1877
|
-
/* @__PURE__ */
|
|
1878
|
-
/* @__PURE__ */
|
|
1879
|
-
/* @__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)) })
|
|
1880
2025
|
] }),
|
|
1881
|
-
["bend", "horizontal", "vertical"].map((k) => /* @__PURE__ */
|
|
1882
|
-
/* @__PURE__ */
|
|
1883
|
-
/* @__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(
|
|
1884
2029
|
"input",
|
|
1885
2030
|
{
|
|
1886
2031
|
type: "number",
|
|
@@ -1901,9 +2046,9 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1901
2046
|
},
|
|
1902
2047
|
`${k}:${warp[k]}`
|
|
1903
2048
|
),
|
|
1904
|
-
/* @__PURE__ */
|
|
2049
|
+
/* @__PURE__ */ jsx13("span", { className: "text-slate-500", children: "%" })
|
|
1905
2050
|
] }, k)),
|
|
1906
|
-
/* @__PURE__ */
|
|
2051
|
+
/* @__PURE__ */ jsx13(
|
|
1907
2052
|
"button",
|
|
1908
2053
|
{
|
|
1909
2054
|
type: "button",
|
|
@@ -1915,9 +2060,9 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1915
2060
|
children: "Vertical"
|
|
1916
2061
|
}
|
|
1917
2062
|
),
|
|
1918
|
-
/* @__PURE__ */
|
|
1919
|
-
/* @__PURE__ */
|
|
1920
|
-
/* @__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(
|
|
1921
2066
|
"select",
|
|
1922
2067
|
{
|
|
1923
2068
|
"aria-label": "Warp grid",
|
|
@@ -1927,14 +2072,14 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1927
2072
|
tool.setWarp({ columns: g.columns, rows: g.rows });
|
|
1928
2073
|
},
|
|
1929
2074
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1930
|
-
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))
|
|
1931
2076
|
}
|
|
1932
2077
|
)
|
|
1933
2078
|
] })
|
|
1934
2079
|
] }),
|
|
1935
|
-
tool.mode !== "warp" && FREE_TRANSFORM_FIELDS.map((f) => /* @__PURE__ */
|
|
1936
|
-
/* @__PURE__ */
|
|
1937
|
-
/* @__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(
|
|
1938
2083
|
"input",
|
|
1939
2084
|
{
|
|
1940
2085
|
type: "number",
|
|
@@ -1954,8 +2099,8 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1954
2099
|
},
|
|
1955
2100
|
`${f.id}:${round(bar[f.id], f.unit)}`
|
|
1956
2101
|
),
|
|
1957
|
-
/* @__PURE__ */
|
|
1958
|
-
f.id === "scaleX" && /* @__PURE__ */
|
|
2102
|
+
/* @__PURE__ */ jsx13("span", { className: "text-slate-500", children: f.unit }),
|
|
2103
|
+
f.id === "scaleX" && /* @__PURE__ */ jsx13(
|
|
1959
2104
|
"button",
|
|
1960
2105
|
{
|
|
1961
2106
|
type: "button",
|
|
@@ -1970,34 +2115,34 @@ var FreeTransformOptionsBar = ({ tool, className }) => {
|
|
|
1970
2115
|
}
|
|
1971
2116
|
)
|
|
1972
2117
|
] }, f.id)),
|
|
1973
|
-
/* @__PURE__ */
|
|
1974
|
-
/* @__PURE__ */
|
|
1975
|
-
/* @__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(
|
|
1976
2121
|
"select",
|
|
1977
2122
|
{
|
|
1978
2123
|
"aria-label": "Interpolation",
|
|
1979
2124
|
value: tool.interpolation,
|
|
1980
2125
|
onChange: (e) => tool.setInterpolation(e.target.value),
|
|
1981
2126
|
className: "rounded border border-slate-700 bg-slate-900 px-1 py-0.5",
|
|
1982
|
-
children: INTERPOLATIONS.map((i) => /* @__PURE__ */
|
|
2127
|
+
children: INTERPOLATIONS.map((i) => /* @__PURE__ */ jsx13("option", { value: i, children: i[0].toUpperCase() + i.slice(1) }, i))
|
|
1983
2128
|
}
|
|
1984
2129
|
)
|
|
1985
2130
|
] }),
|
|
1986
|
-
/* @__PURE__ */
|
|
1987
|
-
/* @__PURE__ */
|
|
1988
|
-
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 })
|
|
1989
2134
|
] });
|
|
1990
2135
|
};
|
|
1991
2136
|
|
|
1992
2137
|
// src/image-editor/ShapeOptionsBar.tsx
|
|
1993
|
-
import { useEffect as
|
|
2138
|
+
import { useEffect as useEffect10, useState as useState13 } from "react";
|
|
1994
2139
|
import { LIVE_SHAPE_KINDS, SHAPE_KIND_LABELS, applyShapeOptions } from "@pixerate/editor/image-editor";
|
|
1995
|
-
import { Fragment as Fragment4, jsx as
|
|
2140
|
+
import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1996
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"}`;
|
|
1997
2142
|
var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
1998
|
-
const [, setTick] =
|
|
1999
|
-
|
|
2000
|
-
const [error, setError] =
|
|
2143
|
+
const [, setTick] = useState13(0);
|
|
2144
|
+
useEffect10(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);
|
|
2145
|
+
const [error, setError] = useState13(null);
|
|
2001
2146
|
const active = controller.getActiveLayer();
|
|
2002
2147
|
const shapeId = active?.type === "shape" ? active.id : null;
|
|
2003
2148
|
const set = (change) => {
|
|
@@ -2011,13 +2156,13 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2011
2156
|
}
|
|
2012
2157
|
};
|
|
2013
2158
|
const num = (v, min, max) => Math.max(min, Math.min(max, Number(v) || min));
|
|
2014
|
-
return /* @__PURE__ */
|
|
2015
|
-
/* @__PURE__ */
|
|
2016
|
-
/* @__PURE__ */
|
|
2017
|
-
/* @__PURE__ */
|
|
2018
|
-
/* @__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 }) }),
|
|
2019
2164
|
"Fill",
|
|
2020
|
-
/* @__PURE__ */
|
|
2165
|
+
/* @__PURE__ */ jsx14(
|
|
2021
2166
|
"input",
|
|
2022
2167
|
{
|
|
2023
2168
|
type: "color",
|
|
@@ -2029,10 +2174,10 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2029
2174
|
}
|
|
2030
2175
|
)
|
|
2031
2176
|
] }),
|
|
2032
|
-
/* @__PURE__ */
|
|
2033
|
-
/* @__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 }) }),
|
|
2034
2179
|
"Stroke",
|
|
2035
|
-
/* @__PURE__ */
|
|
2180
|
+
/* @__PURE__ */ jsx14(
|
|
2036
2181
|
"input",
|
|
2037
2182
|
{
|
|
2038
2183
|
type: "color",
|
|
@@ -2044,9 +2189,9 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2044
2189
|
}
|
|
2045
2190
|
)
|
|
2046
2191
|
] }),
|
|
2047
|
-
/* @__PURE__ */
|
|
2192
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2048
2193
|
"Width",
|
|
2049
|
-
/* @__PURE__ */
|
|
2194
|
+
/* @__PURE__ */ jsx14(
|
|
2050
2195
|
"input",
|
|
2051
2196
|
{
|
|
2052
2197
|
type: "number",
|
|
@@ -2060,23 +2205,23 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2060
2205
|
)
|
|
2061
2206
|
] })
|
|
2062
2207
|
] }),
|
|
2063
|
-
/* @__PURE__ */
|
|
2064
|
-
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: [
|
|
2065
2210
|
"Radius",
|
|
2066
|
-
/* @__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" })
|
|
2067
2212
|
] }),
|
|
2068
|
-
options.kind === "polygon" && /* @__PURE__ */
|
|
2213
|
+
options.kind === "polygon" && /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2069
2214
|
"Sides",
|
|
2070
|
-
/* @__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" })
|
|
2071
2216
|
] }),
|
|
2072
|
-
options.kind === "star" && /* @__PURE__ */
|
|
2073
|
-
/* @__PURE__ */
|
|
2217
|
+
options.kind === "star" && /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
2218
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2074
2219
|
"Points",
|
|
2075
|
-
/* @__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" })
|
|
2076
2221
|
] }),
|
|
2077
|
-
/* @__PURE__ */
|
|
2222
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2078
2223
|
"Inner",
|
|
2079
|
-
/* @__PURE__ */
|
|
2224
|
+
/* @__PURE__ */ jsx14(
|
|
2080
2225
|
"input",
|
|
2081
2226
|
{
|
|
2082
2227
|
type: "range",
|
|
@@ -2091,33 +2236,33 @@ var ShapeOptionsBar = ({ controller, options, onChange, className }) => {
|
|
|
2091
2236
|
)
|
|
2092
2237
|
] })
|
|
2093
2238
|
] }),
|
|
2094
|
-
options.kind === "line" && /* @__PURE__ */
|
|
2095
|
-
/* @__PURE__ */
|
|
2239
|
+
options.kind === "line" && /* @__PURE__ */ jsxs13(Fragment4, { children: [
|
|
2240
|
+
/* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-1", children: [
|
|
2096
2241
|
"Weight",
|
|
2097
|
-
/* @__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" })
|
|
2098
2243
|
] }),
|
|
2099
|
-
/* @__PURE__ */
|
|
2100
|
-
/* @__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 }) }),
|
|
2101
2246
|
"Arrowhead"
|
|
2102
2247
|
] })
|
|
2103
2248
|
] })
|
|
2104
2249
|
] }),
|
|
2105
|
-
/* @__PURE__ */
|
|
2106
|
-
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 })
|
|
2107
2252
|
] });
|
|
2108
2253
|
};
|
|
2109
2254
|
|
|
2110
2255
|
// src/image-editor/TypeOptionsBar.tsx
|
|
2111
|
-
import { useEffect as
|
|
2256
|
+
import { useEffect as useEffect11, useState as useState14 } from "react";
|
|
2112
2257
|
import { TEXT_ALIGNS } from "@pixerate/editor/image-editor";
|
|
2113
|
-
import { jsx as
|
|
2258
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2114
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"}`;
|
|
2115
2260
|
var ALIGN_LABELS = { left: "Left", center: "Centre", right: "Right", justify: "Justify" };
|
|
2116
2261
|
var TypeOptionsBar = ({ controller, options, onChange, session, className }) => {
|
|
2117
|
-
const [, setTick] =
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
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);
|
|
2121
2266
|
const active = controller.getActiveLayer();
|
|
2122
2267
|
const typeId = !session && active?.type === "type" ? active.id : null;
|
|
2123
2268
|
const here = session?.alive ? session.styleHere() : {};
|
|
@@ -2149,11 +2294,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2149
2294
|
setError(e instanceof Error ? e.message : String(e));
|
|
2150
2295
|
}
|
|
2151
2296
|
};
|
|
2152
|
-
return /* @__PURE__ */
|
|
2153
|
-
/* @__PURE__ */
|
|
2154
|
-
/* @__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: [
|
|
2155
2300
|
"Font",
|
|
2156
|
-
/* @__PURE__ */
|
|
2301
|
+
/* @__PURE__ */ jsx15(
|
|
2157
2302
|
"input",
|
|
2158
2303
|
{
|
|
2159
2304
|
list: "pixerate-type-fonts",
|
|
@@ -2163,11 +2308,11 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2163
2308
|
className: "w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5"
|
|
2164
2309
|
}
|
|
2165
2310
|
),
|
|
2166
|
-
/* @__PURE__ */
|
|
2311
|
+
/* @__PURE__ */ jsx15("datalist", { id: "pixerate-type-fonts", children: fonts.map((f) => /* @__PURE__ */ jsx15("option", { value: f }, f)) })
|
|
2167
2312
|
] }),
|
|
2168
|
-
/* @__PURE__ */
|
|
2313
|
+
/* @__PURE__ */ jsxs14("label", { className: "flex items-center gap-1", children: [
|
|
2169
2314
|
"Size",
|
|
2170
|
-
/* @__PURE__ */
|
|
2315
|
+
/* @__PURE__ */ jsx15(
|
|
2171
2316
|
"input",
|
|
2172
2317
|
{
|
|
2173
2318
|
type: "number",
|
|
@@ -2180,24 +2325,24 @@ var TypeOptionsBar = ({ controller, options, onChange, session, className }) =>
|
|
|
2180
2325
|
}
|
|
2181
2326
|
)
|
|
2182
2327
|
] }),
|
|
2183
|
-
/* @__PURE__ */
|
|
2184
|
-
/* @__PURE__ */
|
|
2185
|
-
/* @__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" })
|
|
2186
2331
|
] }),
|
|
2187
|
-
/* @__PURE__ */
|
|
2188
|
-
/* @__PURE__ */
|
|
2189
|
-
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: [
|
|
2190
2335
|
"Missing ",
|
|
2191
2336
|
missing.length === 1 ? "font" : "fonts",
|
|
2192
2337
|
": ",
|
|
2193
2338
|
missing.join(", ")
|
|
2194
2339
|
] }),
|
|
2195
|
-
error && /* @__PURE__ */
|
|
2340
|
+
error && /* @__PURE__ */ jsx15("p", { role: "alert", className: "text-rose-400", children: error })
|
|
2196
2341
|
] });
|
|
2197
2342
|
};
|
|
2198
2343
|
|
|
2199
2344
|
// src/image-editor/ImageEditor.tsx
|
|
2200
|
-
import { Fragment as Fragment5, jsx as
|
|
2345
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2201
2346
|
var ImageEditor = ({
|
|
2202
2347
|
editor: externalEditor,
|
|
2203
2348
|
src,
|
|
@@ -2207,17 +2352,22 @@ var ImageEditor = ({
|
|
|
2207
2352
|
exportOptions,
|
|
2208
2353
|
onInpaint,
|
|
2209
2354
|
onRemoveBackground,
|
|
2210
|
-
aiHooks
|
|
2355
|
+
aiHooks,
|
|
2356
|
+
effects
|
|
2211
2357
|
}) => {
|
|
2212
2358
|
const internalEditor = useImageEditor({ image: src });
|
|
2213
2359
|
const editor = externalEditor || internalEditor;
|
|
2214
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
|
+
});
|
|
2215
2365
|
const legacyProcess = normalizeProcessVersion(state.adjustments.process) < LATEST_PROCESS_VERSION;
|
|
2216
2366
|
const canvasRef = useRef5(null);
|
|
2217
2367
|
const containerRef = useRef5(null);
|
|
2218
|
-
const [activeTab, setActiveTab] =
|
|
2219
|
-
const [activeCropRatio, setActiveCropRatio] =
|
|
2220
|
-
const [selectionOptions, setSelectionOptions] =
|
|
2368
|
+
const [activeTab, setActiveTab] = useState15("crop");
|
|
2369
|
+
const [activeCropRatio, setActiveCropRatio] = useState15(null);
|
|
2370
|
+
const [selectionOptions, setSelectionOptions] = useState15(DEFAULT_SELECTION_TOOL_OPTIONS);
|
|
2221
2371
|
const selectionOptionsRef = useRef5(selectionOptions);
|
|
2222
2372
|
selectionOptionsRef.current = selectionOptions;
|
|
2223
2373
|
const selectionGestureRef = useRef5(null);
|
|
@@ -2225,7 +2375,7 @@ var ImageEditor = ({
|
|
|
2225
2375
|
selectionGestureRef.current = new SelectionGesture(controller, () => selectionOptionsRef.current);
|
|
2226
2376
|
}
|
|
2227
2377
|
const selectionDraftRef = useRef5(null);
|
|
2228
|
-
const [selectionError, setSelectionError] =
|
|
2378
|
+
const [selectionError, setSelectionError] = useState15(null);
|
|
2229
2379
|
const paintGestureRef = useRef5(null);
|
|
2230
2380
|
const paintControllerRef = useRef5(controller);
|
|
2231
2381
|
if (!paintGestureRef.current || paintControllerRef.current !== controller) {
|
|
@@ -2233,7 +2383,7 @@ var ImageEditor = ({
|
|
|
2233
2383
|
paintControllerRef.current = controller;
|
|
2234
2384
|
}
|
|
2235
2385
|
const brushCursorRef = useRef5(null);
|
|
2236
|
-
const [paintError, setPaintError] =
|
|
2386
|
+
const [paintError, setPaintError] = useState15(null);
|
|
2237
2387
|
const transformToolRef = useRef5(null);
|
|
2238
2388
|
const transformControllerRef = useRef5(controller);
|
|
2239
2389
|
if (!transformToolRef.current || transformControllerRef.current !== controller) {
|
|
@@ -2244,12 +2394,12 @@ var ImageEditor = ({
|
|
|
2244
2394
|
transformControllerRef.current = controller;
|
|
2245
2395
|
}
|
|
2246
2396
|
const transformTool = transformToolRef.current;
|
|
2247
|
-
const [, setTransformTick] =
|
|
2248
|
-
const [transformCursor, setTransformCursor] =
|
|
2249
|
-
const [shapeOptions, setShapeOptions] =
|
|
2397
|
+
const [, setTransformTick] = useState15(0);
|
|
2398
|
+
const [transformCursor, setTransformCursor] = useState15("default");
|
|
2399
|
+
const [shapeOptions, setShapeOptions] = useState15(DEFAULT_SHAPE_TOOL_OPTIONS);
|
|
2250
2400
|
const shapeOptionsRef = useRef5(shapeOptions);
|
|
2251
2401
|
shapeOptionsRef.current = shapeOptions;
|
|
2252
|
-
const [typeOptions, setTypeOptions] =
|
|
2402
|
+
const [typeOptions, setTypeOptions] = useState15(DEFAULT_TYPE_TOOL_OPTIONS);
|
|
2253
2403
|
const typeOptionsRef = useRef5(typeOptions);
|
|
2254
2404
|
typeOptionsRef.current = typeOptions;
|
|
2255
2405
|
const shapeGestureRef = useRef5(null);
|
|
@@ -2262,15 +2412,15 @@ var ImageEditor = ({
|
|
|
2262
2412
|
shapeTypeControllerRef.current = controller;
|
|
2263
2413
|
}
|
|
2264
2414
|
const typeInputRef = useRef5(null);
|
|
2265
|
-
const [typeSession, setTypeSession] =
|
|
2266
|
-
const [shapeTypeError, setShapeTypeError] =
|
|
2267
|
-
const [inpaintPrompt, setInpaintPrompt] =
|
|
2268
|
-
const [inpaintMaskMode, setInpaintMaskMode] =
|
|
2269
|
-
const [isRemovingBg, setIsRemovingBg] =
|
|
2270
|
-
const [isInpainting, setIsInpainting] =
|
|
2271
|
-
const [aiError, setAiError] =
|
|
2272
|
-
const [aiSuccess, setAiSuccess] =
|
|
2273
|
-
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");
|
|
2274
2424
|
const aiOptions = aiTarget === "auto" ? {} : { target: aiTarget };
|
|
2275
2425
|
const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;
|
|
2276
2426
|
const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;
|
|
@@ -2333,10 +2483,10 @@ var ImageEditor = ({
|
|
|
2333
2483
|
setIsInpainting(false);
|
|
2334
2484
|
}
|
|
2335
2485
|
};
|
|
2336
|
-
const [activeColor, setActiveColor] =
|
|
2337
|
-
const [strokeWidth, setStrokeWidth] =
|
|
2338
|
-
const [fontSize, setFontSize] =
|
|
2339
|
-
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("");
|
|
2340
2490
|
const draftAnnotationRef = useRef5(null);
|
|
2341
2491
|
const draftCropRef = useRef5(null);
|
|
2342
2492
|
const cropDragInfoRef = useRef5(null);
|
|
@@ -2367,8 +2517,8 @@ var ImageEditor = ({
|
|
|
2367
2517
|
},
|
|
2368
2518
|
[controller, activeTab, transformTool]
|
|
2369
2519
|
);
|
|
2370
|
-
|
|
2371
|
-
|
|
2520
|
+
useEffect12(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);
|
|
2521
|
+
useEffect12(() => {
|
|
2372
2522
|
if (activeTab === "annotate" && state.activeTool === "type") return;
|
|
2373
2523
|
if (typeToolRef.current?.session) {
|
|
2374
2524
|
typeToolRef.current.finish();
|
|
@@ -2403,7 +2553,7 @@ var ImageEditor = ({
|
|
|
2403
2553
|
el.value = "";
|
|
2404
2554
|
}
|
|
2405
2555
|
};
|
|
2406
|
-
|
|
2556
|
+
useEffect12(() => transformTool.subscribe(() => {
|
|
2407
2557
|
setTransformTick((n) => n + 1);
|
|
2408
2558
|
void renderCanvas();
|
|
2409
2559
|
}), [transformTool, renderCanvas]);
|
|
@@ -2446,7 +2596,7 @@ var ImageEditor = ({
|
|
|
2446
2596
|
transformTool.up();
|
|
2447
2597
|
return true;
|
|
2448
2598
|
};
|
|
2449
|
-
|
|
2599
|
+
useEffect12(() => {
|
|
2450
2600
|
if (typeof window === "undefined") return;
|
|
2451
2601
|
const onKey = (e) => {
|
|
2452
2602
|
if (transformTool.key(e)) e.preventDefault();
|
|
@@ -2454,7 +2604,7 @@ var ImageEditor = ({
|
|
|
2454
2604
|
window.addEventListener("keydown", onKey);
|
|
2455
2605
|
return () => window.removeEventListener("keydown", onKey);
|
|
2456
2606
|
}, [transformTool]);
|
|
2457
|
-
|
|
2607
|
+
useEffect12(() => {
|
|
2458
2608
|
const raf = typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : (cb) => setTimeout(cb, 0);
|
|
2459
2609
|
const caf = typeof cancelAnimationFrame !== "undefined" ? cancelAnimationFrame : (id) => clearTimeout(id);
|
|
2460
2610
|
const animId = raf(() => {
|
|
@@ -2462,12 +2612,12 @@ var ImageEditor = ({
|
|
|
2462
2612
|
});
|
|
2463
2613
|
return () => caf(animId);
|
|
2464
2614
|
}, [renderCanvas, state]);
|
|
2465
|
-
|
|
2615
|
+
useEffect12(() => {
|
|
2466
2616
|
if (activeTab === "crop" && editor.state.activeTool !== "crop") {
|
|
2467
2617
|
editor.setTool("crop");
|
|
2468
2618
|
}
|
|
2469
2619
|
}, [activeTab, editor]);
|
|
2470
|
-
|
|
2620
|
+
useEffect12(() => {
|
|
2471
2621
|
const container = containerRef.current;
|
|
2472
2622
|
if (!container) return;
|
|
2473
2623
|
if (typeof ResizeObserver !== "undefined") {
|
|
@@ -2535,7 +2685,7 @@ var ImageEditor = ({
|
|
|
2535
2685
|
if (g.error) setPaintError(g.error);
|
|
2536
2686
|
}
|
|
2537
2687
|
};
|
|
2538
|
-
|
|
2688
|
+
useEffect12(() => {
|
|
2539
2689
|
if (activeTab !== "paint" || typeof window === "undefined") return;
|
|
2540
2690
|
const onKey = (e) => {
|
|
2541
2691
|
if (handlePaintShortcut(controller, e)) e.preventDefault();
|
|
@@ -2930,15 +3080,15 @@ var ImageEditor = ({
|
|
|
2930
3080
|
link.click();
|
|
2931
3081
|
}
|
|
2932
3082
|
};
|
|
2933
|
-
return /* @__PURE__ */
|
|
3083
|
+
return /* @__PURE__ */ jsxs15(
|
|
2934
3084
|
"div",
|
|
2935
3085
|
{
|
|
2936
3086
|
className: `flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`,
|
|
2937
3087
|
style,
|
|
2938
3088
|
children: [
|
|
2939
|
-
/* @__PURE__ */
|
|
2940
|
-
/* @__PURE__ */
|
|
2941
|
-
/* @__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(
|
|
2942
3092
|
"button",
|
|
2943
3093
|
{
|
|
2944
3094
|
type: "button",
|
|
@@ -2950,7 +3100,7 @@ var ImageEditor = ({
|
|
|
2950
3100
|
children: "Transform & Crop"
|
|
2951
3101
|
}
|
|
2952
3102
|
),
|
|
2953
|
-
/* @__PURE__ */
|
|
3103
|
+
/* @__PURE__ */ jsx16(
|
|
2954
3104
|
"button",
|
|
2955
3105
|
{
|
|
2956
3106
|
type: "button",
|
|
@@ -2962,7 +3112,7 @@ var ImageEditor = ({
|
|
|
2962
3112
|
children: "Adjustments"
|
|
2963
3113
|
}
|
|
2964
3114
|
),
|
|
2965
|
-
/* @__PURE__ */
|
|
3115
|
+
/* @__PURE__ */ jsx16(
|
|
2966
3116
|
"button",
|
|
2967
3117
|
{
|
|
2968
3118
|
type: "button",
|
|
@@ -2974,7 +3124,7 @@ var ImageEditor = ({
|
|
|
2974
3124
|
children: "Layers"
|
|
2975
3125
|
}
|
|
2976
3126
|
),
|
|
2977
|
-
/* @__PURE__ */
|
|
3127
|
+
/* @__PURE__ */ jsx16(
|
|
2978
3128
|
"button",
|
|
2979
3129
|
{
|
|
2980
3130
|
type: "button",
|
|
@@ -2986,7 +3136,7 @@ var ImageEditor = ({
|
|
|
2986
3136
|
children: "Paint"
|
|
2987
3137
|
}
|
|
2988
3138
|
),
|
|
2989
|
-
/* @__PURE__ */
|
|
3139
|
+
/* @__PURE__ */ jsx16(
|
|
2990
3140
|
"button",
|
|
2991
3141
|
{
|
|
2992
3142
|
type: "button",
|
|
@@ -2998,7 +3148,7 @@ var ImageEditor = ({
|
|
|
2998
3148
|
children: "Select & Mask"
|
|
2999
3149
|
}
|
|
3000
3150
|
),
|
|
3001
|
-
/* @__PURE__ */
|
|
3151
|
+
/* @__PURE__ */ jsx16(
|
|
3002
3152
|
"button",
|
|
3003
3153
|
{
|
|
3004
3154
|
type: "button",
|
|
@@ -3010,7 +3160,7 @@ var ImageEditor = ({
|
|
|
3010
3160
|
children: "Annotations"
|
|
3011
3161
|
}
|
|
3012
3162
|
),
|
|
3013
|
-
/* @__PURE__ */
|
|
3163
|
+
/* @__PURE__ */ jsx16(
|
|
3014
3164
|
"button",
|
|
3015
3165
|
{
|
|
3016
3166
|
type: "button",
|
|
@@ -3022,7 +3172,7 @@ var ImageEditor = ({
|
|
|
3022
3172
|
children: "Depth Mask"
|
|
3023
3173
|
}
|
|
3024
3174
|
),
|
|
3025
|
-
/* @__PURE__ */
|
|
3175
|
+
/* @__PURE__ */ jsxs15(
|
|
3026
3176
|
"button",
|
|
3027
3177
|
{
|
|
3028
3178
|
type: "button",
|
|
@@ -3032,14 +3182,14 @@ var ImageEditor = ({
|
|
|
3032
3182
|
},
|
|
3033
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"}`,
|
|
3034
3184
|
children: [
|
|
3035
|
-
/* @__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" }) }),
|
|
3036
3186
|
"AI Tools"
|
|
3037
3187
|
]
|
|
3038
3188
|
}
|
|
3039
3189
|
)
|
|
3040
3190
|
] }),
|
|
3041
|
-
/* @__PURE__ */
|
|
3042
|
-
/* @__PURE__ */
|
|
3191
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
3192
|
+
/* @__PURE__ */ jsx16(
|
|
3043
3193
|
"button",
|
|
3044
3194
|
{
|
|
3045
3195
|
type: "button",
|
|
@@ -3050,7 +3200,7 @@ var ImageEditor = ({
|
|
|
3050
3200
|
children: "\u21A9"
|
|
3051
3201
|
}
|
|
3052
3202
|
),
|
|
3053
|
-
/* @__PURE__ */
|
|
3203
|
+
/* @__PURE__ */ jsx16(
|
|
3054
3204
|
"button",
|
|
3055
3205
|
{
|
|
3056
3206
|
type: "button",
|
|
@@ -3061,7 +3211,7 @@ var ImageEditor = ({
|
|
|
3061
3211
|
children: "\u21AA"
|
|
3062
3212
|
}
|
|
3063
3213
|
),
|
|
3064
|
-
/* @__PURE__ */
|
|
3214
|
+
/* @__PURE__ */ jsx16(
|
|
3065
3215
|
"button",
|
|
3066
3216
|
{
|
|
3067
3217
|
type: "button",
|
|
@@ -3070,8 +3220,8 @@ var ImageEditor = ({
|
|
|
3070
3220
|
children: "Reset"
|
|
3071
3221
|
}
|
|
3072
3222
|
),
|
|
3073
|
-
/* @__PURE__ */
|
|
3074
|
-
/* @__PURE__ */
|
|
3223
|
+
/* @__PURE__ */ jsx16("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
3224
|
+
/* @__PURE__ */ jsx16(
|
|
3075
3225
|
"button",
|
|
3076
3226
|
{
|
|
3077
3227
|
type: "button",
|
|
@@ -3081,11 +3231,11 @@ var ImageEditor = ({
|
|
|
3081
3231
|
children: "-"
|
|
3082
3232
|
}
|
|
3083
3233
|
),
|
|
3084
|
-
/* @__PURE__ */
|
|
3234
|
+
/* @__PURE__ */ jsxs15("span", { className: "font-mono text-slate-400 w-10 text-center", children: [
|
|
3085
3235
|
Math.round(state.zoom * 100),
|
|
3086
3236
|
"%"
|
|
3087
3237
|
] }),
|
|
3088
|
-
/* @__PURE__ */
|
|
3238
|
+
/* @__PURE__ */ jsx16(
|
|
3089
3239
|
"button",
|
|
3090
3240
|
{
|
|
3091
3241
|
type: "button",
|
|
@@ -3095,8 +3245,8 @@ var ImageEditor = ({
|
|
|
3095
3245
|
children: "+"
|
|
3096
3246
|
}
|
|
3097
3247
|
),
|
|
3098
|
-
/* @__PURE__ */
|
|
3099
|
-
/* @__PURE__ */
|
|
3248
|
+
/* @__PURE__ */ jsx16("div", { className: "h-4 w-px bg-slate-800 mx-1" }),
|
|
3249
|
+
/* @__PURE__ */ jsx16(
|
|
3100
3250
|
"button",
|
|
3101
3251
|
{
|
|
3102
3252
|
type: "button",
|
|
@@ -3107,7 +3257,7 @@ var ImageEditor = ({
|
|
|
3107
3257
|
children: "Hold Compare"
|
|
3108
3258
|
}
|
|
3109
3259
|
),
|
|
3110
|
-
/* @__PURE__ */
|
|
3260
|
+
/* @__PURE__ */ jsx16(
|
|
3111
3261
|
"button",
|
|
3112
3262
|
{
|
|
3113
3263
|
type: "button",
|
|
@@ -3118,16 +3268,16 @@ var ImageEditor = ({
|
|
|
3118
3268
|
)
|
|
3119
3269
|
] })
|
|
3120
3270
|
] }),
|
|
3121
|
-
transformTool.active && /* @__PURE__ */
|
|
3122
|
-
!transformTool.active && transformTool.error && /* @__PURE__ */
|
|
3123
|
-
/* @__PURE__ */
|
|
3124
|
-
/* @__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(
|
|
3125
3275
|
"div",
|
|
3126
3276
|
{
|
|
3127
3277
|
ref: containerRef,
|
|
3128
3278
|
className: "relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none",
|
|
3129
3279
|
children: [
|
|
3130
|
-
/* @__PURE__ */
|
|
3280
|
+
/* @__PURE__ */ jsx16(
|
|
3131
3281
|
"canvas",
|
|
3132
3282
|
{
|
|
3133
3283
|
ref: canvasRef,
|
|
@@ -3144,7 +3294,7 @@ var ImageEditor = ({
|
|
|
3144
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" : ""}`
|
|
3145
3295
|
}
|
|
3146
3296
|
),
|
|
3147
|
-
typeSession && /* @__PURE__ */
|
|
3297
|
+
typeSession && /* @__PURE__ */ jsx16(
|
|
3148
3298
|
"textarea",
|
|
3149
3299
|
{
|
|
3150
3300
|
ref: typeInputRef,
|
|
@@ -3166,11 +3316,11 @@ var ImageEditor = ({
|
|
|
3166
3316
|
]
|
|
3167
3317
|
}
|
|
3168
3318
|
),
|
|
3169
|
-
/* @__PURE__ */
|
|
3170
|
-
activeTab === "crop" && /* @__PURE__ */
|
|
3171
|
-
/* @__PURE__ */
|
|
3172
|
-
/* @__PURE__ */
|
|
3173
|
-
/* @__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(
|
|
3174
3324
|
"button",
|
|
3175
3325
|
{
|
|
3176
3326
|
type: "button",
|
|
@@ -3182,7 +3332,7 @@ var ImageEditor = ({
|
|
|
3182
3332
|
children: "Freeform"
|
|
3183
3333
|
}
|
|
3184
3334
|
),
|
|
3185
|
-
/* @__PURE__ */
|
|
3335
|
+
/* @__PURE__ */ jsx16(
|
|
3186
3336
|
"button",
|
|
3187
3337
|
{
|
|
3188
3338
|
type: "button",
|
|
@@ -3194,7 +3344,7 @@ var ImageEditor = ({
|
|
|
3194
3344
|
children: "1:1 Square"
|
|
3195
3345
|
}
|
|
3196
3346
|
),
|
|
3197
|
-
/* @__PURE__ */
|
|
3347
|
+
/* @__PURE__ */ jsx16(
|
|
3198
3348
|
"button",
|
|
3199
3349
|
{
|
|
3200
3350
|
type: "button",
|
|
@@ -3206,7 +3356,7 @@ var ImageEditor = ({
|
|
|
3206
3356
|
children: "4:3 Standard"
|
|
3207
3357
|
}
|
|
3208
3358
|
),
|
|
3209
|
-
/* @__PURE__ */
|
|
3359
|
+
/* @__PURE__ */ jsx16(
|
|
3210
3360
|
"button",
|
|
3211
3361
|
{
|
|
3212
3362
|
type: "button",
|
|
@@ -3218,7 +3368,7 @@ var ImageEditor = ({
|
|
|
3218
3368
|
children: "16:9 Wide"
|
|
3219
3369
|
}
|
|
3220
3370
|
),
|
|
3221
|
-
/* @__PURE__ */
|
|
3371
|
+
/* @__PURE__ */ jsx16(
|
|
3222
3372
|
"button",
|
|
3223
3373
|
{
|
|
3224
3374
|
type: "button",
|
|
@@ -3230,7 +3380,7 @@ var ImageEditor = ({
|
|
|
3230
3380
|
children: "3:2 Photo"
|
|
3231
3381
|
}
|
|
3232
3382
|
),
|
|
3233
|
-
/* @__PURE__ */
|
|
3383
|
+
/* @__PURE__ */ jsx16(
|
|
3234
3384
|
"button",
|
|
3235
3385
|
{
|
|
3236
3386
|
type: "button",
|
|
@@ -3243,10 +3393,10 @@ var ImageEditor = ({
|
|
|
3243
3393
|
}
|
|
3244
3394
|
)
|
|
3245
3395
|
] }),
|
|
3246
|
-
/* @__PURE__ */
|
|
3247
|
-
/* @__PURE__ */
|
|
3248
|
-
/* @__PURE__ */
|
|
3249
|
-
/* @__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(
|
|
3250
3400
|
"button",
|
|
3251
3401
|
{
|
|
3252
3402
|
type: "button",
|
|
@@ -3255,7 +3405,7 @@ var ImageEditor = ({
|
|
|
3255
3405
|
children: "Rotate -90\xB0"
|
|
3256
3406
|
}
|
|
3257
3407
|
),
|
|
3258
|
-
/* @__PURE__ */
|
|
3408
|
+
/* @__PURE__ */ jsx16(
|
|
3259
3409
|
"button",
|
|
3260
3410
|
{
|
|
3261
3411
|
type: "button",
|
|
@@ -3264,7 +3414,7 @@ var ImageEditor = ({
|
|
|
3264
3414
|
children: "Rotate +90\xB0"
|
|
3265
3415
|
}
|
|
3266
3416
|
),
|
|
3267
|
-
/* @__PURE__ */
|
|
3417
|
+
/* @__PURE__ */ jsx16(
|
|
3268
3418
|
"button",
|
|
3269
3419
|
{
|
|
3270
3420
|
type: "button",
|
|
@@ -3273,7 +3423,7 @@ var ImageEditor = ({
|
|
|
3273
3423
|
children: "Flip Horizontal"
|
|
3274
3424
|
}
|
|
3275
3425
|
),
|
|
3276
|
-
/* @__PURE__ */
|
|
3426
|
+
/* @__PURE__ */ jsx16(
|
|
3277
3427
|
"button",
|
|
3278
3428
|
{
|
|
3279
3429
|
type: "button",
|
|
@@ -3284,10 +3434,10 @@ var ImageEditor = ({
|
|
|
3284
3434
|
)
|
|
3285
3435
|
] })
|
|
3286
3436
|
] }),
|
|
3287
|
-
activeTab === "adjust" && /* @__PURE__ */
|
|
3288
|
-
/* @__PURE__ */
|
|
3289
|
-
/* @__PURE__ */
|
|
3290
|
-
/* @__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(
|
|
3291
3441
|
"button",
|
|
3292
3442
|
{
|
|
3293
3443
|
type: "button",
|
|
@@ -3297,9 +3447,9 @@ var ImageEditor = ({
|
|
|
3297
3447
|
}
|
|
3298
3448
|
)
|
|
3299
3449
|
] }),
|
|
3300
|
-
/* @__PURE__ */
|
|
3301
|
-
IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */
|
|
3302
|
-
/* @__PURE__ */
|
|
3450
|
+
/* @__PURE__ */ jsx16(Histogram, { histogram: editor.histogram }),
|
|
3451
|
+
IMAGE_ADJUSTMENT_CONTROLS.map((spec) => /* @__PURE__ */ jsxs15(React14.Fragment, { children: [
|
|
3452
|
+
/* @__PURE__ */ jsx16(
|
|
3303
3453
|
ControlSlider,
|
|
3304
3454
|
{
|
|
3305
3455
|
spec,
|
|
@@ -3308,14 +3458,14 @@ var ImageEditor = ({
|
|
|
3308
3458
|
onChange: (v) => editor.setAdjustments({ [spec.id]: v })
|
|
3309
3459
|
}
|
|
3310
3460
|
),
|
|
3311
|
-
spec.id === "tint" && legacyProcess && /* @__PURE__ */
|
|
3461
|
+
spec.id === "tint" && legacyProcess && /* @__PURE__ */ jsxs15(
|
|
3312
3462
|
"div",
|
|
3313
3463
|
{
|
|
3314
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",
|
|
3315
3465
|
"data-testid": "image-editor-process-notice",
|
|
3316
3466
|
children: [
|
|
3317
|
-
/* @__PURE__ */
|
|
3318
|
-
/* @__PURE__ */
|
|
3467
|
+
/* @__PURE__ */ jsx16("span", { children: "Legacy rendering (process 1). Tint needs the current process." }),
|
|
3468
|
+
/* @__PURE__ */ jsx16(
|
|
3319
3469
|
"button",
|
|
3320
3470
|
{
|
|
3321
3471
|
type: "button",
|
|
@@ -3328,7 +3478,7 @@ var ImageEditor = ({
|
|
|
3328
3478
|
}
|
|
3329
3479
|
)
|
|
3330
3480
|
] }, spec.id)),
|
|
3331
|
-
/* @__PURE__ */
|
|
3481
|
+
/* @__PURE__ */ jsx16("div", { className: "border-t border-slate-700/60 pt-3", children: /* @__PURE__ */ jsx16(
|
|
3332
3482
|
AdjustmentLayersPanel,
|
|
3333
3483
|
{
|
|
3334
3484
|
controller,
|
|
@@ -3337,9 +3487,9 @@ var ImageEditor = ({
|
|
|
3337
3487
|
}
|
|
3338
3488
|
) })
|
|
3339
3489
|
] }),
|
|
3340
|
-
activeTab === "layers" && /* @__PURE__ */
|
|
3341
|
-
/* @__PURE__ */
|
|
3342
|
-
/* @__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(
|
|
3343
3493
|
"button",
|
|
3344
3494
|
{
|
|
3345
3495
|
type: "button",
|
|
@@ -3350,14 +3500,15 @@ var ImageEditor = ({
|
|
|
3350
3500
|
children: "Free Transform"
|
|
3351
3501
|
}
|
|
3352
3502
|
),
|
|
3353
|
-
/* @__PURE__ */
|
|
3354
|
-
/* @__PURE__ */
|
|
3355
|
-
/* @__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 })
|
|
3356
3507
|
] }),
|
|
3357
|
-
activeTab === "paint" && /* @__PURE__ */
|
|
3358
|
-
/* @__PURE__ */
|
|
3359
|
-
/* @__PURE__ */
|
|
3360
|
-
/* @__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(
|
|
3361
3512
|
"button",
|
|
3362
3513
|
{
|
|
3363
3514
|
type: "button",
|
|
@@ -3368,12 +3519,12 @@ var ImageEditor = ({
|
|
|
3368
3519
|
children: "Free Transform"
|
|
3369
3520
|
}
|
|
3370
3521
|
),
|
|
3371
|
-
paintError && /* @__PURE__ */
|
|
3372
|
-
/* @__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 }) })
|
|
3373
3524
|
] }),
|
|
3374
|
-
activeTab === "annotate" && /* @__PURE__ */
|
|
3375
|
-
/* @__PURE__ */
|
|
3376
|
-
/* @__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(
|
|
3377
3528
|
"button",
|
|
3378
3529
|
{
|
|
3379
3530
|
type: "button",
|
|
@@ -3384,13 +3535,13 @@ var ImageEditor = ({
|
|
|
3384
3535
|
},
|
|
3385
3536
|
t
|
|
3386
3537
|
)) }),
|
|
3387
|
-
state.activeTool === "shape" && /* @__PURE__ */
|
|
3388
|
-
state.activeTool === "type" && /* @__PURE__ */
|
|
3389
|
-
state.activeTool === "type" && typeSession && /* @__PURE__ */
|
|
3390
|
-
shapeTypeError && /* @__PURE__ */
|
|
3391
|
-
/* @__PURE__ */
|
|
3392
|
-
/* @__PURE__ */
|
|
3393
|
-
/* @__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(
|
|
3394
3545
|
"button",
|
|
3395
3546
|
{
|
|
3396
3547
|
type: "button",
|
|
@@ -3400,9 +3551,9 @@ var ImageEditor = ({
|
|
|
3400
3551
|
},
|
|
3401
3552
|
t
|
|
3402
3553
|
)) }),
|
|
3403
|
-
/* @__PURE__ */
|
|
3404
|
-
/* @__PURE__ */
|
|
3405
|
-
/* @__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(
|
|
3406
3557
|
"input",
|
|
3407
3558
|
{
|
|
3408
3559
|
type: "color",
|
|
@@ -3411,15 +3562,15 @@ var ImageEditor = ({
|
|
|
3411
3562
|
className: "w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent"
|
|
3412
3563
|
}
|
|
3413
3564
|
),
|
|
3414
|
-
/* @__PURE__ */
|
|
3415
|
-
/* @__PURE__ */
|
|
3416
|
-
/* @__PURE__ */
|
|
3417
|
-
/* @__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: [
|
|
3418
3569
|
strokeWidth,
|
|
3419
3570
|
"px"
|
|
3420
3571
|
] })
|
|
3421
3572
|
] }),
|
|
3422
|
-
/* @__PURE__ */
|
|
3573
|
+
/* @__PURE__ */ jsx16(
|
|
3423
3574
|
"input",
|
|
3424
3575
|
{
|
|
3425
3576
|
type: "range",
|
|
@@ -3432,10 +3583,10 @@ var ImageEditor = ({
|
|
|
3432
3583
|
)
|
|
3433
3584
|
] })
|
|
3434
3585
|
] }),
|
|
3435
|
-
/* @__PURE__ */
|
|
3436
|
-
/* @__PURE__ */
|
|
3437
|
-
/* @__PURE__ */
|
|
3438
|
-
/* @__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(
|
|
3439
3590
|
"input",
|
|
3440
3591
|
{
|
|
3441
3592
|
type: "text",
|
|
@@ -3446,7 +3597,7 @@ var ImageEditor = ({
|
|
|
3446
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"
|
|
3447
3598
|
}
|
|
3448
3599
|
),
|
|
3449
|
-
/* @__PURE__ */
|
|
3600
|
+
/* @__PURE__ */ jsx16(
|
|
3450
3601
|
"button",
|
|
3451
3602
|
{
|
|
3452
3603
|
type: "button",
|
|
@@ -3456,14 +3607,14 @@ var ImageEditor = ({
|
|
|
3456
3607
|
}
|
|
3457
3608
|
)
|
|
3458
3609
|
] }),
|
|
3459
|
-
/* @__PURE__ */
|
|
3460
|
-
/* @__PURE__ */
|
|
3461
|
-
/* @__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: [
|
|
3462
3613
|
fontSize,
|
|
3463
3614
|
"px"
|
|
3464
3615
|
] })
|
|
3465
3616
|
] }),
|
|
3466
|
-
/* @__PURE__ */
|
|
3617
|
+
/* @__PURE__ */ jsx16(
|
|
3467
3618
|
"input",
|
|
3468
3619
|
{
|
|
3469
3620
|
type: "range",
|
|
@@ -3474,14 +3625,14 @@ var ImageEditor = ({
|
|
|
3474
3625
|
className: "w-full accent-indigo-500"
|
|
3475
3626
|
}
|
|
3476
3627
|
),
|
|
3477
|
-
/* @__PURE__ */
|
|
3478
|
-
/* @__PURE__ */
|
|
3479
|
-
/* @__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: [
|
|
3480
3631
|
"Layers (",
|
|
3481
3632
|
state.annotations.length,
|
|
3482
3633
|
")"
|
|
3483
3634
|
] }),
|
|
3484
|
-
state.selectedAnnotationId && /* @__PURE__ */
|
|
3635
|
+
state.selectedAnnotationId && /* @__PURE__ */ jsx16(
|
|
3485
3636
|
"button",
|
|
3486
3637
|
{
|
|
3487
3638
|
type: "button",
|
|
@@ -3490,7 +3641,7 @@ var ImageEditor = ({
|
|
|
3490
3641
|
children: "Delete Selected"
|
|
3491
3642
|
}
|
|
3492
3643
|
),
|
|
3493
|
-
state.annotations.length > 0 && /* @__PURE__ */
|
|
3644
|
+
state.annotations.length > 0 && /* @__PURE__ */ jsx16(
|
|
3494
3645
|
"button",
|
|
3495
3646
|
{
|
|
3496
3647
|
type: "button",
|
|
@@ -3501,10 +3652,10 @@ var ImageEditor = ({
|
|
|
3501
3652
|
)
|
|
3502
3653
|
] })
|
|
3503
3654
|
] }),
|
|
3504
|
-
activeTab === "depth" && /* @__PURE__ */
|
|
3505
|
-
/* @__PURE__ */
|
|
3506
|
-
/* @__PURE__ */
|
|
3507
|
-
/* @__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(
|
|
3508
3659
|
"button",
|
|
3509
3660
|
{
|
|
3510
3661
|
type: "button",
|
|
@@ -3514,8 +3665,8 @@ var ImageEditor = ({
|
|
|
3514
3665
|
}
|
|
3515
3666
|
)
|
|
3516
3667
|
] }),
|
|
3517
|
-
/* @__PURE__ */
|
|
3518
|
-
/* @__PURE__ */
|
|
3668
|
+
/* @__PURE__ */ jsxs15("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300", children: [
|
|
3669
|
+
/* @__PURE__ */ jsx16(
|
|
3519
3670
|
"input",
|
|
3520
3671
|
{
|
|
3521
3672
|
type: "checkbox",
|
|
@@ -3524,12 +3675,12 @@ var ImageEditor = ({
|
|
|
3524
3675
|
className: "rounded accent-indigo-500"
|
|
3525
3676
|
}
|
|
3526
3677
|
),
|
|
3527
|
-
/* @__PURE__ */
|
|
3678
|
+
/* @__PURE__ */ jsx16("span", { children: "Enable Depth / Alpha Mask" })
|
|
3528
3679
|
] }),
|
|
3529
|
-
state.depthMask.enabled && /* @__PURE__ */
|
|
3530
|
-
/* @__PURE__ */
|
|
3531
|
-
/* @__PURE__ */
|
|
3532
|
-
/* @__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(
|
|
3533
3684
|
"input",
|
|
3534
3685
|
{
|
|
3535
3686
|
type: "text",
|
|
@@ -3540,8 +3691,8 @@ var ImageEditor = ({
|
|
|
3540
3691
|
}
|
|
3541
3692
|
)
|
|
3542
3693
|
] }),
|
|
3543
|
-
/* @__PURE__ */
|
|
3544
|
-
/* @__PURE__ */
|
|
3694
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex gap-2", children: [
|
|
3695
|
+
/* @__PURE__ */ jsx16(
|
|
3545
3696
|
"button",
|
|
3546
3697
|
{
|
|
3547
3698
|
type: "button",
|
|
@@ -3550,7 +3701,7 @@ var ImageEditor = ({
|
|
|
3550
3701
|
children: "Threshold Mode"
|
|
3551
3702
|
}
|
|
3552
3703
|
),
|
|
3553
|
-
/* @__PURE__ */
|
|
3704
|
+
/* @__PURE__ */ jsx16(
|
|
3554
3705
|
"button",
|
|
3555
3706
|
{
|
|
3556
3707
|
type: "button",
|
|
@@ -3560,12 +3711,12 @@ var ImageEditor = ({
|
|
|
3560
3711
|
}
|
|
3561
3712
|
)
|
|
3562
3713
|
] }),
|
|
3563
|
-
/* @__PURE__ */
|
|
3564
|
-
/* @__PURE__ */
|
|
3565
|
-
/* @__PURE__ */
|
|
3566
|
-
/* @__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] })
|
|
3567
3718
|
] }),
|
|
3568
|
-
/* @__PURE__ */
|
|
3719
|
+
/* @__PURE__ */ jsx16(
|
|
3569
3720
|
"input",
|
|
3570
3721
|
{
|
|
3571
3722
|
type: "range",
|
|
@@ -3579,12 +3730,12 @@ var ImageEditor = ({
|
|
|
3579
3730
|
}
|
|
3580
3731
|
)
|
|
3581
3732
|
] }),
|
|
3582
|
-
/* @__PURE__ */
|
|
3583
|
-
/* @__PURE__ */
|
|
3584
|
-
/* @__PURE__ */
|
|
3585
|
-
/* @__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] })
|
|
3586
3737
|
] }),
|
|
3587
|
-
/* @__PURE__ */
|
|
3738
|
+
/* @__PURE__ */ jsx16(
|
|
3588
3739
|
"input",
|
|
3589
3740
|
{
|
|
3590
3741
|
type: "range",
|
|
@@ -3598,12 +3749,12 @@ var ImageEditor = ({
|
|
|
3598
3749
|
}
|
|
3599
3750
|
)
|
|
3600
3751
|
] }),
|
|
3601
|
-
/* @__PURE__ */
|
|
3602
|
-
/* @__PURE__ */
|
|
3603
|
-
/* @__PURE__ */
|
|
3604
|
-
/* @__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 })
|
|
3605
3756
|
] }),
|
|
3606
|
-
/* @__PURE__ */
|
|
3757
|
+
/* @__PURE__ */ jsx16(
|
|
3607
3758
|
"input",
|
|
3608
3759
|
{
|
|
3609
3760
|
type: "range",
|
|
@@ -3615,8 +3766,8 @@ var ImageEditor = ({
|
|
|
3615
3766
|
}
|
|
3616
3767
|
)
|
|
3617
3768
|
] }),
|
|
3618
|
-
/* @__PURE__ */
|
|
3619
|
-
/* @__PURE__ */
|
|
3769
|
+
/* @__PURE__ */ jsxs15("label", { className: "flex items-center gap-2 cursor-pointer text-slate-300 mt-1", children: [
|
|
3770
|
+
/* @__PURE__ */ jsx16(
|
|
3620
3771
|
"input",
|
|
3621
3772
|
{
|
|
3622
3773
|
type: "checkbox",
|
|
@@ -3625,12 +3776,12 @@ var ImageEditor = ({
|
|
|
3625
3776
|
className: "rounded accent-indigo-500"
|
|
3626
3777
|
}
|
|
3627
3778
|
),
|
|
3628
|
-
/* @__PURE__ */
|
|
3779
|
+
/* @__PURE__ */ jsx16("span", { children: "Invert Mask" })
|
|
3629
3780
|
] })
|
|
3630
3781
|
] })
|
|
3631
3782
|
] }),
|
|
3632
|
-
activeTab === "select" && /* @__PURE__ */
|
|
3633
|
-
/* @__PURE__ */
|
|
3783
|
+
activeTab === "select" && /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-4 text-xs", children: [
|
|
3784
|
+
/* @__PURE__ */ jsx16(
|
|
3634
3785
|
SelectionOptionsBar,
|
|
3635
3786
|
{
|
|
3636
3787
|
controller,
|
|
@@ -3640,9 +3791,9 @@ var ImageEditor = ({
|
|
|
3640
3791
|
quickMask: Boolean(state.quickMask)
|
|
3641
3792
|
}
|
|
3642
3793
|
),
|
|
3643
|
-
selectionError && /* @__PURE__ */
|
|
3644
|
-
/* @__PURE__ */
|
|
3645
|
-
/* @__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(
|
|
3646
3797
|
"button",
|
|
3647
3798
|
{
|
|
3648
3799
|
type: "button",
|
|
@@ -3653,7 +3804,7 @@ var ImageEditor = ({
|
|
|
3653
3804
|
children: "Transform Selection"
|
|
3654
3805
|
}
|
|
3655
3806
|
),
|
|
3656
|
-
/* @__PURE__ */
|
|
3807
|
+
/* @__PURE__ */ jsx16(
|
|
3657
3808
|
"button",
|
|
3658
3809
|
{
|
|
3659
3810
|
type: "button",
|
|
@@ -3665,12 +3816,12 @@ var ImageEditor = ({
|
|
|
3665
3816
|
}
|
|
3666
3817
|
)
|
|
3667
3818
|
] }),
|
|
3668
|
-
/* @__PURE__ */
|
|
3819
|
+
/* @__PURE__ */ jsx16(RefineEdgePanel, { controller, selection: state.selection ?? null, layers: state.adjustments.layers })
|
|
3669
3820
|
] }),
|
|
3670
|
-
activeTab === "ai" && /* @__PURE__ */
|
|
3671
|
-
/* @__PURE__ */
|
|
3672
|
-
/* @__PURE__ */
|
|
3673
|
-
/* @__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(
|
|
3674
3825
|
"select",
|
|
3675
3826
|
{
|
|
3676
3827
|
"aria-label": "AI result target",
|
|
@@ -3678,54 +3829,54 @@ var ImageEditor = ({
|
|
|
3678
3829
|
onChange: (e) => setAiTarget(e.target.value),
|
|
3679
3830
|
className: "bg-slate-800 border border-slate-700 rounded px-1.5 py-1",
|
|
3680
3831
|
children: [
|
|
3681
|
-
/* @__PURE__ */
|
|
3682
|
-
/* @__PURE__ */
|
|
3683
|
-
/* @__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" })
|
|
3684
3835
|
]
|
|
3685
3836
|
}
|
|
3686
3837
|
)
|
|
3687
3838
|
] }),
|
|
3688
|
-
/* @__PURE__ */
|
|
3689
|
-
/* @__PURE__ */
|
|
3690
|
-
/* @__PURE__ */
|
|
3691
|
-
/* @__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" }) }),
|
|
3692
3843
|
"Background Removal"
|
|
3693
3844
|
] }),
|
|
3694
|
-
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..." })
|
|
3695
3846
|
] }),
|
|
3696
|
-
/* @__PURE__ */
|
|
3697
|
-
/* @__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(
|
|
3698
3849
|
"button",
|
|
3699
3850
|
{
|
|
3700
3851
|
type: "button",
|
|
3701
3852
|
onClick: handleRemoveBackground,
|
|
3702
3853
|
disabled: isRemovingBg || isInpainting,
|
|
3703
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",
|
|
3704
|
-
children: isRemovingBg ? /* @__PURE__ */
|
|
3705
|
-
/* @__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" }),
|
|
3706
3857
|
"Removing Background..."
|
|
3707
|
-
] }) : /* @__PURE__ */
|
|
3708
|
-
/* @__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" }) }),
|
|
3709
3860
|
"Remove Background"
|
|
3710
3861
|
] })
|
|
3711
3862
|
}
|
|
3712
3863
|
)
|
|
3713
3864
|
] }),
|
|
3714
|
-
/* @__PURE__ */
|
|
3715
|
-
/* @__PURE__ */
|
|
3716
|
-
/* @__PURE__ */
|
|
3717
|
-
/* @__PURE__ */
|
|
3718
|
-
/* @__PURE__ */
|
|
3719
|
-
/* @__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" })
|
|
3720
3871
|
] }),
|
|
3721
3872
|
"Generative Inpainting"
|
|
3722
3873
|
] }),
|
|
3723
|
-
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..." })
|
|
3724
3875
|
] }),
|
|
3725
|
-
/* @__PURE__ */
|
|
3726
|
-
/* @__PURE__ */
|
|
3727
|
-
/* @__PURE__ */
|
|
3728
|
-
/* @__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(
|
|
3729
3880
|
"textarea",
|
|
3730
3881
|
{
|
|
3731
3882
|
id: "ai-inpaint-prompt-react",
|
|
@@ -3737,10 +3888,10 @@ var ImageEditor = ({
|
|
|
3737
3888
|
}
|
|
3738
3889
|
)
|
|
3739
3890
|
] }),
|
|
3740
|
-
/* @__PURE__ */
|
|
3741
|
-
/* @__PURE__ */
|
|
3742
|
-
/* @__PURE__ */
|
|
3743
|
-
/* @__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(
|
|
3744
3895
|
"button",
|
|
3745
3896
|
{
|
|
3746
3897
|
type: "button",
|
|
@@ -3753,7 +3904,7 @@ var ImageEditor = ({
|
|
|
3753
3904
|
]
|
|
3754
3905
|
}
|
|
3755
3906
|
),
|
|
3756
|
-
/* @__PURE__ */
|
|
3907
|
+
/* @__PURE__ */ jsxs15(
|
|
3757
3908
|
"button",
|
|
3758
3909
|
{
|
|
3759
3910
|
type: "button",
|
|
@@ -3768,25 +3919,25 @@ var ImageEditor = ({
|
|
|
3768
3919
|
)
|
|
3769
3920
|
] })
|
|
3770
3921
|
] }),
|
|
3771
|
-
/* @__PURE__ */
|
|
3922
|
+
/* @__PURE__ */ jsx16(
|
|
3772
3923
|
"button",
|
|
3773
3924
|
{
|
|
3774
3925
|
type: "button",
|
|
3775
3926
|
onClick: handleInpaint,
|
|
3776
3927
|
disabled: isInpainting || isRemovingBg || !inpaintPrompt.trim(),
|
|
3777
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",
|
|
3778
|
-
children: isInpainting ? /* @__PURE__ */
|
|
3779
|
-
/* @__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" }),
|
|
3780
3931
|
"Generating Inpaint..."
|
|
3781
|
-
] }) : /* @__PURE__ */
|
|
3782
|
-
/* @__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" }) }),
|
|
3783
3934
|
"Apply Inpainting"
|
|
3784
3935
|
] })
|
|
3785
3936
|
}
|
|
3786
3937
|
)
|
|
3787
3938
|
] }),
|
|
3788
|
-
aiError && /* @__PURE__ */
|
|
3789
|
-
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 })
|
|
3790
3941
|
] })
|
|
3791
3942
|
] })
|
|
3792
3943
|
] })
|
|
@@ -3797,6 +3948,7 @@ var ImageEditor = ({
|
|
|
3797
3948
|
|
|
3798
3949
|
export {
|
|
3799
3950
|
useImageEditor,
|
|
3951
|
+
useImageEffectsTools,
|
|
3800
3952
|
ControlSlider,
|
|
3801
3953
|
Histogram,
|
|
3802
3954
|
useImageHistogram,
|
|
@@ -3804,6 +3956,7 @@ export {
|
|
|
3804
3956
|
AdjustmentLayersPanel,
|
|
3805
3957
|
LayerEffectsPanel,
|
|
3806
3958
|
LayersPanel,
|
|
3959
|
+
ImageProviderEffectsPanel,
|
|
3807
3960
|
PaintGradientEditor,
|
|
3808
3961
|
BrushOptionsBar,
|
|
3809
3962
|
ColorProfilePanel,
|
|
@@ -3814,4 +3967,4 @@ export {
|
|
|
3814
3967
|
TypeOptionsBar,
|
|
3815
3968
|
ImageEditor
|
|
3816
3969
|
};
|
|
3817
|
-
//# sourceMappingURL=chunk-
|
|
3970
|
+
//# sourceMappingURL=chunk-2EW42UXC.js.map
|