dishui 0.0.47 → 0.0.49
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/components/pro/CodeEditor/editors/MarkdownEditor.js +1 -2
- package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js.map +1 -1
- package/dist/components/pro/CodeEditor/themes.js +0 -25
- package/dist/components/pro/CodeEditor/themes.js.map +1 -1
- package/dist/components/pro/CodeEditor/types.d.ts +1 -1
- package/dist/components/pro/Flow/Flow.js +500 -483
- package/dist/components/pro/Flow/Flow.js.map +1 -1
- package/dist/components/pro/Flow/FlowCanvas.js +526 -524
- package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
- package/dist/components/pro/Flow/canvas/GridRenderer.d.ts +3 -0
- package/dist/components/pro/Flow/canvas/GridRenderer.js +28 -23
- package/dist/components/pro/Flow/canvas/GridRenderer.js.map +1 -1
- package/dist/components/pro/Flow/canvas/MiniMapRenderer.js +18 -17
- package/dist/components/pro/Flow/canvas/MiniMapRenderer.js.map +1 -1
- package/dist/components/pro/Flow/canvas/PixiApp.d.ts +2 -0
- package/dist/components/pro/Flow/canvas/PixiApp.js +14 -11
- package/dist/components/pro/Flow/canvas/PixiApp.js.map +1 -1
- package/dist/components/pro/Flow/constants.js +7 -7
- package/dist/components/pro/Flow/constants.js.map +1 -1
- package/dist/components/pro/Flow/context/FlowAIContext.d.ts +15 -0
- package/dist/components/pro/Flow/context/FlowAIContext.js +32 -0
- package/dist/components/pro/Flow/context/FlowAIContext.js.map +1 -0
- package/dist/components/pro/Flow/context/FlowUIContext.d.ts +4 -1
- package/dist/components/pro/Flow/context/FlowUIContext.js +58 -55
- package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
- package/dist/components/pro/Flow/edges/EdgeRenderer.js +22 -21
- package/dist/components/pro/Flow/edges/EdgeRenderer.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useFlowImportExport.js +32 -32
- package/dist/components/pro/Flow/hooks/useFlowImportExport.js.map +1 -1
- package/dist/components/pro/Flow/hooks/usePixiApp.d.ts +6 -1
- package/dist/components/pro/Flow/hooks/usePixiApp.js +49 -30
- package/dist/components/pro/Flow/hooks/usePixiApp.js.map +1 -1
- package/dist/components/pro/Flow/index.d.ts +2 -0
- package/dist/components/pro/Flow/lines/FreehandTool.js +21 -20
- package/dist/components/pro/Flow/lines/FreehandTool.js.map +1 -1
- package/dist/components/pro/Flow/lines/GeometricLineTool.js +22 -18
- package/dist/components/pro/Flow/lines/GeometricLineTool.js.map +1 -1
- package/dist/components/pro/Flow/lines/LineRenderer.js +19 -18
- package/dist/components/pro/Flow/lines/LineRenderer.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.js +143 -124
- package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js +22 -17
- package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
- package/dist/components/pro/Flow/nodes/NodeRenderer.js +77 -76
- package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
- package/dist/components/pro/Flow/nodes/aiClient.d.ts +22 -0
- package/dist/components/pro/Flow/nodes/aiClient.js +107 -54
- package/dist/components/pro/Flow/nodes/aiClient.js.map +1 -1
- package/dist/components/pro/Flow/nodes/svgIcons.js +6 -6
- package/dist/components/pro/Flow/nodes/svgIcons.js.map +1 -1
- package/dist/components/pro/Flow/panels/AIPanel.d.ts +2 -0
- package/dist/components/pro/Flow/panels/AIPanel.js +498 -0
- package/dist/components/pro/Flow/panels/AIPanel.js.map +1 -0
- package/dist/components/pro/Flow/panels/FlowPanelGroup.js +51 -39
- package/dist/components/pro/Flow/panels/FlowPanelGroup.js.map +1 -1
- package/dist/components/pro/Flow/panels/FlowToolbar.js +91 -85
- package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
- package/dist/components/pro/Flow/panels/InspectorPanel.js +372 -332
- package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
- package/dist/components/pro/Flow/panels/OutlinePanel.js +28 -27
- package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
- package/dist/components/pro/Flow/panels/ShapePalette.js +107 -104
- package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
- package/dist/components/pro/Flow/panels/toolbarIcons.d.ts +1 -0
- package/dist/components/pro/Flow/panels/toolbarIcons.js +25 -20
- package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
- package/dist/components/pro/Flow/types.d.ts +13 -0
- package/dist/components/pro/Flow/types.js.map +1 -1
- package/dist/components/pro/Flow/utils/themeColor.d.ts +87 -0
- package/dist/components/pro/Flow/utils/themeColor.js +212 -0
- package/dist/components/pro/Flow/utils/themeColor.js.map +1 -0
- package/dist/contexts/AppContext.d.ts +1 -1
- package/dist/contexts/AppContext.js +28 -29
- package/dist/contexts/AppContext.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/favicon.svg +10 -0
- package/dist/flow.js +56 -51
- package/dist/styles/themeStyles.js +6 -11
- package/dist/styles/themeStyles.js.map +1 -1
- package/dist/utils/themes.js +3 -23
- package/dist/utils/themes.js.map +1 -1
- package/package.json +17 -18
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { PixiApp } from '../canvas/PixiApp';
|
|
2
|
+
import { type FlowThemeColors } from '../utils/themeColor';
|
|
2
3
|
/**
|
|
3
4
|
* Manages PixiJS Application lifecycle: creates on mount, destroys on unmount,
|
|
4
5
|
* handles container resize.
|
|
6
|
+
*
|
|
7
|
+
* The canvas backdrop follows the active DishUI theme (`--color-base-200`). We
|
|
8
|
+
* resolve the theme color from the container's inherited CSS scope at init and
|
|
9
|
+
* again whenever the ancestor `data-theme` attribute changes.
|
|
5
10
|
*/
|
|
6
|
-
export declare function usePixiApp(containerRef: React.RefObject<HTMLDivElement | null
|
|
11
|
+
export declare function usePixiApp(containerRef: React.RefObject<HTMLDivElement | null>, onThemeColors?: (colors: FlowThemeColors) => void): {
|
|
7
12
|
pixiRef: import("react").RefObject<PixiApp | null>;
|
|
8
13
|
canvasRef: import("react").RefObject<HTMLCanvasElement | null>;
|
|
9
14
|
readyRef: import("react").RefObject<boolean>;
|
|
@@ -1,41 +1,60 @@
|
|
|
1
|
-
import { PixiApp as
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
r
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
import { PixiApp as k } from "../canvas/PixiApp.js";
|
|
2
|
+
import { refreshThemePalette as y, resolveFlowThemeColors as w } from "../utils/themeColor.js";
|
|
3
|
+
import { useEffect as x, useRef as o } from "react";
|
|
4
|
+
function O(l, a) {
|
|
5
|
+
const s = o(null), d = o(null), c = o(!1), i = o(a);
|
|
6
|
+
return i.current = a, x(() => {
|
|
7
|
+
const e = l.current;
|
|
8
|
+
if (!e) return;
|
|
9
|
+
let h = !1;
|
|
10
|
+
const t = document.createElement("canvas");
|
|
11
|
+
t.style.display = "block", t.style.width = "100%", t.style.height = "100%", e.appendChild(t), d.current = t;
|
|
12
|
+
const r = new k();
|
|
13
|
+
s.current = r;
|
|
14
|
+
const f = e.getBoundingClientRect();
|
|
15
|
+
y(e);
|
|
16
|
+
const m = w(e);
|
|
17
|
+
r.init({
|
|
18
|
+
canvas: t,
|
|
19
|
+
width: f.width,
|
|
20
|
+
height: f.height,
|
|
21
|
+
backgroundColor: m.background
|
|
18
22
|
}).then(() => {
|
|
19
|
-
|
|
23
|
+
h || (c.current = !0, i.current?.(m));
|
|
20
24
|
});
|
|
21
|
-
const
|
|
22
|
-
if (!
|
|
23
|
-
for (const
|
|
24
|
-
const { width:
|
|
25
|
-
|
|
25
|
+
const p = new ResizeObserver((n) => {
|
|
26
|
+
if (!r.destroyed)
|
|
27
|
+
for (const R of n) {
|
|
28
|
+
const { width: v, height: g } = R.contentRect;
|
|
29
|
+
v > 0 && g > 0 && r.resize(v, g);
|
|
26
30
|
}
|
|
27
31
|
});
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
p.observe(e);
|
|
33
|
+
const C = () => {
|
|
34
|
+
if (r.destroyed) return;
|
|
35
|
+
y(e);
|
|
36
|
+
const n = w(e);
|
|
37
|
+
r.setBackgroundColor(n.background), i.current?.(n);
|
|
38
|
+
}, u = new MutationObserver(C);
|
|
39
|
+
u.observe(document.documentElement, {
|
|
40
|
+
attributes: !0,
|
|
41
|
+
attributeFilter: ["data-theme", "class"]
|
|
42
|
+
});
|
|
43
|
+
const b = e.closest("[data-theme]");
|
|
44
|
+
return b && u.observe(b, {
|
|
45
|
+
attributes: !0,
|
|
46
|
+
attributeFilter: ["data-theme", "class"]
|
|
47
|
+
}), () => {
|
|
48
|
+
h = !0, p.disconnect(), u.disconnect(), r.destroy(), s.current = null, c.current = !1, t.parentNode && t.parentNode.removeChild(t);
|
|
30
49
|
};
|
|
31
|
-
}, [
|
|
32
|
-
pixiRef:
|
|
33
|
-
canvasRef:
|
|
34
|
-
readyRef:
|
|
50
|
+
}, [l]), {
|
|
51
|
+
pixiRef: s,
|
|
52
|
+
canvasRef: d,
|
|
53
|
+
readyRef: c
|
|
35
54
|
};
|
|
36
55
|
}
|
|
37
56
|
export {
|
|
38
|
-
|
|
57
|
+
O as usePixiApp
|
|
39
58
|
};
|
|
40
59
|
|
|
41
60
|
//# sourceMappingURL=usePixiApp.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePixiApp.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/usePixiApp.ts"],"sourcesContent":["import { useRef, useEffect, useCallback } from 'react';\nimport { PixiApp } from '../canvas/PixiApp';\n\n/**\n * Manages PixiJS Application lifecycle: creates on mount, destroys on unmount,\n * handles container resize.\n */\nexport function usePixiApp(containerRef: React.RefObject<HTMLDivElement | null
|
|
1
|
+
{"version":3,"file":"usePixiApp.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/usePixiApp.ts"],"sourcesContent":["import { useRef, useEffect, useCallback } from 'react';\nimport { PixiApp } from '../canvas/PixiApp';\nimport { resolveFlowThemeColors, refreshThemePalette, type FlowThemeColors } from '../utils/themeColor';\n\n/**\n * Manages PixiJS Application lifecycle: creates on mount, destroys on unmount,\n * handles container resize.\n *\n * The canvas backdrop follows the active DishUI theme (`--color-base-200`). We\n * resolve the theme color from the container's inherited CSS scope at init and\n * again whenever the ancestor `data-theme` attribute changes.\n */\nexport function usePixiApp(\n containerRef: React.RefObject<HTMLDivElement | null>,\n onThemeColors?: (colors: FlowThemeColors) => void,\n) {\n const pixiRef = useRef<PixiApp | null>(null);\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\n const readyRef = useRef(false);\n const onThemeColorsRef = useRef(onThemeColors);\n onThemeColorsRef.current = onThemeColors;\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n let cancelled = false;\n\n const canvas = document.createElement('canvas');\n canvas.style.display = 'block';\n canvas.style.width = '100%';\n canvas.style.height = '100%';\n container.appendChild(canvas);\n canvasRef.current = canvas;\n\n const pixi = new PixiApp();\n pixiRef.current = pixi;\n\n const rect = container.getBoundingClientRect();\n refreshThemePalette(container);\n const themeColors = resolveFlowThemeColors(container);\n pixi.init({\n canvas,\n width: rect.width,\n height: rect.height,\n backgroundColor: themeColors.background,\n }).then(() => {\n if (!cancelled) {\n readyRef.current = true;\n onThemeColorsRef.current?.(themeColors);\n }\n });\n\n const ro = new ResizeObserver((entries) => {\n if (pixi.destroyed) return;\n for (const entry of entries) {\n const { width, height } = entry.contentRect;\n if (width > 0 && height > 0) {\n pixi.resize(width, height);\n }\n }\n });\n ro.observe(container);\n\n // React to DishUI theme switches (the theme is applied via a `data-theme`\n // attribute on an ancestor element). Re-resolve the themed colors and push\n // them to the canvas + subscriber.\n const applyTheme = () => {\n if (pixi.destroyed) return;\n refreshThemePalette(container);\n const colors = resolveFlowThemeColors(container);\n pixi.setBackgroundColor(colors.background);\n onThemeColorsRef.current?.(colors);\n };\n const themeObserver = new MutationObserver(applyTheme);\n themeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['data-theme', 'class'],\n });\n // Also watch the closest themed ancestor, if any.\n const themedAncestor = container.closest('[data-theme]');\n if (themedAncestor) {\n themeObserver.observe(themedAncestor, {\n attributes: true,\n attributeFilter: ['data-theme', 'class'],\n });\n }\n\n return () => {\n cancelled = true;\n ro.disconnect();\n themeObserver.disconnect();\n pixi.destroy();\n pixiRef.current = null;\n readyRef.current = false;\n if (canvas.parentNode) canvas.parentNode.removeChild(canvas);\n };\n }, [containerRef]);\n\n return { pixiRef, canvasRef, readyRef };\n}\n"],"mappings":";;;AAYA,SAAgB,EACd,GACA,GACA;AACA,QAAM,IAAU,EAAuB,IAAI,GACrC,IAAY,EAAiC,IAAI,GACjD,IAAW,EAAO,EAAK,GACvB,IAAmB,EAAO,CAAa;AAC7C,SAAA,EAAiB,UAAU,GAE3B,EAAA,MAAgB;AACd,UAAM,IAAY,EAAa;AAC/B,QAAI,CAAC,EAAW;AAEhB,QAAI,IAAY;AAEhB,UAAM,IAAS,SAAS,cAAc,QAAQ;AAC9C,IAAA,EAAO,MAAM,UAAU,SACvB,EAAO,MAAM,QAAQ,QACrB,EAAO,MAAM,SAAS,QACtB,EAAU,YAAY,CAAM,GAC5B,EAAU,UAAU;AAEpB,UAAM,IAAO,IAAI,EAAQ;AACzB,IAAA,EAAQ,UAAU;AAElB,UAAM,IAAO,EAAU,sBAAsB;AAC7C,IAAA,EAAoB,CAAS;AAC7B,UAAM,IAAc,EAAuB,CAAS;AACpD,IAAA,EAAK,KAAK;AAAA,MACR,QAAA;AAAA,MACA,OAAO,EAAK;AAAA,MACZ,QAAQ,EAAK;AAAA,MACb,iBAAiB,EAAY;AAAA,IAC/B,CAAC,EAAE,KAAA,MAAW;AACZ,MAAK,MACH,EAAS,UAAU,IACnB,EAAiB,UAAU,CAAW;AAAA,IAE1C,CAAC;AAED,UAAM,IAAK,IAAI,eAAA,CAAgB,MAAY;AACzC,UAAI,CAAA,EAAK;AACT,mBAAW,KAAS,GAAS;AAC3B,gBAAM,EAAE,OAAA,GAAO,QAAA,EAAA,IAAW,EAAM;AAChC,UAAI,IAAQ,KAAK,IAAS,KACxB,EAAK,OAAO,GAAO,CAAM;AAAA,QAE7B;AAAA,IACF,CAAC;AACD,IAAA,EAAG,QAAQ,CAAS;AAKpB,UAAM,IAAA,MAAmB;AACvB,UAAI,EAAK,UAAW;AACpB,MAAA,EAAoB,CAAS;AAC7B,YAAM,IAAS,EAAuB,CAAS;AAC/C,MAAA,EAAK,mBAAmB,EAAO,UAAU,GACzC,EAAiB,UAAU,CAAM;AAAA,IACnC,GACM,IAAgB,IAAI,iBAAiB,CAAU;AACrD,IAAA,EAAc,QAAQ,SAAS,iBAAiB;AAAA,MAC9C,YAAY;AAAA,MACZ,iBAAiB,CAAC,cAAc,OAAO;AAAA,IACzC,CAAC;AAED,UAAM,IAAiB,EAAU,QAAQ,cAAc;AACvD,WAAI,KACF,EAAc,QAAQ,GAAgB;AAAA,MACpC,YAAY;AAAA,MACZ,iBAAiB,CAAC,cAAc,OAAO;AAAA,IACzC,CAAC,GAGH,MAAa;AACX,MAAA,IAAY,IACZ,EAAG,WAAW,GACd,EAAc,WAAW,GACzB,EAAK,QAAQ,GACb,EAAQ,UAAU,MAClB,EAAS,UAAU,IACf,EAAO,cAAY,EAAO,WAAW,YAAY,CAAM;AAAA,IAC7D;AAAA,EACF,GAAG,CAAC,CAAY,CAAC,GAEV;AAAA,IAAE,SAAA;AAAA,IAAS,WAAA;AAAA,IAAW,UAAA;AAAA,EAAS;AACxC"}
|
|
@@ -13,6 +13,8 @@ export { default as FlowToolbar, FlowZoomControls } from './panels/FlowToolbar';
|
|
|
13
13
|
export { default as ShapePalette } from './panels/ShapePalette';
|
|
14
14
|
export { default as InspectorPanel } from './panels/InspectorPanel';
|
|
15
15
|
export { default as OutlinePanel } from './panels/OutlinePanel';
|
|
16
|
+
export { AIPanelContent } from './panels/AIPanel';
|
|
17
|
+
export { useFlowAI, FlowAIProvider } from './context/FlowAIContext';
|
|
16
18
|
export { default as ContextMenu } from './panels/ContextMenu';
|
|
17
19
|
export { default as Breadcrumb } from './panels/Breadcrumb';
|
|
18
20
|
export { default as ProjectTitle } from './panels/ProjectTitle';
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { resolveThemeColor as s } from "../utils/themeColor.js";
|
|
2
|
+
import { generateId as o } from "../nodes/nodeUtils.js";
|
|
3
|
+
import { simplifyPath as r, smoothCatmullRom as h } from "./lineSmoothing.js";
|
|
4
|
+
import { Graphics as a } from "pixi.js";
|
|
5
|
+
var v = class {
|
|
5
6
|
stage;
|
|
6
7
|
preview;
|
|
7
8
|
callbacks;
|
|
8
9
|
rawPoints = [];
|
|
9
10
|
drawing = !1;
|
|
10
11
|
_active = !1;
|
|
11
|
-
constructor(
|
|
12
|
-
this.stage =
|
|
12
|
+
constructor(t, i, e) {
|
|
13
|
+
this.stage = t, this.callbacks = e, this.preview = new a(), this.preview.label = "freehand-preview", this.preview.visible = !1, i.addChild(this.preview);
|
|
13
14
|
}
|
|
14
15
|
get active() {
|
|
15
16
|
return this._active;
|
|
@@ -20,19 +21,19 @@ var w = class {
|
|
|
20
21
|
deactivate() {
|
|
21
22
|
this._active = !1, this.drawing = !1, this.rawPoints = [], this.preview.destroyed || (this.preview.clear(), this.preview.visible = !1), this.stage.off("pointerdown", this._onDown, this), this.stage.off("globalpointermove", this._onMove, this), this.stage.off("pointerup", this._onUp, this), this.stage.off("pointerupoutside", this._onUp, this);
|
|
22
23
|
}
|
|
23
|
-
_onDown = (
|
|
24
|
-
if (
|
|
25
|
-
const
|
|
26
|
-
this.drawing = !0, this.rawPoints = [
|
|
24
|
+
_onDown = (t) => {
|
|
25
|
+
if (t.button !== 0) return;
|
|
26
|
+
const i = this.callbacks.screenToWorld(t.global.x, t.global.y);
|
|
27
|
+
this.drawing = !0, this.rawPoints = [i], this.preview.visible = !0, this.preview.clear();
|
|
27
28
|
};
|
|
28
|
-
_onMove = (
|
|
29
|
+
_onMove = (t) => {
|
|
29
30
|
if (!this.drawing) return;
|
|
30
|
-
const
|
|
31
|
-
if (this.rawPoints.push(
|
|
31
|
+
const i = this.callbacks.screenToWorld(t.global.x, t.global.y);
|
|
32
|
+
if (this.rawPoints.push(i), this.preview.clear(), !(this.rawPoints.length < 2)) {
|
|
32
33
|
this.preview.moveTo(this.rawPoints[0].x, this.rawPoints[0].y);
|
|
33
34
|
for (let e = 1; e < this.rawPoints.length; e++) this.preview.lineTo(this.rawPoints[e].x, this.rawPoints[e].y);
|
|
34
35
|
this.preview.stroke({
|
|
35
|
-
color:
|
|
36
|
+
color: s("theme:base-content", "#374151"),
|
|
36
37
|
width: 2,
|
|
37
38
|
alpha: 0.6
|
|
38
39
|
});
|
|
@@ -44,22 +45,22 @@ var w = class {
|
|
|
44
45
|
this.rawPoints = [];
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
|
-
const
|
|
48
|
-
id:
|
|
48
|
+
const t = h(r(this.rawPoints, 2), 4), i = {
|
|
49
|
+
id: o("line"),
|
|
49
50
|
type: "freehand",
|
|
50
|
-
points:
|
|
51
|
-
strokeColor: "
|
|
51
|
+
points: t,
|
|
52
|
+
strokeColor: "theme:base-content",
|
|
52
53
|
strokeWidth: 2,
|
|
53
54
|
lineStyle: "solid"
|
|
54
55
|
};
|
|
55
|
-
this.callbacks.onLineComplete(
|
|
56
|
+
this.callbacks.onLineComplete(i), this.rawPoints = [];
|
|
56
57
|
};
|
|
57
58
|
destroy() {
|
|
58
59
|
this.deactivate(), this.preview.destroyed || this.preview.destroy();
|
|
59
60
|
}
|
|
60
61
|
};
|
|
61
62
|
export {
|
|
62
|
-
|
|
63
|
+
v as FreehandTool
|
|
63
64
|
};
|
|
64
65
|
|
|
65
66
|
//# sourceMappingURL=FreehandTool.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FreehandTool.js","names":[],"sources":["../../../../../src/components/pro/Flow/lines/FreehandTool.ts"],"sourcesContent":["import { Graphics, Container, FederatedPointerEvent } from 'pixi.js';\nimport { simplifyPath, smoothCatmullRom, type Point } from './lineSmoothing';\nimport type { FlowLine } from '../types';\nimport { generateId } from '../nodes/nodeUtils';\n\nexport interface FreehandToolCallbacks {\n /** Called when a freehand line is finished */\n onLineComplete: (line: FlowLine) => void;\n /** Convert screen coords to world coords */\n screenToWorld: (sx: number, sy: number) => { x: number; y: number };\n}\n\n/**\n * Captures pointer trail for freehand drawing, smooths and stores as FlowLine.\n */\nexport class FreehandTool {\n private stage: Container;\n private preview: Graphics;\n private callbacks: FreehandToolCallbacks;\n private rawPoints: Point[] = [];\n private drawing = false;\n private _active = false;\n\n constructor(stage: Container, world: Container, callbacks: FreehandToolCallbacks) {\n this.stage = stage;\n this.callbacks = callbacks;\n this.preview = new Graphics();\n this.preview.label = 'freehand-preview';\n this.preview.visible = false;\n world.addChild(this.preview);\n }\n\n get active(): boolean { return this._active; }\n\n activate(): void {\n this._active = true;\n this.stage.on('pointerdown', this._onDown, this);\n this.stage.on('globalpointermove', this._onMove, this);\n this.stage.on('pointerup', this._onUp, this);\n this.stage.on('pointerupoutside', this._onUp, this);\n }\n\n deactivate(): void {\n this._active = false;\n this.drawing = false;\n this.rawPoints = [];\n if (!this.preview.destroyed) {\n this.preview.clear();\n this.preview.visible = false;\n }\n this.stage.off('pointerdown', this._onDown, this);\n this.stage.off('globalpointermove', this._onMove, this);\n this.stage.off('pointerup', this._onUp, this);\n this.stage.off('pointerupoutside', this._onUp, this);\n }\n\n private _onDown = (e: FederatedPointerEvent): void => {\n if (e.button !== 0) return;\n const world = this.callbacks.screenToWorld(e.global.x, e.global.y);\n this.drawing = true;\n this.rawPoints = [world];\n this.preview.visible = true;\n this.preview.clear();\n };\n\n private _onMove = (e: FederatedPointerEvent): void => {\n if (!this.drawing) return;\n const world = this.callbacks.screenToWorld(e.global.x, e.global.y);\n this.rawPoints.push(world);\n\n // Draw preview\n this.preview.clear();\n if (this.rawPoints.length < 2) return;\n this.preview.moveTo(this.rawPoints[0].x, this.rawPoints[0].y);\n for (let i = 1; i < this.rawPoints.length; i++) {\n this.preview.lineTo(this.rawPoints[i].x, this.rawPoints[i].y);\n }\n this.preview.stroke({ color:
|
|
1
|
+
{"version":3,"file":"FreehandTool.js","names":[],"sources":["../../../../../src/components/pro/Flow/lines/FreehandTool.ts"],"sourcesContent":["import { Graphics, Container, FederatedPointerEvent } from 'pixi.js';\nimport { simplifyPath, smoothCatmullRom, type Point } from './lineSmoothing';\nimport type { FlowLine } from '../types';\nimport { generateId } from '../nodes/nodeUtils';\nimport { resolveThemeColor } from '../utils/themeColor';\n\nexport interface FreehandToolCallbacks {\n /** Called when a freehand line is finished */\n onLineComplete: (line: FlowLine) => void;\n /** Convert screen coords to world coords */\n screenToWorld: (sx: number, sy: number) => { x: number; y: number };\n}\n\n/**\n * Captures pointer trail for freehand drawing, smooths and stores as FlowLine.\n */\nexport class FreehandTool {\n private stage: Container;\n private preview: Graphics;\n private callbacks: FreehandToolCallbacks;\n private rawPoints: Point[] = [];\n private drawing = false;\n private _active = false;\n\n constructor(stage: Container, world: Container, callbacks: FreehandToolCallbacks) {\n this.stage = stage;\n this.callbacks = callbacks;\n this.preview = new Graphics();\n this.preview.label = 'freehand-preview';\n this.preview.visible = false;\n world.addChild(this.preview);\n }\n\n get active(): boolean { return this._active; }\n\n activate(): void {\n this._active = true;\n this.stage.on('pointerdown', this._onDown, this);\n this.stage.on('globalpointermove', this._onMove, this);\n this.stage.on('pointerup', this._onUp, this);\n this.stage.on('pointerupoutside', this._onUp, this);\n }\n\n deactivate(): void {\n this._active = false;\n this.drawing = false;\n this.rawPoints = [];\n if (!this.preview.destroyed) {\n this.preview.clear();\n this.preview.visible = false;\n }\n this.stage.off('pointerdown', this._onDown, this);\n this.stage.off('globalpointermove', this._onMove, this);\n this.stage.off('pointerup', this._onUp, this);\n this.stage.off('pointerupoutside', this._onUp, this);\n }\n\n private _onDown = (e: FederatedPointerEvent): void => {\n if (e.button !== 0) return;\n const world = this.callbacks.screenToWorld(e.global.x, e.global.y);\n this.drawing = true;\n this.rawPoints = [world];\n this.preview.visible = true;\n this.preview.clear();\n };\n\n private _onMove = (e: FederatedPointerEvent): void => {\n if (!this.drawing) return;\n const world = this.callbacks.screenToWorld(e.global.x, e.global.y);\n this.rawPoints.push(world);\n\n // Draw preview\n this.preview.clear();\n if (this.rawPoints.length < 2) return;\n this.preview.moveTo(this.rawPoints[0].x, this.rawPoints[0].y);\n for (let i = 1; i < this.rawPoints.length; i++) {\n this.preview.lineTo(this.rawPoints[i].x, this.rawPoints[i].y);\n }\n this.preview.stroke({ color: resolveThemeColor('theme:base-content', '#374151'), width: 2, alpha: 0.6 });\n };\n\n private _onUp = (): void => {\n if (!this.drawing) return;\n this.drawing = false;\n this.preview.clear();\n this.preview.visible = false;\n\n if (this.rawPoints.length < 3) {\n this.rawPoints = [];\n return;\n }\n\n const simplified = simplifyPath(this.rawPoints, 2);\n const smoothed = smoothCatmullRom(simplified, 4);\n\n const line: FlowLine = {\n id: generateId('line'),\n type: 'freehand',\n points: smoothed,\n strokeColor: 'theme:base-content',\n strokeWidth: 2,\n lineStyle: 'solid',\n };\n\n this.callbacks.onLineComplete(line);\n this.rawPoints = [];\n };\n\n destroy(): void {\n this.deactivate();\n if (!this.preview.destroyed) this.preview.destroy();\n }\n}\n"],"mappings":";;;;AAgBA,IAAa,IAAb,MAA0B;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAA6B,CAAC;AAAA,EAC9B,UAAkB;AAAA,EAClB,UAAkB;AAAA,EAElB,YAAY,GAAkB,GAAkB,GAAkC;AAChF,SAAK,QAAQ,GACb,KAAK,YAAY,GACjB,KAAK,UAAU,IAAI,EAAS,GAC5B,KAAK,QAAQ,QAAQ,oBACrB,KAAK,QAAQ,UAAU,IACvB,EAAM,SAAS,KAAK,OAAO;AAAA,EAC7B;AAAA,EAEA,IAAI,SAAkB;AAAE,WAAO,KAAK;AAAA,EAAS;AAAA,EAE7C,WAAiB;AACf,SAAK,UAAU,IACf,KAAK,MAAM,GAAG,eAAe,KAAK,SAAS,IAAI,GAC/C,KAAK,MAAM,GAAG,qBAAqB,KAAK,SAAS,IAAI,GACrD,KAAK,MAAM,GAAG,aAAa,KAAK,OAAO,IAAI,GAC3C,KAAK,MAAM,GAAG,oBAAoB,KAAK,OAAO,IAAI;AAAA,EACpD;AAAA,EAEA,aAAmB;AACjB,SAAK,UAAU,IACf,KAAK,UAAU,IACf,KAAK,YAAY,CAAC,GACb,KAAK,QAAQ,cAChB,KAAK,QAAQ,MAAM,GACnB,KAAK,QAAQ,UAAU,KAEzB,KAAK,MAAM,IAAI,eAAe,KAAK,SAAS,IAAI,GAChD,KAAK,MAAM,IAAI,qBAAqB,KAAK,SAAS,IAAI,GACtD,KAAK,MAAM,IAAI,aAAa,KAAK,OAAO,IAAI,GAC5C,KAAK,MAAM,IAAI,oBAAoB,KAAK,OAAO,IAAI;AAAA,EACrD;AAAA,EAEA,UAAA,CAAmB,MAAmC;AACpD,QAAI,EAAE,WAAW,EAAG;AACpB,UAAM,IAAQ,KAAK,UAAU,cAAc,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC;AACjE,SAAK,UAAU,IACf,KAAK,YAAY,CAAC,CAAK,GACvB,KAAK,QAAQ,UAAU,IACvB,KAAK,QAAQ,MAAM;AAAA,EACrB;AAAA,EAEA,UAAA,CAAmB,MAAmC;AACpD,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,IAAQ,KAAK,UAAU,cAAc,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC;AAKjE,QAJA,KAAK,UAAU,KAAK,CAAK,GAGzB,KAAK,QAAQ,MAAM,GACf,OAAK,UAAU,SAAS,IAC5B;AAAA,WAAK,QAAQ,OAAO,KAAK,UAAU,CAAA,EAAG,GAAG,KAAK,UAAU,CAAA,EAAG,CAAC;AAC5D,eAAS,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,IACzC,MAAK,QAAQ,OAAO,KAAK,UAAU,CAAA,EAAG,GAAG,KAAK,UAAU,CAAA,EAAG,CAAC;AAE9D,WAAK,QAAQ,OAAO;AAAA,QAAE,OAAO,EAAkB,sBAAsB,SAAS;AAAA,QAAG,OAAO;AAAA,QAAG,OAAO;AAAA,MAAI,CAAC;AAAA;AAAA,EACzG;AAAA,EAEA,QAAA,MAA4B;AAC1B,QAAI,CAAC,KAAK,QAAS;AAKnB,QAJA,KAAK,UAAU,IACf,KAAK,QAAQ,MAAM,GACnB,KAAK,QAAQ,UAAU,IAEnB,KAAK,UAAU,SAAS,GAAG;AAC7B,WAAK,YAAY,CAAC;AAClB;AAAA,IACF;AAGA,UAAM,IAAW,EADE,EAAa,KAAK,WAAW,CACd,GAAY,CAAC,GAEzC,IAAiB;AAAA,MACrB,IAAI,EAAW,MAAM;AAAA,MACrB,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,aAAa;AAAA,MACb,WAAW;AAAA,IACb;AAEA,SAAK,UAAU,eAAe,CAAI,GAClC,KAAK,YAAY,CAAC;AAAA,EACpB;AAAA,EAEA,UAAgB;AACd,SAAK,WAAW,GACX,KAAK,QAAQ,aAAW,KAAK,QAAQ,QAAQ;AAAA,EACpD;AACF"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveThemeColor as o } from "../utils/themeColor.js";
|
|
2
|
+
import { generateId as n } from "../nodes/nodeUtils.js";
|
|
2
3
|
import { Graphics as h } from "pixi.js";
|
|
3
|
-
|
|
4
|
+
function r() {
|
|
5
|
+
return o("theme:base-content", "#374151");
|
|
6
|
+
}
|
|
7
|
+
var p = class {
|
|
4
8
|
stage;
|
|
5
9
|
preview;
|
|
6
10
|
callbacks;
|
|
@@ -16,8 +20,8 @@ var r = class {
|
|
|
16
20
|
x: 0,
|
|
17
21
|
y: 0
|
|
18
22
|
};
|
|
19
|
-
constructor(i,
|
|
20
|
-
this.stage = i, this.callbacks =
|
|
23
|
+
constructor(i, e, t) {
|
|
24
|
+
this.stage = i, this.callbacks = t, this.preview = new h(), this.preview.label = "geo-line-preview", this.preview.visible = !1, e.addChild(this.preview), this._handleKeyDown = this._handleKeyDown.bind(this);
|
|
21
25
|
}
|
|
22
26
|
get active() {
|
|
23
27
|
return this._active;
|
|
@@ -39,43 +43,43 @@ var r = class {
|
|
|
39
43
|
}
|
|
40
44
|
_onClick = (i) => {
|
|
41
45
|
if (i.button !== 0) return;
|
|
42
|
-
const
|
|
43
|
-
if (this._lastClickTime =
|
|
46
|
+
const e = this.callbacks.screenToWorld(i.global.x, i.global.y), t = Date.now(), s = t - this._lastClickTime < 350 && Math.hypot(e.x - this._lastClickPos.x, e.y - this._lastClickPos.y) < 10;
|
|
47
|
+
if (this._lastClickTime = t, this._lastClickPos = e, s && this._mode === "polyline" && this.points.length >= 2) {
|
|
44
48
|
this._finishLine();
|
|
45
49
|
return;
|
|
46
50
|
}
|
|
47
|
-
this.points.push(
|
|
51
|
+
this.points.push(e), (this._mode === "straight" || this._mode === "arrow") && this.points.length >= 2 && this._finishLine();
|
|
48
52
|
};
|
|
49
53
|
_onMove = (i) => {
|
|
50
|
-
const
|
|
51
|
-
if (this._currentPos =
|
|
54
|
+
const e = this.callbacks.screenToWorld(i.global.x, i.global.y);
|
|
55
|
+
if (this._currentPos = e, this.points.length !== 0) {
|
|
52
56
|
this.preview.visible = !0, this.preview.clear(), this.preview.moveTo(this.points[0].x, this.points[0].y);
|
|
53
|
-
for (let
|
|
54
|
-
this.preview.lineTo(
|
|
55
|
-
color:
|
|
57
|
+
for (let t = 1; t < this.points.length; t++) this.preview.lineTo(this.points[t].x, this.points[t].y);
|
|
58
|
+
this.preview.lineTo(e.x, e.y), this.preview.stroke({
|
|
59
|
+
color: r(),
|
|
56
60
|
width: 2,
|
|
57
61
|
alpha: 0.5
|
|
58
62
|
});
|
|
59
63
|
}
|
|
60
64
|
};
|
|
61
65
|
_finishLine() {
|
|
62
|
-
const i = this._mode === "arrow" ? "arrowclosed" : "none",
|
|
63
|
-
id:
|
|
64
|
-
type:
|
|
66
|
+
const i = this._mode === "arrow" ? "arrowclosed" : "none", e = this._mode === "arrow" ? "arrow" : this._mode, t = {
|
|
67
|
+
id: n("line"),
|
|
68
|
+
type: e,
|
|
65
69
|
points: [...this.points],
|
|
66
|
-
strokeColor: "
|
|
70
|
+
strokeColor: "theme:base-content",
|
|
67
71
|
strokeWidth: 2,
|
|
68
72
|
lineStyle: "solid",
|
|
69
73
|
markerEnd: i
|
|
70
74
|
};
|
|
71
|
-
this.callbacks.onLineComplete(
|
|
75
|
+
this.callbacks.onLineComplete(t), this.points = [], this.preview.clear(), this.preview.visible = !1;
|
|
72
76
|
}
|
|
73
77
|
destroy() {
|
|
74
78
|
this.deactivate(), this.preview.destroyed || this.preview.destroy();
|
|
75
79
|
}
|
|
76
80
|
};
|
|
77
81
|
export {
|
|
78
|
-
|
|
82
|
+
p as GeometricLineTool
|
|
79
83
|
};
|
|
80
84
|
|
|
81
85
|
//# sourceMappingURL=GeometricLineTool.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeometricLineTool.js","names":[],"sources":["../../../../../src/components/pro/Flow/lines/GeometricLineTool.ts"],"sourcesContent":["import { Graphics, Container, FederatedPointerEvent } from 'pixi.js';\nimport type { FlowLine, FlowLineType, FlowEdgeMarkerKind } from '../types';\nimport { generateId } from '../nodes/nodeUtils';\n\nexport interface GeometricLineToolCallbacks {\n onLineComplete: (line: FlowLine) => void;\n screenToWorld: (sx: number, sy: number) => { x: number; y: number };\n}\n\ntype GeoMode = 'straight' | 'polyline' | 'arrow';\n\n/**\n * Click-to-place geometric lines: straight, polyline, and arrow.\n * - straight/arrow: click start, click end\n * - polyline: click each point, double-click to finish\n */\nexport class GeometricLineTool {\n private stage: Container;\n private preview: Graphics;\n private callbacks: GeometricLineToolCallbacks;\n private points: Array<{ x: number; y: number }> = [];\n private _active = false;\n private _mode: GeoMode = 'straight';\n private _currentPos = { x: 0, y: 0 };\n private _lastClickTime = 0;\n private _lastClickPos = { x: 0, y: 0 };\n\n constructor(stage: Container, world: Container, callbacks: GeometricLineToolCallbacks) {\n this.stage = stage;\n this.callbacks = callbacks;\n this.preview = new Graphics();\n this.preview.label = 'geo-line-preview';\n this.preview.visible = false;\n world.addChild(this.preview);\n this._handleKeyDown = this._handleKeyDown.bind(this);\n }\n\n get active(): boolean { return this._active; }\n get mode(): GeoMode { return this._mode; }\n set mode(m: GeoMode) { this._mode = m; }\n\n activate(mode: GeoMode = 'straight'): void {\n this._active = true;\n this._mode = mode;\n this.points = [];\n this._lastClickTime = 0;\n this.stage.on('pointerdown', this._onClick, this);\n this.stage.on('globalpointermove', this._onMove, this);\n window.addEventListener('keydown', this._handleKeyDown);\n }\n\n deactivate(): void {\n this._active = false;\n this.points = [];\n if (!this.preview.destroyed) {\n this.preview.clear();\n this.preview.visible = false;\n }\n this.stage.off('pointerdown', this._onClick, this);\n this.stage.off('globalpointermove', this._onMove, this);\n window.removeEventListener('keydown', this._handleKeyDown);\n }\n\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === 'Enter' || e.key === 'Return') {\n if (this._mode === 'polyline' && this.points.length >= 2) {\n this._finishLine();\n }\n }\n }\n\n private _onClick = (e: FederatedPointerEvent): void => {\n if (e.button !== 0) return;\n const world = this.callbacks.screenToWorld(e.global.x, e.global.y);\n\n const now = Date.now();\n const isDbl = now - this._lastClickTime < 350\n && Math.hypot(world.x - this._lastClickPos.x, world.y - this._lastClickPos.y) < 10;\n this._lastClickTime = now;\n this._lastClickPos = world;\n\n if (isDbl && this._mode === 'polyline' && this.points.length >= 2) {\n this._finishLine();\n return;\n }\n\n this.points.push(world);\n if ((this._mode === 'straight' || this._mode === 'arrow') && this.points.length >= 2) {\n this._finishLine();\n }\n };\n\n private _onMove = (e: FederatedPointerEvent): void => {\n const world = this.callbacks.screenToWorld(e.global.x, e.global.y);\n this._currentPos = world;\n\n if (this.points.length === 0) return;\n this.preview.visible = true;\n this.preview.clear();\n\n this.preview.moveTo(this.points[0].x, this.points[0].y);\n for (let i = 1; i < this.points.length; i++) {\n this.preview.lineTo(this.points[i].x, this.points[i].y);\n }\n this.preview.lineTo(world.x, world.y);\n this.preview.stroke({ color:
|
|
1
|
+
{"version":3,"file":"GeometricLineTool.js","names":[],"sources":["../../../../../src/components/pro/Flow/lines/GeometricLineTool.ts"],"sourcesContent":["import { Graphics, Container, FederatedPointerEvent } from 'pixi.js';\nimport type { FlowLine, FlowLineType, FlowEdgeMarkerKind } from '../types';\nimport { generateId } from '../nodes/nodeUtils';\nimport { resolveThemeColor } from '../utils/themeColor';\n\nfunction previewStrokeColor(): string {\n return resolveThemeColor('theme:base-content', '#374151');\n}\n\nexport interface GeometricLineToolCallbacks {\n onLineComplete: (line: FlowLine) => void;\n screenToWorld: (sx: number, sy: number) => { x: number; y: number };\n}\n\ntype GeoMode = 'straight' | 'polyline' | 'arrow';\n\n/**\n * Click-to-place geometric lines: straight, polyline, and arrow.\n * - straight/arrow: click start, click end\n * - polyline: click each point, double-click to finish\n */\nexport class GeometricLineTool {\n private stage: Container;\n private preview: Graphics;\n private callbacks: GeometricLineToolCallbacks;\n private points: Array<{ x: number; y: number }> = [];\n private _active = false;\n private _mode: GeoMode = 'straight';\n private _currentPos = { x: 0, y: 0 };\n private _lastClickTime = 0;\n private _lastClickPos = { x: 0, y: 0 };\n\n constructor(stage: Container, world: Container, callbacks: GeometricLineToolCallbacks) {\n this.stage = stage;\n this.callbacks = callbacks;\n this.preview = new Graphics();\n this.preview.label = 'geo-line-preview';\n this.preview.visible = false;\n world.addChild(this.preview);\n this._handleKeyDown = this._handleKeyDown.bind(this);\n }\n\n get active(): boolean { return this._active; }\n get mode(): GeoMode { return this._mode; }\n set mode(m: GeoMode) { this._mode = m; }\n\n activate(mode: GeoMode = 'straight'): void {\n this._active = true;\n this._mode = mode;\n this.points = [];\n this._lastClickTime = 0;\n this.stage.on('pointerdown', this._onClick, this);\n this.stage.on('globalpointermove', this._onMove, this);\n window.addEventListener('keydown', this._handleKeyDown);\n }\n\n deactivate(): void {\n this._active = false;\n this.points = [];\n if (!this.preview.destroyed) {\n this.preview.clear();\n this.preview.visible = false;\n }\n this.stage.off('pointerdown', this._onClick, this);\n this.stage.off('globalpointermove', this._onMove, this);\n window.removeEventListener('keydown', this._handleKeyDown);\n }\n\n private _handleKeyDown(e: KeyboardEvent): void {\n if (e.key === 'Enter' || e.key === 'Return') {\n if (this._mode === 'polyline' && this.points.length >= 2) {\n this._finishLine();\n }\n }\n }\n\n private _onClick = (e: FederatedPointerEvent): void => {\n if (e.button !== 0) return;\n const world = this.callbacks.screenToWorld(e.global.x, e.global.y);\n\n const now = Date.now();\n const isDbl = now - this._lastClickTime < 350\n && Math.hypot(world.x - this._lastClickPos.x, world.y - this._lastClickPos.y) < 10;\n this._lastClickTime = now;\n this._lastClickPos = world;\n\n if (isDbl && this._mode === 'polyline' && this.points.length >= 2) {\n this._finishLine();\n return;\n }\n\n this.points.push(world);\n if ((this._mode === 'straight' || this._mode === 'arrow') && this.points.length >= 2) {\n this._finishLine();\n }\n };\n\n private _onMove = (e: FederatedPointerEvent): void => {\n const world = this.callbacks.screenToWorld(e.global.x, e.global.y);\n this._currentPos = world;\n\n if (this.points.length === 0) return;\n this.preview.visible = true;\n this.preview.clear();\n\n this.preview.moveTo(this.points[0].x, this.points[0].y);\n for (let i = 1; i < this.points.length; i++) {\n this.preview.lineTo(this.points[i].x, this.points[i].y);\n }\n this.preview.lineTo(world.x, world.y);\n this.preview.stroke({ color: previewStrokeColor(), width: 2, alpha: 0.5 });\n };\n\n private _finishLine(): void {\n const markerEnd: FlowEdgeMarkerKind = this._mode === 'arrow' ? 'arrowclosed' : 'none';\n const lineType: FlowLineType = this._mode === 'arrow' ? 'arrow' : this._mode;\n\n const line: FlowLine = {\n id: generateId('line'),\n type: lineType,\n points: [...this.points],\n strokeColor: 'theme:base-content',\n strokeWidth: 2,\n lineStyle: 'solid',\n markerEnd,\n };\n\n this.callbacks.onLineComplete(line);\n this.points = [];\n this.preview.clear();\n this.preview.visible = false;\n }\n\n destroy(): void {\n this.deactivate();\n if (!this.preview.destroyed) this.preview.destroy();\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import { resolveThemeColor as x } from "../utils/themeColor.js";
|
|
1
2
|
import { angleBetween as h, drawMarker as f } from "../edges/edgeMarkers.js";
|
|
2
|
-
import { drawDashedPolyline as
|
|
3
|
+
import { drawDashedPolyline as g } from "../utils/dashedLine.js";
|
|
3
4
|
import { Container as y, Graphics as m } from "pixi.js";
|
|
4
|
-
function
|
|
5
|
+
function u(n, e = 2) {
|
|
5
6
|
if (!(!n || n === "solid")) {
|
|
6
7
|
if (n === "dynamic") return [e * 4, e * 3];
|
|
7
8
|
if (n === "dotted") return [e, e * 2];
|
|
8
9
|
if (n === "dashed") return [e * 3, e * 2];
|
|
9
10
|
}
|
|
10
11
|
}
|
|
11
|
-
var
|
|
12
|
+
var L = class {
|
|
12
13
|
world;
|
|
13
14
|
lineLayer;
|
|
14
15
|
lines = /* @__PURE__ */ new Map();
|
|
@@ -23,36 +24,36 @@ var v = class {
|
|
|
23
24
|
}), this.world.addChildAt(this.lineLayer, Math.min(1, this.world.children.length));
|
|
24
25
|
}
|
|
25
26
|
sync(n, e) {
|
|
26
|
-
const
|
|
27
|
+
const s = /* @__PURE__ */ new Set();
|
|
27
28
|
for (const r of n) {
|
|
28
|
-
|
|
29
|
+
s.add(r.id);
|
|
29
30
|
let o = this.lines.get(r.id);
|
|
30
31
|
o || (o = this._create(r), this.lines.set(r.id, o)), this._update(o, r, e.has(r.id));
|
|
31
32
|
}
|
|
32
|
-
for (const [r, o] of this.lines)
|
|
33
|
+
for (const [r, o] of this.lines) s.has(r) || (this.lineLayer.removeChild(o.container), o.container.destroy({ children: !0 }), this.lines.delete(r));
|
|
33
34
|
}
|
|
34
35
|
_create(n) {
|
|
35
|
-
const e = new y({ label: `line-${n.id}` }),
|
|
36
|
-
|
|
36
|
+
const e = new y({ label: `line-${n.id}` }), s = new m();
|
|
37
|
+
s.label = "line-hitarea", s.eventMode = "static", s.cursor = "pointer", s.alpha = 1e-3, e.addChild(s);
|
|
37
38
|
const r = new m();
|
|
38
39
|
return r.label = "line-gfx", e.addChild(r), this.lineLayer.addChild(e), {
|
|
39
40
|
container: e,
|
|
40
41
|
gfx: r,
|
|
41
|
-
hitArea:
|
|
42
|
+
hitArea: s,
|
|
42
43
|
lineId: n.id
|
|
43
44
|
};
|
|
44
45
|
}
|
|
45
|
-
_update(n, e,
|
|
46
|
+
_update(n, e, s) {
|
|
46
47
|
n.container.zIndex = e.zIndex ?? 0;
|
|
47
48
|
const { gfx: r, hitArea: o } = n, t = e.points;
|
|
48
49
|
if (t.length < 2) return;
|
|
49
|
-
const
|
|
50
|
+
const a = s ? "#3b82f6" : x(e.strokeColor, "#374151"), d = e.strokeWidth;
|
|
50
51
|
r.clear();
|
|
51
|
-
const l =
|
|
52
|
+
const l = u(e.lineStyle, d);
|
|
52
53
|
if (l) {
|
|
53
54
|
const i = e.lineStyle === "dynamic" ? this._dynamicOffset : 0;
|
|
54
|
-
|
|
55
|
-
color:
|
|
55
|
+
g(r, e.closed ? [...t, t[0]] : t, l, i), r.stroke({
|
|
56
|
+
color: a,
|
|
56
57
|
width: d,
|
|
57
58
|
cap: "round"
|
|
58
59
|
});
|
|
@@ -60,17 +61,17 @@ var v = class {
|
|
|
60
61
|
r.moveTo(t[0].x, t[0].y);
|
|
61
62
|
for (let i = 1; i < t.length; i++) r.lineTo(t[i].x, t[i].y);
|
|
62
63
|
e.closed && r.closePath(), r.stroke({
|
|
63
|
-
color:
|
|
64
|
+
color: a,
|
|
64
65
|
width: d
|
|
65
66
|
});
|
|
66
67
|
}
|
|
67
68
|
if (e.markerStart && e.markerStart !== "none" && t.length >= 2) {
|
|
68
69
|
const i = h(t[1].x, t[1].y, t[0].x, t[0].y);
|
|
69
|
-
f(r, e.markerStart, t[0].x, t[0].y, i,
|
|
70
|
+
f(r, e.markerStart, t[0].x, t[0].y, i, a);
|
|
70
71
|
}
|
|
71
72
|
if (e.markerEnd && e.markerEnd !== "none" && t.length >= 2) {
|
|
72
73
|
const i = t[t.length - 1], c = t[t.length - 2], p = h(c.x, c.y, i.x, i.y);
|
|
73
|
-
f(r, e.markerEnd, i.x, i.y, p,
|
|
74
|
+
f(r, e.markerEnd, i.x, i.y, p, a);
|
|
74
75
|
}
|
|
75
76
|
o.clear(), o.moveTo(t[0].x, t[0].y);
|
|
76
77
|
for (let i = 1; i < t.length; i++) o.lineTo(t[i].x, t[i].y);
|
|
@@ -85,7 +86,7 @@ var v = class {
|
|
|
85
86
|
}
|
|
86
87
|
};
|
|
87
88
|
export {
|
|
88
|
-
|
|
89
|
+
L as LineRenderer
|
|
89
90
|
};
|
|
90
91
|
|
|
91
92
|
//# sourceMappingURL=LineRenderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LineRenderer.js","names":[],"sources":["../../../../../src/components/pro/Flow/lines/LineRenderer.ts"],"sourcesContent":["import { Container, Graphics } from 'pixi.js';\nimport type { FlowLine } from '../types';\nimport { drawMarker, angleBetween } from '../edges/edgeMarkers';\nimport { drawDashedPolyline } from '../utils/dashedLine';\n\nfunction getLineDash(style?: string, width = 2): number[] | undefined {\n if (!style || style === 'solid') return undefined;\n if (style === 'dynamic') return [width * 4, width * 3];\n if (style === 'dotted') return [width, width * 2];\n if (style === 'dashed') return [width * 3, width * 2];\n return undefined;\n}\n\ninterface LineDisplay {\n container: Container;\n gfx: Graphics;\n hitArea: Graphics;\n lineId: string;\n}\n\n/**\n * Renders independent FlowLine[] objects on the canvas.\n */\nexport class LineRenderer {\n private world: Container;\n private lineLayer: Container;\n private lines = new Map<string, LineDisplay>();\n private _dynamicOffset = 0;\n\n /** Call once per frame to advance the dynamic dash animation. */\n advanceAnimation(deltaMs: number): void {\n this._dynamicOffset = (this._dynamicOffset + deltaMs * 0.06) % 1000;\n }\n\n constructor(world: Container) {\n this.world = world;\n this.lineLayer = new Container({ label: 'lines', sortableChildren: true });\n // Lines on top of edges but below nodes\n this.world.addChildAt(this.lineLayer, Math.min(1, this.world.children.length));\n }\n\n sync(flowLines: FlowLine[], selectedIds: Set<string>): void {\n const seen = new Set<string>();\n\n for (const line of flowLines) {\n seen.add(line.id);\n let display = this.lines.get(line.id);\n if (!display) {\n display = this._create(line);\n this.lines.set(line.id, display);\n }\n this._update(display, line, selectedIds.has(line.id));\n }\n\n for (const [id, display] of this.lines) {\n if (!seen.has(id)) {\n this.lineLayer.removeChild(display.container);\n display.container.destroy({ children: true });\n this.lines.delete(id);\n }\n }\n }\n\n private _create(line: FlowLine): LineDisplay {\n const container = new Container({ label: `line-${line.id}` });\n\n const hitArea = new Graphics();\n hitArea.label = 'line-hitarea';\n hitArea.eventMode = 'static';\n hitArea.cursor = 'pointer';\n hitArea.alpha = 0.001;\n container.addChild(hitArea);\n\n const gfx = new Graphics();\n gfx.label = 'line-gfx';\n container.addChild(gfx);\n\n this.lineLayer.addChild(container);\n return { container, gfx, hitArea, lineId: line.id };\n }\n\n private _update(display: LineDisplay, line: FlowLine, selected: boolean): void {\n display.container.zIndex = line.zIndex ?? 0;\n const { gfx, hitArea } = display;\n const pts = line.points;\n if (pts.length < 2) return;\n\n const color = selected ? '#3b82f6' : line.strokeColor;\n const width = line.strokeWidth;\n\n gfx.clear();\n const dash = getLineDash(line.lineStyle, width);\n if (dash) {\n const offset = line.lineStyle === 'dynamic' ? this._dynamicOffset : 0;\n const drawPts = line.closed ? [...pts, pts[0]] : pts;\n drawDashedPolyline(gfx, drawPts, dash, offset);\n gfx.stroke({ color, width, cap: 'round' as const });\n } else {\n gfx.moveTo(pts[0].x, pts[0].y);\n for (let i = 1; i < pts.length; i++) {\n gfx.lineTo(pts[i].x, pts[i].y);\n }\n if (line.closed) gfx.closePath();\n gfx.stroke({ color, width });\n }\n\n // Markers\n if (line.markerStart && line.markerStart !== 'none' && pts.length >= 2) {\n const angle = angleBetween(pts[1].x, pts[1].y, pts[0].x, pts[0].y);\n drawMarker(gfx, line.markerStart, pts[0].x, pts[0].y, angle, color);\n }\n if (line.markerEnd && line.markerEnd !== 'none' && pts.length >= 2) {\n const last = pts[pts.length - 1];\n const prev = pts[pts.length - 2];\n const angle = angleBetween(prev.x, prev.y, last.x, last.y);\n drawMarker(gfx, line.markerEnd, last.x, last.y, angle, color);\n }\n\n // Hit area\n hitArea.clear();\n hitArea.moveTo(pts[0].x, pts[0].y);\n for (let i = 1; i < pts.length; i++) {\n hitArea.lineTo(pts[i].x, pts[i].y);\n }\n hitArea.stroke({ color: '#000000', width: Math.max(width + 10, 14) });\n hitArea.alpha = 0.001;\n }\n\n destroy(): void {\n for (const [, display] of this.lines) {\n display.container.destroy({ children: true });\n }\n this.lines.clear();\n this.lineLayer.destroy({ children: true });\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"LineRenderer.js","names":[],"sources":["../../../../../src/components/pro/Flow/lines/LineRenderer.ts"],"sourcesContent":["import { Container, Graphics } from 'pixi.js';\nimport type { FlowLine } from '../types';\nimport { drawMarker, angleBetween } from '../edges/edgeMarkers';\nimport { drawDashedPolyline } from '../utils/dashedLine';\nimport { resolveThemeColor } from '../utils/themeColor';\n\nfunction getLineDash(style?: string, width = 2): number[] | undefined {\n if (!style || style === 'solid') return undefined;\n if (style === 'dynamic') return [width * 4, width * 3];\n if (style === 'dotted') return [width, width * 2];\n if (style === 'dashed') return [width * 3, width * 2];\n return undefined;\n}\n\ninterface LineDisplay {\n container: Container;\n gfx: Graphics;\n hitArea: Graphics;\n lineId: string;\n}\n\n/**\n * Renders independent FlowLine[] objects on the canvas.\n */\nexport class LineRenderer {\n private world: Container;\n private lineLayer: Container;\n private lines = new Map<string, LineDisplay>();\n private _dynamicOffset = 0;\n\n /** Call once per frame to advance the dynamic dash animation. */\n advanceAnimation(deltaMs: number): void {\n this._dynamicOffset = (this._dynamicOffset + deltaMs * 0.06) % 1000;\n }\n\n constructor(world: Container) {\n this.world = world;\n this.lineLayer = new Container({ label: 'lines', sortableChildren: true });\n // Lines on top of edges but below nodes\n this.world.addChildAt(this.lineLayer, Math.min(1, this.world.children.length));\n }\n\n sync(flowLines: FlowLine[], selectedIds: Set<string>): void {\n const seen = new Set<string>();\n\n for (const line of flowLines) {\n seen.add(line.id);\n let display = this.lines.get(line.id);\n if (!display) {\n display = this._create(line);\n this.lines.set(line.id, display);\n }\n this._update(display, line, selectedIds.has(line.id));\n }\n\n for (const [id, display] of this.lines) {\n if (!seen.has(id)) {\n this.lineLayer.removeChild(display.container);\n display.container.destroy({ children: true });\n this.lines.delete(id);\n }\n }\n }\n\n private _create(line: FlowLine): LineDisplay {\n const container = new Container({ label: `line-${line.id}` });\n\n const hitArea = new Graphics();\n hitArea.label = 'line-hitarea';\n hitArea.eventMode = 'static';\n hitArea.cursor = 'pointer';\n hitArea.alpha = 0.001;\n container.addChild(hitArea);\n\n const gfx = new Graphics();\n gfx.label = 'line-gfx';\n container.addChild(gfx);\n\n this.lineLayer.addChild(container);\n return { container, gfx, hitArea, lineId: line.id };\n }\n\n private _update(display: LineDisplay, line: FlowLine, selected: boolean): void {\n display.container.zIndex = line.zIndex ?? 0;\n const { gfx, hitArea } = display;\n const pts = line.points;\n if (pts.length < 2) return;\n\n const color = selected ? '#3b82f6' : resolveThemeColor(line.strokeColor, '#374151');\n const width = line.strokeWidth;\n\n gfx.clear();\n const dash = getLineDash(line.lineStyle, width);\n if (dash) {\n const offset = line.lineStyle === 'dynamic' ? this._dynamicOffset : 0;\n const drawPts = line.closed ? [...pts, pts[0]] : pts;\n drawDashedPolyline(gfx, drawPts, dash, offset);\n gfx.stroke({ color, width, cap: 'round' as const });\n } else {\n gfx.moveTo(pts[0].x, pts[0].y);\n for (let i = 1; i < pts.length; i++) {\n gfx.lineTo(pts[i].x, pts[i].y);\n }\n if (line.closed) gfx.closePath();\n gfx.stroke({ color, width });\n }\n\n // Markers\n if (line.markerStart && line.markerStart !== 'none' && pts.length >= 2) {\n const angle = angleBetween(pts[1].x, pts[1].y, pts[0].x, pts[0].y);\n drawMarker(gfx, line.markerStart, pts[0].x, pts[0].y, angle, color);\n }\n if (line.markerEnd && line.markerEnd !== 'none' && pts.length >= 2) {\n const last = pts[pts.length - 1];\n const prev = pts[pts.length - 2];\n const angle = angleBetween(prev.x, prev.y, last.x, last.y);\n drawMarker(gfx, line.markerEnd, last.x, last.y, angle, color);\n }\n\n // Hit area\n hitArea.clear();\n hitArea.moveTo(pts[0].x, pts[0].y);\n for (let i = 1; i < pts.length; i++) {\n hitArea.lineTo(pts[i].x, pts[i].y);\n }\n hitArea.stroke({ color: '#000000', width: Math.max(width + 10, 14) });\n hitArea.alpha = 0.001;\n }\n\n destroy(): void {\n for (const [, display] of this.lines) {\n display.container.destroy({ children: true });\n }\n this.lines.clear();\n this.lineLayer.destroy({ children: true });\n }\n}\n"],"mappings":"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"}
|