@pixerate/editor-react 0.68.0 → 0.69.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/paint-editor/index.cjs +26 -4
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +31 -2
- package/dist/paint-editor/index.d.ts +31 -2
- package/dist/paint-editor/index.js +28 -7
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/vector/index.cjs +302 -152
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +23 -2
- package/dist/vector/index.d.ts +23 -2
- package/dist/vector/index.js +285 -136
- package/dist/vector/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PaintEditorController, PaintEditorState, PaintEditorOptions, PaintTool, SliderControl } from '@pixerate/editor/paint-editor';
|
|
1
|
+
import { PaintEditorController, PaintEditorState, PaintDirectorOptions, PaintPresence, PaintDirector, PaintEditorOptions, PaintTool, PaintView, SliderControl } from '@pixerate/editor/paint-editor';
|
|
2
2
|
import React__default from 'react';
|
|
3
3
|
|
|
4
4
|
interface UsePaintEditorReturn {
|
|
@@ -13,6 +13,15 @@ interface UsePaintEditorReturn {
|
|
|
13
13
|
declare function usePaintEditor(options?: PaintEditorOptions | PaintEditorController): UsePaintEditorReturn;
|
|
14
14
|
/** Subscribes to a controller's state. */
|
|
15
15
|
declare function usePaintEditorState(controller: PaintEditorController): PaintEditorState;
|
|
16
|
+
/**
|
|
17
|
+
* A `PaintPresence` and `PaintDirector` for a paint editor: pass `presence` to `PaintEditor` (or
|
|
18
|
+
* `PaintCanvas`) and `director` to `createPaintEditorToolProvider`, so agent strokes are painted
|
|
19
|
+
* live by a cursor on the canvas. Options are read on the first render.
|
|
20
|
+
*/
|
|
21
|
+
declare function usePaintDirector(controller: PaintEditorController, options?: Omit<PaintDirectorOptions, 'clock'>): {
|
|
22
|
+
presence: PaintPresence;
|
|
23
|
+
director: PaintDirector;
|
|
24
|
+
};
|
|
16
25
|
|
|
17
26
|
interface PaintCanvasProps {
|
|
18
27
|
controller: PaintEditorController;
|
|
@@ -24,6 +33,8 @@ interface PaintCanvasProps {
|
|
|
24
33
|
fitOnMount?: boolean;
|
|
25
34
|
/** Called with a refusal (hidden or locked layer). */
|
|
26
35
|
onError?: (message: string | null) => void;
|
|
36
|
+
/** Agent cursors to draw over the canvas (see `PaintDirector` and `usePaintDirector`). */
|
|
37
|
+
presence?: PaintPresence;
|
|
27
38
|
className?: string;
|
|
28
39
|
}
|
|
29
40
|
/**
|
|
@@ -34,6 +45,22 @@ interface PaintCanvasProps {
|
|
|
34
45
|
* rotation. Guides and floating reference images are drawn on top.
|
|
35
46
|
*/
|
|
36
47
|
declare const PaintCanvas: React__default.FC<PaintCanvasProps>;
|
|
48
|
+
/**
|
|
49
|
+
* Agent cursors and notes over the canvas. Positions are document pixels, placed through the view
|
|
50
|
+
* (zoom, pan, rotation, mirroring), while the cursors themselves stay upright and unscaled.
|
|
51
|
+
*/
|
|
52
|
+
declare const PaintPresenceLayer: React__default.FC<{
|
|
53
|
+
presence: PaintPresence;
|
|
54
|
+
view: PaintView;
|
|
55
|
+
canvas: {
|
|
56
|
+
width: number;
|
|
57
|
+
height: number;
|
|
58
|
+
};
|
|
59
|
+
viewport: {
|
|
60
|
+
width: number;
|
|
61
|
+
height: number;
|
|
62
|
+
};
|
|
63
|
+
}>;
|
|
37
64
|
|
|
38
65
|
interface PaintToolbarProps {
|
|
39
66
|
controller: PaintEditorController;
|
|
@@ -108,6 +135,8 @@ interface PaintEditorProps {
|
|
|
108
135
|
fileName?: string;
|
|
109
136
|
/** Height of the editor (default 720 px). */
|
|
110
137
|
height?: number | string;
|
|
138
|
+
/** Agent cursors to draw over the canvas (see `usePaintDirector`). */
|
|
139
|
+
presence?: PaintPresence;
|
|
111
140
|
className?: string;
|
|
112
141
|
}
|
|
113
142
|
/**
|
|
@@ -127,4 +156,4 @@ declare const PaintSlider: React__default.FC<{
|
|
|
127
156
|
onCommit?: (v: number) => void;
|
|
128
157
|
}>;
|
|
129
158
|
|
|
130
|
-
export { BrushPanel, type BrushPanelProps, ColorPanel, type ColorPanelProps, PaintCanvas, type PaintCanvasProps, PaintEditor, type PaintEditorProps, PaintLayersPanel, type PaintLayersPanelProps, PaintSlider, PaintToolbar, type PaintToolbarProps, PaperPanel, type PaperPanelProps, type UsePaintEditorReturn, usePaintEditor, usePaintEditorState };
|
|
159
|
+
export { BrushPanel, type BrushPanelProps, ColorPanel, type ColorPanelProps, PaintCanvas, type PaintCanvasProps, PaintEditor, type PaintEditorProps, PaintLayersPanel, type PaintLayersPanelProps, PaintPresenceLayer, PaintSlider, PaintToolbar, type PaintToolbarProps, PaperPanel, type PaperPanelProps, type UsePaintEditorReturn, usePaintDirector, usePaintEditor, usePaintEditorState };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/paint-editor/usePaintEditor.ts
|
|
2
2
|
import { useMemo, useState, useSyncExternalStore } from "react";
|
|
3
|
-
import { PaintEditorController } from "@pixerate/editor/paint-editor";
|
|
3
|
+
import { PaintDirector, PaintEditorController, PaintPresence } from "@pixerate/editor/paint-editor";
|
|
4
4
|
function usePaintEditor(options = {}) {
|
|
5
5
|
const [controller] = useState(() => options instanceof PaintEditorController ? options : new PaintEditorController(options));
|
|
6
6
|
const state = usePaintEditorState(controller);
|
|
@@ -13,19 +13,27 @@ function usePaintEditorState(controller) {
|
|
|
13
13
|
() => controller.getState()
|
|
14
14
|
);
|
|
15
15
|
}
|
|
16
|
+
function usePaintDirector(controller, options = {}) {
|
|
17
|
+
const [value] = useState(() => {
|
|
18
|
+
const presence = new PaintPresence();
|
|
19
|
+
return { presence, director: new PaintDirector(controller, presence, options) };
|
|
20
|
+
});
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
16
23
|
|
|
17
24
|
// src/paint-editor/PaintCanvas.tsx
|
|
18
|
-
import { useEffect, useMemo as useMemo2, useRef, useState as useState2 } from "react";
|
|
25
|
+
import { useEffect, useMemo as useMemo2, useRef, useState as useState2, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
19
26
|
import {
|
|
20
27
|
PaintCanvasPresenter,
|
|
21
28
|
PaintGesture,
|
|
29
|
+
documentToScreen,
|
|
22
30
|
fitZoom,
|
|
23
31
|
guideOverlay,
|
|
24
32
|
handlePaintShortcut,
|
|
25
33
|
viewCssTransform
|
|
26
34
|
} from "@pixerate/editor/paint-editor";
|
|
27
35
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
28
|
-
var PaintCanvas = ({ controller, tool = "brush", showGuides = true, fitOnMount = true, onError, className }) => {
|
|
36
|
+
var PaintCanvas = ({ controller, tool = "brush", showGuides = true, fitOnMount = true, onError, presence, className }) => {
|
|
29
37
|
const state = usePaintEditorState(controller);
|
|
30
38
|
const viewport = useRef(null);
|
|
31
39
|
const canvas = useRef(null);
|
|
@@ -140,6 +148,7 @@ var PaintCanvas = ({ controller, tool = "brush", showGuides = true, fitOnMount =
|
|
|
140
148
|
predicted.length > 0 && /* @__PURE__ */ jsx("polyline", { points: predicted.map((p) => `${p.x},${p.y}`).join(" "), fill: "none", stroke: state.color, strokeOpacity: 0.5, strokeWidth: Math.max(1, state.brush.tip.size / 2), strokeLinecap: "round" })
|
|
141
149
|
] }),
|
|
142
150
|
state.guides.references.filter((r) => r.visible).map((r) => /* @__PURE__ */ jsx(ReferencePanel, { controller, id: r.id }, r.id)),
|
|
151
|
+
presence && /* @__PURE__ */ jsx(PaintPresenceLayer, { presence, view: state.view, canvas: doc, viewport: size }),
|
|
143
152
|
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-1 right-2 text-[10px] text-slate-500 pointer-events-none", "data-testid": "paint-view-status", children: [
|
|
144
153
|
Math.round(state.view.zoom * 100),
|
|
145
154
|
"% \xB7 ",
|
|
@@ -151,6 +160,16 @@ var PaintCanvas = ({ controller, tool = "brush", showGuides = true, fitOnMount =
|
|
|
151
160
|
}
|
|
152
161
|
);
|
|
153
162
|
};
|
|
163
|
+
var PaintPresenceLayer = ({ presence, view, canvas, viewport }) => {
|
|
164
|
+
const { actors } = useSyncExternalStore2(presence.subscribe, presence.getState, presence.getState);
|
|
165
|
+
return /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 overflow-hidden", "data-paint-presence": "", "aria-hidden": "true", children: actors.map((a) => {
|
|
166
|
+
const p = documentToScreen(view, canvas, viewport, a.x, a.y);
|
|
167
|
+
return /* @__PURE__ */ jsxs("div", { className: "absolute", style: { left: p.x, top: p.y }, "data-actor": a.id, children: [
|
|
168
|
+
/* @__PURE__ */ jsx("svg", { width: "18", height: "20", viewBox: "0 0 18 20", className: "drop-shadow-md", style: { transform: a.pressed ? "scale(0.85)" : void 0, transformOrigin: "0 0" }, children: /* @__PURE__ */ jsx("path", { d: "M0 0 L0 15 L4.5 10.8 L7.6 17 L10.2 15.8 L7.2 9.7 L13.5 9.4 Z", fill: a.color, stroke: "white", strokeWidth: "1.4", strokeLinejoin: "round" }) }),
|
|
169
|
+
/* @__PURE__ */ jsx("span", { className: "absolute left-4 top-4 w-max max-w-[240px] rounded-md px-2 py-0.5 text-[11px] font-semibold text-white shadow", style: { background: a.color }, children: a.message ?? a.name })
|
|
170
|
+
] }, a.id);
|
|
171
|
+
}) });
|
|
172
|
+
};
|
|
154
173
|
var ReferencePanel = ({ controller, id }) => {
|
|
155
174
|
const state = usePaintEditorState(controller);
|
|
156
175
|
const ref = state.guides.references.find((r) => r.id === id);
|
|
@@ -728,7 +747,7 @@ var ColorPanel = ({ controller, wheelSize = 168, mixingPad = true, className })
|
|
|
728
747
|
|
|
729
748
|
// src/paint-editor/PaintLayersPanel.tsx
|
|
730
749
|
import { useState as useState6 } from "react";
|
|
731
|
-
import {
|
|
750
|
+
import { BLEND_MENU_GROUPS } from "@pixerate/editor/paint-editor";
|
|
732
751
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
733
752
|
function siblingIndex(layers, l) {
|
|
734
753
|
const sibs = layers.filter((x) => x.parentId === l.parentId).reverse();
|
|
@@ -825,7 +844,7 @@ var PaintLayersPanel = ({ controller, className }) => {
|
|
|
825
844
|
/* @__PURE__ */ jsx7("span", { className: "w-14 text-slate-400", children: "Blend" }),
|
|
826
845
|
/* @__PURE__ */ jsxs7("select", { "aria-label": "Layer blend", value: active.blend, onChange: (e) => attempt(() => controller.updateLayer(active.id, { blend: e.target.value })), className: "flex-1 rounded bg-slate-800 px-1 py-0.5", children: [
|
|
827
846
|
active.type === "group" && /* @__PURE__ */ jsx7("option", { value: "pass-through", children: "Pass through" }),
|
|
828
|
-
|
|
847
|
+
BLEND_MENU_GROUPS.map((g) => /* @__PURE__ */ jsx7("optgroup", { label: g.label, children: g.modes.map((m) => /* @__PURE__ */ jsx7("option", { value: m.id, title: m.description, children: m.label }, m.id)) }, g.label))
|
|
829
848
|
] })
|
|
830
849
|
] }),
|
|
831
850
|
/* @__PURE__ */ jsxs7("div", { className: "flex gap-1", children: [
|
|
@@ -840,7 +859,7 @@ var PaintLayersPanel = ({ controller, className }) => {
|
|
|
840
859
|
// src/paint-editor/PaintEditor.tsx
|
|
841
860
|
import { useState as useState7 } from "react";
|
|
842
861
|
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
843
|
-
var PaintEditor = ({ controller, fileName, height = 720, className }) => {
|
|
862
|
+
var PaintEditor = ({ controller, fileName, height = 720, presence, className }) => {
|
|
844
863
|
const [tool, setTool] = useState7("brush");
|
|
845
864
|
const [tab, setTab] = useState7("color");
|
|
846
865
|
const [error, setError] = useState7(null);
|
|
@@ -849,7 +868,7 @@ var PaintEditor = ({ controller, fileName, height = 720, className }) => {
|
|
|
849
868
|
/* @__PURE__ */ jsxs8("div", { className: "flex min-h-0 flex-1 gap-2", children: [
|
|
850
869
|
/* @__PURE__ */ jsx8(BrushPanel, { controller, className: "w-60 shrink-0 overflow-y-auto pr-1" }),
|
|
851
870
|
/* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
852
|
-
/* @__PURE__ */ jsx8(PaintCanvas, { controller, tool, onError: setError, className: "flex-1 rounded-lg" }),
|
|
871
|
+
/* @__PURE__ */ jsx8(PaintCanvas, { controller, tool, onError: setError, presence, className: "flex-1 rounded-lg" }),
|
|
853
872
|
error && /* @__PURE__ */ jsx8("p", { role: "alert", className: "mt-1 text-[11px] text-rose-400", children: error })
|
|
854
873
|
] }),
|
|
855
874
|
/* @__PURE__ */ jsxs8("div", { className: "flex w-64 shrink-0 flex-col gap-2 overflow-y-auto pr-1", children: [
|
|
@@ -867,9 +886,11 @@ export {
|
|
|
867
886
|
PaintCanvas,
|
|
868
887
|
PaintEditor,
|
|
869
888
|
PaintLayersPanel,
|
|
889
|
+
PaintPresenceLayer,
|
|
870
890
|
PaintSlider,
|
|
871
891
|
PaintToolbar,
|
|
872
892
|
PaperPanel,
|
|
893
|
+
usePaintDirector,
|
|
873
894
|
usePaintEditor,
|
|
874
895
|
usePaintEditorState
|
|
875
896
|
};
|