@pixerate/editor-svelte 0.15.2 → 0.16.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/BubbleMenu.svelte.d.ts +14 -0
- package/dist/BubbleMenu.svelte.d.ts.map +1 -0
- package/{src → dist}/EditableTextNodeEditor.svelte +1 -1
- package/dist/EditableTextNodeEditor.svelte.d.ts +26 -0
- package/dist/EditableTextNodeEditor.svelte.d.ts.map +1 -0
- package/dist/TemplateRenderer.svelte.d.ts +14 -0
- package/dist/TemplateRenderer.svelte.d.ts.map +1 -0
- package/dist/canvas/AgentPresenceLayer.svelte.d.ts +9 -0
- package/dist/canvas/AgentPresenceLayer.svelte.d.ts.map +1 -0
- package/dist/canvas/FloatingHorizontalScrollbar.svelte.d.ts +9 -0
- package/dist/canvas/FloatingHorizontalScrollbar.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasClipboard.svelte.d.ts +32 -0
- package/dist/canvas/createCanvasClipboard.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasClipboard.svelte.js +171 -0
- package/dist/canvas/createCanvasDisplacement.d.ts +32 -0
- package/dist/canvas/createCanvasDisplacement.d.ts.map +1 -0
- package/dist/canvas/createCanvasDisplacement.js +170 -0
- package/dist/canvas/createCanvasDocking.svelte.d.ts +56 -0
- package/dist/canvas/createCanvasDocking.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasDocking.svelte.js +227 -0
- package/dist/canvas/createCanvasExplosion.svelte.d.ts +31 -0
- package/dist/canvas/createCanvasExplosion.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasExplosion.svelte.js +346 -0
- package/dist/canvas/createCanvasGraph.svelte.d.ts +62 -0
- package/dist/canvas/createCanvasGraph.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasGraph.svelte.js +223 -0
- package/dist/canvas/createCanvasInteractions.svelte.d.ts +28 -0
- package/dist/canvas/createCanvasInteractions.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasInteractions.svelte.js +95 -0
- package/dist/canvas/createCanvasLayout.d.ts +22 -0
- package/dist/canvas/createCanvasLayout.d.ts.map +1 -0
- package/dist/canvas/createCanvasLayout.js +76 -0
- package/dist/canvas/createCanvasMultiDrag.svelte.d.ts +61 -0
- package/dist/canvas/createCanvasMultiDrag.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasMultiDrag.svelte.js +105 -0
- package/dist/canvas/createCanvasNodeSync.svelte.d.ts +58 -0
- package/dist/canvas/createCanvasNodeSync.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasNodeSync.svelte.js +82 -0
- package/dist/canvas/createCanvasSelection.svelte.d.ts +26 -0
- package/dist/canvas/createCanvasSelection.svelte.d.ts.map +1 -0
- package/dist/canvas/createCanvasSelection.svelte.js +26 -0
- package/dist/canvas/createCanvasShortcuts.d.ts +9 -0
- package/dist/canvas/createCanvasShortcuts.d.ts.map +1 -0
- package/dist/canvas/createCanvasShortcuts.js +97 -0
- package/dist/canvas/createCanvasTrajectory.d.ts +31 -0
- package/dist/canvas/createCanvasTrajectory.d.ts.map +1 -0
- package/dist/canvas/createCanvasTrajectory.js +141 -0
- package/dist/canvas/createStreamingCanvas.svelte.d.ts +19 -0
- package/dist/canvas/createStreamingCanvas.svelte.d.ts.map +1 -0
- package/dist/canvas/createStreamingCanvas.svelte.js +32 -0
- package/dist/canvas/index.d.ts +18 -688
- package/dist/canvas/index.d.ts.map +1 -0
- package/dist/canvas/index.js +34 -1839
- package/dist/canvas/types.d.ts +183 -0
- package/dist/canvas/types.d.ts.map +1 -0
- package/dist/canvas/types.js +1 -0
- package/dist/createNavigationGuard.svelte.d.ts +24 -0
- package/dist/createNavigationGuard.svelte.d.ts.map +1 -0
- package/dist/createNavigationGuard.svelte.js +65 -0
- package/dist/editor.svelte.d.ts +23 -0
- package/dist/editor.svelte.d.ts.map +1 -0
- package/dist/editor.svelte.js +41 -0
- package/dist/history/createHistoryShortcuts.d.ts +24 -0
- package/dist/history/createHistoryShortcuts.d.ts.map +1 -0
- package/dist/history/createHistoryShortcuts.js +57 -0
- package/dist/history/history.svelte.d.ts +18 -0
- package/dist/history/history.svelte.d.ts.map +1 -0
- package/dist/history/history.svelte.js +43 -0
- package/dist/history/index.d.ts +3 -0
- package/dist/history/index.d.ts.map +1 -0
- package/dist/history/index.js +2 -0
- package/{src → dist}/image-editor/ImageEditor.svelte +1 -1
- package/dist/image-editor/ImageEditor.svelte.d.ts +17 -0
- package/dist/image-editor/ImageEditor.svelte.d.ts.map +1 -0
- package/dist/image-editor/imageEditorState.svelte.d.ts +50 -0
- package/dist/image-editor/imageEditorState.svelte.d.ts.map +1 -0
- package/dist/image-editor/imageEditorState.svelte.js +132 -0
- package/dist/image-editor/index.d.ts +6 -16
- package/dist/image-editor/index.d.ts.map +1 -0
- package/dist/image-editor/index.js +2 -9
- package/dist/index.d.ts +20 -249
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -1119
- package/dist/navigationGuard.d.ts +21 -0
- package/dist/navigationGuard.d.ts.map +1 -0
- package/dist/navigationGuard.js +59 -0
- package/{src → dist}/spreadsheet/FormulaBar.svelte +1 -1
- package/dist/spreadsheet/FormulaBar.svelte.d.ts +17 -0
- package/dist/spreadsheet/FormulaBar.svelte.d.ts.map +1 -0
- package/{src → dist}/spreadsheet/SpreadsheetEditor.svelte +1 -1
- package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts +22 -0
- package/dist/spreadsheet/SpreadsheetEditor.svelte.d.ts.map +1 -0
- package/dist/spreadsheet/index.d.ts +9 -0
- package/dist/spreadsheet/index.d.ts.map +1 -0
- package/{src/spreadsheet/index.ts → dist/spreadsheet/index.js} +1 -1
- package/dist/spreadsheet/spreadsheet.svelte.d.ts +33 -0
- package/dist/spreadsheet/spreadsheet.svelte.d.ts.map +1 -0
- package/dist/spreadsheet/spreadsheet.svelte.js +160 -0
- package/package.json +14 -16
- package/dist/canvas/index.js.map +0 -1
- package/dist/chunk-HEOI4UNF.js +0 -1191
- package/dist/chunk-HEOI4UNF.js.map +0 -1
- package/dist/image-editor/index.js.map +0 -1
- package/dist/index.css +0 -50
- package/dist/index.css.map +0 -1
- package/dist/index.js.map +0 -1
- package/src/canvas/__tests__/canvas-clipboard.test.ts +0 -154
- package/src/canvas/__tests__/canvas-docking.test.ts +0 -288
- package/src/canvas/__tests__/canvas-explosion.test.ts +0 -634
- package/src/canvas/__tests__/canvas-graph.test.ts +0 -159
- package/src/canvas/__tests__/canvas-interactions.test.ts +0 -86
- package/src/canvas/__tests__/canvas-layout.test.ts +0 -75
- package/src/canvas/__tests__/canvas-multi-drag.test.ts +0 -112
- package/src/canvas/__tests__/canvas-node-sync.svelte.test.ts +0 -104
- package/src/canvas/__tests__/canvas-shortcuts.test.ts +0 -59
- package/src/canvas/createCanvasClipboard.svelte.ts +0 -219
- package/src/canvas/createCanvasDisplacement.ts +0 -253
- package/src/canvas/createCanvasDocking.svelte.ts +0 -355
- package/src/canvas/createCanvasExplosion.svelte.ts +0 -457
- package/src/canvas/createCanvasGraph.svelte.ts +0 -330
- package/src/canvas/createCanvasInteractions.svelte.ts +0 -112
- package/src/canvas/createCanvasLayout.ts +0 -129
- package/src/canvas/createCanvasMultiDrag.svelte.ts +0 -175
- package/src/canvas/createCanvasNodeSync.svelte.ts +0 -150
- package/src/canvas/createCanvasSelection.svelte.ts +0 -51
- package/src/canvas/createCanvasShortcuts.ts +0 -99
- package/src/canvas/createCanvasTrajectory.ts +0 -207
- package/src/canvas/createStreamingCanvas.svelte.ts +0 -56
- package/src/canvas/index.d.ts +0 -688
- package/src/canvas/index.ts +0 -126
- package/src/canvas/types.ts +0 -223
- package/src/createNavigationGuard.svelte.ts +0 -97
- package/src/editor.svelte.ts +0 -65
- package/src/history/createHistoryShortcuts.ts +0 -95
- package/src/history/history.svelte.ts +0 -68
- package/src/history/index.ts +0 -2
- package/src/image-editor/imageEditorState.svelte.ts +0 -151
- package/src/image-editor/index.d.ts +0 -16
- package/src/image-editor/index.ts +0 -2
- package/src/index.d.ts +0 -249
- package/src/index.ts +0 -89
- package/src/navigationGuard.ts +0 -82
- package/src/spreadsheet/spreadsheet.svelte.ts +0 -176
- package/src/svelte.d.ts +0 -5
- /package/{src → dist}/BubbleMenu.svelte +0 -0
- /package/{src → dist}/TemplateRenderer.svelte +0 -0
- /package/{src → dist}/canvas/AgentPresenceLayer.svelte +0 -0
- /package/{src → dist}/canvas/FloatingHorizontalScrollbar.svelte +0 -0
- /package/{src → dist}/canvas/README.md +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Position } from '@xyflow/svelte';
|
|
2
|
+
import type { CanvasNode, CanvasEdge } from './types.js';
|
|
3
|
+
export interface HandleConfig {
|
|
4
|
+
id?: string | null;
|
|
5
|
+
type: 'source' | 'target';
|
|
6
|
+
position: Position;
|
|
7
|
+
x?: number;
|
|
8
|
+
y?: number;
|
|
9
|
+
width?: number;
|
|
10
|
+
height?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface NodeMeasurement {
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Preserves cached .measured dimensions from existing nodes to newly constructed nodes.
|
|
18
|
+
* Resolves measurements without subscribing to reactive updates on the existing collection.
|
|
19
|
+
*/
|
|
20
|
+
export declare function preserveNodeMeasurements<TNode extends CanvasNode = CanvasNode>(newNodes: TNode[], existingNodes: TNode[] | Map<string, TNode>): TNode[];
|
|
21
|
+
/**
|
|
22
|
+
* Pre-populates handle geometry on a node to prevent @xyflow/system's getNodesInside
|
|
23
|
+
* from evaluating `forceInitialRender = !node.internals.handleBounds` and triggering
|
|
24
|
+
* a false full-canvas selection on the first frame of marquee drag-selection.
|
|
25
|
+
*/
|
|
26
|
+
export declare function normalizeNodeHandles<TNode extends CanvasNode = CanvasNode>(node: TNode, handles?: HandleConfig[]): TNode;
|
|
27
|
+
export interface CreateCanvasNodeSyncOptions<TItem, TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge> {
|
|
28
|
+
/**
|
|
29
|
+
* Reactive getter returning raw domain items.
|
|
30
|
+
*/
|
|
31
|
+
items: () => TItem[];
|
|
32
|
+
/**
|
|
33
|
+
* Factory function converting a domain item into a CanvasNode.
|
|
34
|
+
*/
|
|
35
|
+
toNode: (item: TItem, index: number, context: {
|
|
36
|
+
existingNode?: TNode;
|
|
37
|
+
prevNodesMap: Map<string, TNode>;
|
|
38
|
+
}) => TNode;
|
|
39
|
+
/**
|
|
40
|
+
* Optional factory function converting domain items and generated nodes into CanvasEdges.
|
|
41
|
+
*/
|
|
42
|
+
toEdges?: (items: TItem[], nodes: TNode[]) => TEdge[];
|
|
43
|
+
/**
|
|
44
|
+
* Optional default handle configuration provider for connectable nodes.
|
|
45
|
+
*/
|
|
46
|
+
defaultHandles?: (node: TNode) => HandleConfig[] | undefined;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Headless Svelte 5 rune that synchronizes reactive domain items with SvelteFlow nodes/edges,
|
|
50
|
+
* automatically untracking previous node reads, caching .measured dimensions, and normalizing
|
|
51
|
+
* handle bounds to prevent Svelte 5 effect_update_depth_exceeded and marquee drag flashes.
|
|
52
|
+
*/
|
|
53
|
+
export declare function createCanvasNodeSync<TItem, TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(options: CreateCanvasNodeSyncOptions<TItem, TNode, TEdge>): {
|
|
54
|
+
nodes: TNode[];
|
|
55
|
+
edges: TEdge[];
|
|
56
|
+
updateNodeMeasurements(id: string, width: number, height: number): void;
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=createCanvasNodeSync.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createCanvasNodeSync.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasNodeSync.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC5B,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAC7E,QAAQ,EAAE,KAAK,EAAE,EACjB,aAAa,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GACzC,KAAK,EAAE,CAaT;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EACzE,IAAI,EAAE,KAAK,EACX,OAAO,GAAE,YAAY,EAAO,GAC1B,KAAK,CAGP;AAED,MAAM,WAAW,2BAA2B,CAC3C,KAAK,EACL,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,KAAK,SAAS,UAAU,GAAG,UAAU;IAErC;;OAEG;IACH,KAAK,EAAE,MAAM,KAAK,EAAE,CAAC;IACrB;;OAEG;IACH,MAAM,EAAE,CACP,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;QAAE,YAAY,CAAC,EAAE,KAAK,CAAC;QAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;KAAE,KAC/D,KAAK,CAAC;IACX;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,CAAC;IACtD;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,YAAY,EAAE,GAAG,SAAS,CAAC;CAC7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CACnC,KAAK,EACL,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,KAAK,SAAS,UAAU,GAAG,UAAU,EACpC,OAAO,EAAE,2BAA2B,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;WA2CxC,KAAK,EAAE;WAMP,KAAK,EAAE;+BAGG,MAAM,SAAS,MAAM,UAAU,MAAM;EAOjE"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { untrack } from 'svelte';
|
|
2
|
+
/**
|
|
3
|
+
* Preserves cached .measured dimensions from existing nodes to newly constructed nodes.
|
|
4
|
+
* Resolves measurements without subscribing to reactive updates on the existing collection.
|
|
5
|
+
*/
|
|
6
|
+
export function preserveNodeMeasurements(newNodes, existingNodes) {
|
|
7
|
+
const map = existingNodes instanceof Map
|
|
8
|
+
? existingNodes
|
|
9
|
+
: new Map(existingNodes.map((n) => [n.id, n]));
|
|
10
|
+
for (const node of newNodes) {
|
|
11
|
+
const prev = map.get(node.id);
|
|
12
|
+
if (prev && prev.measured) {
|
|
13
|
+
node.measured = { ...prev.measured };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return newNodes;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Pre-populates handle geometry on a node to prevent @xyflow/system's getNodesInside
|
|
20
|
+
* from evaluating `forceInitialRender = !node.internals.handleBounds` and triggering
|
|
21
|
+
* a false full-canvas selection on the first frame of marquee drag-selection.
|
|
22
|
+
*/
|
|
23
|
+
export function normalizeNodeHandles(node, handles = []) {
|
|
24
|
+
node.handles = handles;
|
|
25
|
+
return node;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Headless Svelte 5 rune that synchronizes reactive domain items with SvelteFlow nodes/edges,
|
|
29
|
+
* automatically untracking previous node reads, caching .measured dimensions, and normalizing
|
|
30
|
+
* handle bounds to prevent Svelte 5 effect_update_depth_exceeded and marquee drag flashes.
|
|
31
|
+
*/
|
|
32
|
+
export function createCanvasNodeSync(options) {
|
|
33
|
+
let nodes = $state([]);
|
|
34
|
+
let edges = $state([]);
|
|
35
|
+
$effect.pre(() => {
|
|
36
|
+
const rawItems = options.items();
|
|
37
|
+
// Untrack the read of current nodes to avoid recursive effect loops
|
|
38
|
+
const existingNodesMap = untrack(() => new Map(nodes.map((n) => [n.id, n])));
|
|
39
|
+
const newNodes = rawItems.map((item, index) => {
|
|
40
|
+
const existing = existingNodesMap.get(item?.id);
|
|
41
|
+
const node = options.toNode(item, index, {
|
|
42
|
+
existingNode: existing,
|
|
43
|
+
prevNodesMap: existingNodesMap
|
|
44
|
+
});
|
|
45
|
+
// Automatically preserve measured dimensions if available
|
|
46
|
+
if (existing && existing.measured && !node.measured) {
|
|
47
|
+
node.measured = { ...existing.measured };
|
|
48
|
+
}
|
|
49
|
+
// Pre-populate handles if provided
|
|
50
|
+
if (options.defaultHandles && !node.handles) {
|
|
51
|
+
const handles = options.defaultHandles(node);
|
|
52
|
+
if (handles) {
|
|
53
|
+
node.handles = handles;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return node;
|
|
57
|
+
});
|
|
58
|
+
const newEdges = options.toEdges ? options.toEdges(rawItems, newNodes) : [];
|
|
59
|
+
nodes = newNodes;
|
|
60
|
+
edges = newEdges;
|
|
61
|
+
});
|
|
62
|
+
return {
|
|
63
|
+
get nodes() {
|
|
64
|
+
return nodes;
|
|
65
|
+
},
|
|
66
|
+
set nodes(value) {
|
|
67
|
+
nodes = value;
|
|
68
|
+
},
|
|
69
|
+
get edges() {
|
|
70
|
+
return edges;
|
|
71
|
+
},
|
|
72
|
+
set edges(value) {
|
|
73
|
+
edges = value;
|
|
74
|
+
},
|
|
75
|
+
updateNodeMeasurements(id, width, height) {
|
|
76
|
+
const node = nodes.find((n) => n.id === id);
|
|
77
|
+
if (node) {
|
|
78
|
+
node.measured = { width, height };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CanvasInteractionPresetConfig } from './types.js';
|
|
2
|
+
export interface CanvasSelectionOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Whether spacebar panning is currently active (suspends marquee selection).
|
|
5
|
+
*/
|
|
6
|
+
isSpacebarPanning?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Selection mode: 'partial' (default) selects nodes intersected by selection box,
|
|
9
|
+
* 'full' requires nodes to be fully enclosed.
|
|
10
|
+
*/
|
|
11
|
+
selectionMode?: 'partial' | 'full';
|
|
12
|
+
/**
|
|
13
|
+
* Additional keys that trigger multi-selection (default: ['Shift', 'Meta']).
|
|
14
|
+
*/
|
|
15
|
+
multiSelectionKey?: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Generates an interaction preset configured for left-click marquee drag-selection
|
|
19
|
+
* while preserving middle-mouse and spacebar panning.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getMarqueeSelectionPreset(options?: CanvasSelectionOptions): CanvasInteractionPresetConfig;
|
|
22
|
+
/**
|
|
23
|
+
* Keyboard listener helper to deselect nodes on Escape.
|
|
24
|
+
*/
|
|
25
|
+
export declare function handleDeselectOnEscape(event: KeyboardEvent, onDeselect: () => void): boolean;
|
|
26
|
+
//# sourceMappingURL=createCanvasSelection.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createCanvasSelection.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasSelection.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACnC;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACxC,OAAO,GAAE,sBAA2B,GAClC,6BAA6B,CAY/B;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,aAAa,EACpB,UAAU,EAAE,MAAM,IAAI,GACpB,OAAO,CAMT"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates an interaction preset configured for left-click marquee drag-selection
|
|
3
|
+
* while preserving middle-mouse and spacebar panning.
|
|
4
|
+
*/
|
|
5
|
+
export function getMarqueeSelectionPreset(options = {}) {
|
|
6
|
+
const isSpacebarPanning = options.isSpacebarPanning ?? false;
|
|
7
|
+
return {
|
|
8
|
+
snapGrid: [25, 25],
|
|
9
|
+
panOnDrag: isSpacebarPanning ? [0, 1, 2] : [1, 2],
|
|
10
|
+
panOnScroll: false,
|
|
11
|
+
selectionOnDrag: !isSpacebarPanning,
|
|
12
|
+
colorMode: 'system',
|
|
13
|
+
multiSelectionKey: options.multiSelectionKey ?? ['Shift', 'Meta'],
|
|
14
|
+
selectionMode: (options.selectionMode ?? 'partial')
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Keyboard listener helper to deselect nodes on Escape.
|
|
19
|
+
*/
|
|
20
|
+
export function handleDeselectOnEscape(event, onDeselect) {
|
|
21
|
+
if (event.key === 'Escape' || event.code === 'Escape') {
|
|
22
|
+
onDeselect();
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CanvasNode, CanvasShortcutsOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Attaches keyboard shortcut handlers for canvas interaction.
|
|
4
|
+
* Automatically ignores shortcuts when the user is typing into text inputs, textareas, or rich editors.
|
|
5
|
+
*
|
|
6
|
+
* @returns A cleanup function to remove event listeners.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createCanvasShortcuts<TNode extends CanvasNode = CanvasNode>(options: CanvasShortcutsOptions<TNode>): () => void;
|
|
9
|
+
//# sourceMappingURL=createCanvasShortcuts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createCanvasShortcuts.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasShortcuts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAC1E,OAAO,EAAE,sBAAsB,CAAC,KAAK,CAAC,GACpC,MAAM,IAAI,CAuFZ"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { isEventFromTextInput } from './createCanvasClipboard.svelte.js';
|
|
2
|
+
/**
|
|
3
|
+
* Attaches keyboard shortcut handlers for canvas interaction.
|
|
4
|
+
* Automatically ignores shortcuts when the user is typing into text inputs, textareas, or rich editors.
|
|
5
|
+
*
|
|
6
|
+
* @returns A cleanup function to remove event listeners.
|
|
7
|
+
*/
|
|
8
|
+
export function createCanvasShortcuts(options) {
|
|
9
|
+
const target = options.targetElement ?? (typeof window !== 'undefined' ? window : null);
|
|
10
|
+
if (!target)
|
|
11
|
+
return () => { };
|
|
12
|
+
function handleKeyDown(event) {
|
|
13
|
+
const keyboardEvent = event;
|
|
14
|
+
if (isEventFromTextInput(keyboardEvent)) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const isMod = keyboardEvent.metaKey || keyboardEvent.ctrlKey;
|
|
18
|
+
const isShift = keyboardEvent.shiftKey;
|
|
19
|
+
const key = keyboardEvent.key;
|
|
20
|
+
const selectedNodes = options.getSelectedNodes ? options.getSelectedNodes() : [];
|
|
21
|
+
if (key === 'Backspace' || key === 'Delete') {
|
|
22
|
+
if (options.onDelete && selectedNodes.length > 0) {
|
|
23
|
+
keyboardEvent.preventDefault();
|
|
24
|
+
options.onDelete(selectedNodes);
|
|
25
|
+
}
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (isMod) {
|
|
29
|
+
const lowerKey = key.toLowerCase();
|
|
30
|
+
if (lowerKey === 'c' && !isShift) {
|
|
31
|
+
if (options.onCopy) {
|
|
32
|
+
// We let the native copy event fire or call onCopy
|
|
33
|
+
options.onCopy();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (lowerKey === 'x' && !isShift) {
|
|
37
|
+
if (options.onCut) {
|
|
38
|
+
options.onCut();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else if (lowerKey === 'd' && !isShift) {
|
|
42
|
+
if (options.onDuplicate && selectedNodes.length > 0) {
|
|
43
|
+
keyboardEvent.preventDefault();
|
|
44
|
+
options.onDuplicate(selectedNodes);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else if (lowerKey === 'a' && !isShift) {
|
|
48
|
+
if (options.onSelectAll) {
|
|
49
|
+
keyboardEvent.preventDefault();
|
|
50
|
+
options.onSelectAll();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (lowerKey === 'g') {
|
|
54
|
+
if (isShift) {
|
|
55
|
+
if (options.onUngroup && selectedNodes.length > 0) {
|
|
56
|
+
keyboardEvent.preventDefault();
|
|
57
|
+
options.onUngroup(selectedNodes);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
if (options.onGroup && selectedNodes.length > 0) {
|
|
62
|
+
keyboardEvent.preventDefault();
|
|
63
|
+
options.onGroup(selectedNodes);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if (key === '=' || key === '+') {
|
|
68
|
+
if (options.onZoomIn) {
|
|
69
|
+
keyboardEvent.preventDefault();
|
|
70
|
+
options.onZoomIn();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (key === '-') {
|
|
74
|
+
if (options.onZoomOut) {
|
|
75
|
+
keyboardEvent.preventDefault();
|
|
76
|
+
options.onZoomOut();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (key === '0') {
|
|
80
|
+
if (options.onFitView) {
|
|
81
|
+
keyboardEvent.preventDefault();
|
|
82
|
+
options.onFitView();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (lowerKey === 'f') {
|
|
86
|
+
if (options.onSearch) {
|
|
87
|
+
keyboardEvent.preventDefault();
|
|
88
|
+
options.onSearch();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
target.addEventListener('keydown', handleKeyDown);
|
|
94
|
+
return () => {
|
|
95
|
+
target.removeEventListener('keydown', handleKeyDown);
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { XYPosition } from '@xyflow/svelte';
|
|
2
|
+
import type { CanvasNode, FanOutTrajectoryOptions, NodeTransition, TrajectoryFunction } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Standard linear trajectory: straight line interpolation with linear scale & opacity progression.
|
|
5
|
+
*/
|
|
6
|
+
export declare const linearTrajectory: TrajectoryFunction;
|
|
7
|
+
/**
|
|
8
|
+
* Linear position trajectory: pure position interpolation without altering scale or opacity.
|
|
9
|
+
* Used for displaced sibling nodes to ensure their visibility remains unaltered.
|
|
10
|
+
*/
|
|
11
|
+
export declare const linearPositionTrajectory: TrajectoryFunction;
|
|
12
|
+
/**
|
|
13
|
+
* Creates a fan-out trajectory where nodes arc outward from origin to target.
|
|
14
|
+
* Matches the curved distribution shown in multi-node branching diagrams.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createFanOutTrajectory(options?: FanOutTrajectoryOptions): TrajectoryFunction;
|
|
17
|
+
/**
|
|
18
|
+
* Creates a custom quadratic Bezier trajectory with a specified or dynamically calculated control point.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createBezierTrajectory(getControlPoint: (origin: XYPosition, target: XYPosition) => XYPosition): TrajectoryFunction;
|
|
21
|
+
/**
|
|
22
|
+
* Coordinates and animates multiple node transitions simultaneously with zero per-frame array allocations.
|
|
23
|
+
* Directly mutates node positions and data (scale, opacity) in-place during the animation loop.
|
|
24
|
+
*/
|
|
25
|
+
export declare function runMultiNodeTransition<TNode extends CanvasNode = CanvasNode>(transitions: NodeTransition<TNode>[], options?: {
|
|
26
|
+
defaultDuration?: number;
|
|
27
|
+
defaultEasing?: (t: number) => number;
|
|
28
|
+
onUpdate?: () => void;
|
|
29
|
+
onComplete?: () => void;
|
|
30
|
+
}): () => void;
|
|
31
|
+
//# sourceMappingURL=createCanvasTrajectory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createCanvasTrajectory.d.ts","sourceRoot":"","sources":["../../src/canvas/createCanvasTrajectory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EACX,UAAU,EACV,uBAAuB,EACvB,cAAc,EACd,kBAAkB,EAElB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAa9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,kBAWtC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,kBAAkB,CA0ChG;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACrC,eAAe,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,KAAK,UAAU,GACrE,kBAAkB,CAepB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,SAAS,UAAU,GAAG,UAAU,EAC3E,WAAW,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,EACpC,OAAO,GAAE;IACR,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACnB,GACJ,MAAM,IAAI,CA+EZ"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { cubicOut } from 'svelte/easing';
|
|
2
|
+
/**
|
|
3
|
+
* Standard linear trajectory: straight line interpolation with linear scale & opacity progression.
|
|
4
|
+
*/
|
|
5
|
+
export const linearTrajectory = (origin, target, progress) => {
|
|
6
|
+
return {
|
|
7
|
+
position: {
|
|
8
|
+
x: origin.x + (target.x - origin.x) * progress,
|
|
9
|
+
y: origin.y + (target.y - origin.y) * progress
|
|
10
|
+
},
|
|
11
|
+
scale: progress,
|
|
12
|
+
opacity: Math.min(1, progress * 1.5)
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Linear position trajectory: pure position interpolation without altering scale or opacity.
|
|
17
|
+
* Used for displaced sibling nodes to ensure their visibility remains unaltered.
|
|
18
|
+
*/
|
|
19
|
+
export const linearPositionTrajectory = (origin, target, progress) => {
|
|
20
|
+
return {
|
|
21
|
+
position: {
|
|
22
|
+
x: origin.x + (target.x - origin.x) * progress,
|
|
23
|
+
y: origin.y + (target.y - origin.y) * progress
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Creates a fan-out trajectory where nodes arc outward from origin to target.
|
|
29
|
+
* Matches the curved distribution shown in multi-node branching diagrams.
|
|
30
|
+
*/
|
|
31
|
+
export function createFanOutTrajectory(options = {}) {
|
|
32
|
+
const { curvature = 0.4, startScale = 0, endScale = 1, startOpacity = 0, endOpacity = 1 } = options;
|
|
33
|
+
return (origin, target, progress, index, total) => {
|
|
34
|
+
const dx = target.x - origin.x;
|
|
35
|
+
const dy = target.y - origin.y;
|
|
36
|
+
// Normalized index from -1 (top) to +1 (bottom)
|
|
37
|
+
const normIndex = total > 1 ? (index - (total - 1) / 2) / ((total - 1) / 2) : 0;
|
|
38
|
+
// Perpendicular control point offset to create smooth fan arc
|
|
39
|
+
const midX = origin.x + dx * 0.4;
|
|
40
|
+
const midY = origin.y + dy * 0.1 - normIndex * Math.abs(dx) * 0.15 * curvature;
|
|
41
|
+
// Quadratic Bezier interpolation: B(t) = (1-t)^2 * P0 + 2(1-t)t * P1 + t^2 * P2
|
|
42
|
+
const t = progress;
|
|
43
|
+
const oneMinusT = 1 - t;
|
|
44
|
+
const x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * midX + t * t * target.x;
|
|
45
|
+
const y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * midY + t * t * target.y;
|
|
46
|
+
const scale = startScale + (endScale - startScale) * progress;
|
|
47
|
+
const opacity = startOpacity + (endOpacity - startOpacity) * progress;
|
|
48
|
+
return {
|
|
49
|
+
position: { x, y },
|
|
50
|
+
scale,
|
|
51
|
+
opacity
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Creates a custom quadratic Bezier trajectory with a specified or dynamically calculated control point.
|
|
57
|
+
*/
|
|
58
|
+
export function createBezierTrajectory(getControlPoint) {
|
|
59
|
+
return (origin, target, progress) => {
|
|
60
|
+
const cp = getControlPoint(origin, target);
|
|
61
|
+
const t = progress;
|
|
62
|
+
const oneMinusT = 1 - t;
|
|
63
|
+
const x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * cp.x + t * t * target.x;
|
|
64
|
+
const y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * cp.y + t * t * target.y;
|
|
65
|
+
return {
|
|
66
|
+
position: { x, y },
|
|
67
|
+
scale: progress,
|
|
68
|
+
opacity: progress
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Coordinates and animates multiple node transitions simultaneously with zero per-frame array allocations.
|
|
74
|
+
* Directly mutates node positions and data (scale, opacity) in-place during the animation loop.
|
|
75
|
+
*/
|
|
76
|
+
export function runMultiNodeTransition(transitions, options = {}) {
|
|
77
|
+
if (transitions.length === 0) {
|
|
78
|
+
options.onComplete?.();
|
|
79
|
+
return () => { };
|
|
80
|
+
}
|
|
81
|
+
const { defaultDuration = 400, defaultEasing = cubicOut, onUpdate, onComplete } = options;
|
|
82
|
+
let isCancelled = false;
|
|
83
|
+
const startTime = Date.now();
|
|
84
|
+
const items = transitions.map((tr, i) => ({
|
|
85
|
+
...tr,
|
|
86
|
+
index: tr.index ?? i,
|
|
87
|
+
total: tr.total ?? transitions.length,
|
|
88
|
+
duration: tr.duration ?? defaultDuration,
|
|
89
|
+
easing: tr.easing ?? defaultEasing,
|
|
90
|
+
delay: tr.delay ?? 0,
|
|
91
|
+
trajectory: tr.trajectory ?? linearTrajectory
|
|
92
|
+
}));
|
|
93
|
+
function frame() {
|
|
94
|
+
if (isCancelled)
|
|
95
|
+
return;
|
|
96
|
+
const now = Date.now();
|
|
97
|
+
let allCompleted = true;
|
|
98
|
+
for (let i = 0; i < items.length; i++) {
|
|
99
|
+
const item = items[i];
|
|
100
|
+
const elapsed = now - (startTime + item.delay);
|
|
101
|
+
if (elapsed < 0) {
|
|
102
|
+
allCompleted = false;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const rawProgress = item.duration <= 0 ? 1 : Math.min(elapsed / item.duration, 1);
|
|
106
|
+
const progress = item.duration <= 0 ? 1 : item.easing(rawProgress);
|
|
107
|
+
const point = item.trajectory(item.from, item.to, progress, item.index, item.total);
|
|
108
|
+
// Direct in-place mutation avoids array reconstruction during RAF
|
|
109
|
+
item.node.position = { ...point.position };
|
|
110
|
+
if (point.scale !== undefined || point.opacity !== undefined) {
|
|
111
|
+
if (!item.node.data) {
|
|
112
|
+
item.node.data = {};
|
|
113
|
+
}
|
|
114
|
+
if (point.scale !== undefined) {
|
|
115
|
+
item.node.data.scale = point.scale;
|
|
116
|
+
}
|
|
117
|
+
if (point.opacity !== undefined) {
|
|
118
|
+
item.node.data.opacity = point.opacity;
|
|
119
|
+
const currentStyle = (item.node.style || '').replace(/opacity:\s*[^;]+;?/g, '').trim();
|
|
120
|
+
item.node.style = `${currentStyle ? currentStyle + '; ' : ''}opacity: ${point.opacity};`;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (rawProgress < 1) {
|
|
124
|
+
allCompleted = false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
onUpdate?.();
|
|
128
|
+
if (!allCompleted) {
|
|
129
|
+
if (typeof requestAnimationFrame !== 'undefined') {
|
|
130
|
+
requestAnimationFrame(frame);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
onComplete?.();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
frame();
|
|
138
|
+
return () => {
|
|
139
|
+
isCancelled = true;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type CanvasEdge, type CanvasNode, type IncrementalLayoutOptions, type XYPosition } from '@pixerate/editor/canvas';
|
|
2
|
+
export interface CreateStreamingCanvasOptions<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge> {
|
|
3
|
+
throttleMs?: number;
|
|
4
|
+
glideDurationMs?: number;
|
|
5
|
+
connectedOnly?: boolean;
|
|
6
|
+
clock?: any;
|
|
7
|
+
layoutOptions?: IncrementalLayoutOptions;
|
|
8
|
+
onPositionsChange?: (positions: Map<string, XYPosition>) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Svelte 5 rune managing throttled graph streaming and fluid node glide animations.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createStreamingCanvas<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(options?: CreateStreamingCanvasOptions<TNode, TEdge>): {
|
|
14
|
+
readonly positions: Map<string, XYPosition>;
|
|
15
|
+
pushStreamUpdate(nodes: TNode[], edges: TEdge[], currentPositions: Map<string, XYPosition>): void;
|
|
16
|
+
flush(nodes: TNode[], edges: TEdge[], currentPositions: Map<string, XYPosition>): void;
|
|
17
|
+
destroy(): void;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=createStreamingCanvas.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createStreamingCanvas.svelte.d.ts","sourceRoot":"","sources":["../../src/canvas/createStreamingCanvas.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,wBAAwB,EAC7B,KAAK,UAAU,EACf,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,4BAA4B,CAC5C,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,KAAK,SAAS,UAAU,GAAG,UAAU;IAErC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,IAAI,CAAC;CACjE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,SAAS,UAAU,GAAG,UAAU,EACrC,KAAK,SAAS,UAAU,GAAG,UAAU,EACpC,OAAO,GAAE,4BAA4B,CAAC,KAAK,EAAE,KAAK,CAAM;;4BAmBhC,KAAK,EAAE,SAAS,KAAK,EAAE,oBAAoB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;iBAG7E,KAAK,EAAE,SAAS,KAAK,EAAE,oBAAoB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;;EAOhF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { StreamingLayoutManager } from '@pixerate/editor/canvas';
|
|
2
|
+
/**
|
|
3
|
+
* Svelte 5 rune managing throttled graph streaming and fluid node glide animations.
|
|
4
|
+
*/
|
|
5
|
+
export function createStreamingCanvas(options = {}) {
|
|
6
|
+
let positions = $state(new Map());
|
|
7
|
+
const manager = new StreamingLayoutManager({
|
|
8
|
+
throttleMs: options.throttleMs,
|
|
9
|
+
glideDurationMs: options.glideDurationMs,
|
|
10
|
+
connectedOnly: options.connectedOnly,
|
|
11
|
+
clock: options.clock,
|
|
12
|
+
layoutOptions: options.layoutOptions,
|
|
13
|
+
onLayoutUpdated: (updated) => {
|
|
14
|
+
positions = updated;
|
|
15
|
+
options.onPositionsChange?.(updated);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
get positions() {
|
|
20
|
+
return positions;
|
|
21
|
+
},
|
|
22
|
+
pushStreamUpdate(nodes, edges, currentPositions) {
|
|
23
|
+
manager.pushStreamUpdate(nodes, edges, currentPositions);
|
|
24
|
+
},
|
|
25
|
+
flush(nodes, edges, currentPositions) {
|
|
26
|
+
manager.flush(nodes, edges, currentPositions);
|
|
27
|
+
},
|
|
28
|
+
destroy() {
|
|
29
|
+
manager.destroy();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|