Skip to content

Commit e79e3bc

Browse files
committed
improved connection dragging
1 parent 05ad653 commit e79e3bc

File tree

18 files changed

+584
-325
lines changed

18 files changed

+584
-325
lines changed

apps/vps-web/src/styles.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ rect-node:has(.hover) > .shape-circle,
129129
.connection-controller.thumb.dragging div {
130130
@apply !bg-white;
131131
}
132+
.connection-controller.thumb.hovering div {
133+
@apply !bg-white;
134+
}
132135

133136
.rect-thumb-node:not(.dropping):hover > .rect-thumb-tooltip {
134137
@apply bg-white text-black block;

examples-test-flows/container.json

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
{
2+
"schemaType": "flow",
3+
"schemaVersion": "0.0.1",
4+
"id": "1234",
5+
"flows": {
6+
"flow": {
7+
"flowType": "flow",
8+
"nodes": [
9+
{
10+
"id": "891b56d1-2fa5-428a-a2d8-a9d17f8d6d0f",
11+
"x": 379.0949864510301,
12+
"y": -75.05466727079755,
13+
"width": 633,
14+
"height": 400,
15+
"nodeType": "Shape",
16+
"elements": [
17+
{
18+
"id": "891b56d1-2fa5-428a-a2d8-a9d17f8d6d0f_input",
19+
"x": 0,
20+
"y": 0,
21+
"width": 1,
22+
"height": 1,
23+
"nodeType": "Shape",
24+
"nodeInfo": {}
25+
},
26+
{
27+
"id": "891b56d1-2fa5-428a-a2d8-a9d17f8d6d0f_output",
28+
"x": 633,
29+
"y": 0,
30+
"width": 1,
31+
"height": 1,
32+
"nodeType": "Shape",
33+
"nodeInfo": {}
34+
},
35+
{
36+
"id": "018f77ce-5c3b-46d3-a127-dcf2a53d594b",
37+
"x": 122.7485549656526,
38+
"y": 151.4699003913202,
39+
"width": 100,
40+
"height": 50,
41+
"nodeType": "Shape",
42+
"nodeInfo": {
43+
"type": "state",
44+
"formValues": {
45+
"caption": "Off"
46+
}
47+
}
48+
},
49+
{
50+
"id": "238d3f63-d97f-445b-a3b3-10d006c92dff",
51+
"x": 250.41487495830825,
52+
"y": 33.262925487642654,
53+
"width": 99.99993896484375,
54+
"height": 50.000003814697266,
55+
"nodeType": "Shape",
56+
"nodeInfo": {
57+
"type": "state-transition",
58+
"formValues": {
59+
"caption": "toggle"
60+
}
61+
}
62+
},
63+
{
64+
"id": "bcb38eb0-06e0-4f8a-af18-1e590b429525",
65+
"x": 172.7485549656526,
66+
"y": 176.4699003913202,
67+
"endX": 300.4148444407301,
68+
"endY": 58.26292739499129,
69+
"startNodeId": "018f77ce-5c3b-46d3-a127-dcf2a53d594b",
70+
"endNodeId": "238d3f63-d97f-445b-a3b3-10d006c92dff",
71+
"startThumbName": "state",
72+
"endThumbName": "state",
73+
"lineType": "BezierQuadratic",
74+
"nodeType": "Connection",
75+
"layer": 1,
76+
"nodeInfo": {}
77+
}
78+
],
79+
"nodeInfo": {
80+
"type": "state-machine",
81+
"taskType": "state-machine",
82+
"formValues": {
83+
"caption": "State"
84+
}
85+
}
86+
}
87+
]
88+
}
89+
},
90+
"compositions": {}
91+
}

libs/visual-programming-system/src/canvas-app/base-flow.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,4 +234,9 @@ export interface IBaseFlow<T extends BaseNodeInfo> {
234234
getDebugInfoHandler: () =>
235235
| ((debugInfo: Record<string, string | number | boolean>) => void)
236236
| undefined;
237+
238+
getPointerPositionInLocalSpace: (event: MouseEvent) => {
239+
x: number;
240+
y: number;
241+
};
237242
}

libs/visual-programming-system/src/canvas-app/composition-runtime-flow-context.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,4 +590,11 @@ export class CompositionRuntimeFlowContext<T extends BaseNodeInfo>
590590
getDebugInfoHandler = () => {
591591
return undefined;
592592
};
593+
594+
getPointerPositionInLocalSpace = (_event: MouseEvent) => {
595+
return {
596+
x: 0,
597+
y: 0,
598+
};
599+
};
593600
}

libs/visual-programming-system/src/canvas-app/index.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,4 +2053,27 @@ export class FlowCanvas<T extends BaseNodeInfo>
20532053
getDebugInfoHandler = () => {
20542054
return this.onDebugInfoHandler;
20552055
};
2056+
2057+
getPointerPositionInLocalSpace = (event: MouseEvent) => {
2058+
const { rootX, rootY, eventClientX, eventClientY } = getPointerPos(
2059+
this.canvas.domElement as HTMLElement,
2060+
this.rootElement,
2061+
event
2062+
);
2063+
2064+
const { x: rootXCamera, y: rootYCamera } = transformCameraSpaceToWorldSpace(
2065+
rootX,
2066+
rootY
2067+
);
2068+
2069+
const { x: clientXCamera, y: clientYCamera } =
2070+
transformCameraSpaceToWorldSpace(eventClientX, eventClientY);
2071+
2072+
const xpos = clientXCamera - rootXCamera;
2073+
const ypos = clientYCamera - rootYCamera;
2074+
return {
2075+
x: xpos,
2076+
y: ypos,
2077+
};
2078+
};
20562079
}

libs/visual-programming-system/src/canvas-app/runtime-flow-context.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,4 +399,11 @@ export class RuntimeFlowContext<T extends BaseNodeInfo>
399399
getDebugInfoHandler = () => {
400400
return undefined;
401401
};
402+
403+
getPointerPositionInLocalSpace = (_event: MouseEvent) => {
404+
return {
405+
x: 0,
406+
y: 0,
407+
};
408+
};
402409
}

libs/visual-programming-system/src/components/arc-connection.ts

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { thumbHalfWidth, thumbHalfHeight } from '../constants/measures';
33
import { CanvasAction } from '../enums/canvas-action';
44
import { InteractionStateMachine } from '../interaction-state-machine';
55
import {
6+
ConnectionStartEndPositions,
67
ElementNodeMap,
78
IConnectionNodeComponent,
89
IElementNode,
@@ -355,7 +356,7 @@ export class LineConnection<T extends BaseNodeInfo> extends Connection<T> {
355356
// y2
356357
// );
357358

358-
const path = this.getArc(
359+
const pathInfo = this.getArc(
359360
{ x: 0, y: 0 },
360361
startOffsetX,
361362
startOffsetY,
@@ -369,7 +370,7 @@ export class LineConnection<T extends BaseNodeInfo> extends Connection<T> {
369370

370371
(this.pathHiddenElement.domElement as HTMLElement).setAttribute(
371372
'd',
372-
path
373+
pathInfo.path
373374
);
374375
}
375376
}
@@ -380,7 +381,7 @@ export class LineConnection<T extends BaseNodeInfo> extends Connection<T> {
380381
startOffsetY: number,
381382
endOffsetX: number,
382383
endOffsetY: number
383-
): void {
384+
): ConnectionStartEndPositions {
384385
const x1 = this.points.beginX - bbox.x + startOffsetX;
385386
const y1 = this.points.beginY - bbox.y + startOffsetY;
386387
const x2 = this.points.endX - bbox.x + endOffsetX;
@@ -394,7 +395,7 @@ export class LineConnection<T extends BaseNodeInfo> extends Connection<T> {
394395
// x2,
395396
// y2
396397
// );
397-
const path = this.getArc(
398+
const pathInfo = this.getArc(
398399
bbox,
399400
startOffsetX,
400401
startOffsetY,
@@ -406,11 +407,20 @@ export class LineConnection<T extends BaseNodeInfo> extends Connection<T> {
406407
y2
407408
);
408409

409-
(this.pathElement?.domElement as HTMLElement).setAttribute('d', path);
410+
(this.pathElement?.domElement as HTMLElement).setAttribute(
411+
'd',
412+
pathInfo.path
413+
);
410414
(this.pathTransparentElement?.domElement as HTMLElement).setAttribute(
411415
'd',
412-
path
416+
pathInfo.path
413417
);
418+
return {
419+
startX: pathInfo.startX,
420+
startY: pathInfo.startY,
421+
endX: pathInfo.endX,
422+
endY: pathInfo.endY,
423+
};
414424
}
415425

416426
protected getArc(
@@ -622,10 +632,16 @@ export class LineConnection<T extends BaseNodeInfo> extends Connection<T> {
622632
const endY = end.y - (targetHeight / 2) * unitY;
623633

624634
// Create path from edge to edge
625-
const controlX = (startX + endX) / 2;
626-
const controlY = (startY + endY) / 2;
635+
// const controlX = (startX + endX) / 2;
636+
// const controlY = (startY + endY) / 2;
627637
//canvas.updateControlPoint(controlX, controlY);
628-
return `M ${startX} ${startY} L ${endX} ${endY}`;
638+
return {
639+
path: `M ${startX} ${startY} L ${endX} ${endY}`,
640+
startX: startX,
641+
startY: startY,
642+
endX: endX,
643+
endY: endY,
644+
};
629645
//canvas.updateTestArcPath(d);
630646
} else {
631647
//canvas.updateControlPoint(controlX, controlY);
@@ -640,7 +656,13 @@ export class LineConnection<T extends BaseNodeInfo> extends Connection<T> {
640656
bestIntersection2.y
641657
}`;
642658
//canvas.updateTestArcPath(d);
643-
return d;
659+
return {
660+
path: d,
661+
startX: bestIntersection1.x,
662+
startY: bestIntersection1.y,
663+
endX: bestIntersection2.x,
664+
endY: bestIntersection2.y,
665+
};
644666
}
645667

646668
// const finalSweepFlag = isOverlapping ? 1 : angleDiff > 0 ? 1 : 0;
@@ -653,7 +675,7 @@ export class LineConnection<T extends BaseNodeInfo> extends Connection<T> {
653675
// : 0;
654676
} else {
655677
//canvas.updateTestArcPath('');
656-
return '';
678+
return { path: '', startX: 0, startY: 0, endX: 0, endY: 0 };
657679
}
658680

659681
//canvas.updateIntersectionPoints([...intersections1, ...intersections2]);

0 commit comments

Comments
 (0)