@ngroznykh/papirus 0.9.0 → 0.9.1
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.
|
@@ -45,6 +45,9 @@ export declare class ConnectionManager extends EventEmitter<ConnectionEvents> {
|
|
|
45
45
|
private sourceAnchorId;
|
|
46
46
|
private hoverNodeId;
|
|
47
47
|
private hoverAnchorId;
|
|
48
|
+
private hoverPoint;
|
|
49
|
+
private hoverOutlineHandle;
|
|
50
|
+
private hoverOutlineSide;
|
|
48
51
|
private hoverDisabled;
|
|
49
52
|
private reconnectPoint;
|
|
50
53
|
private previewTargetAnchorId;
|
|
@@ -112,7 +115,7 @@ export declare class ConnectionManager extends EventEmitter<ConnectionEvents> {
|
|
|
112
115
|
enableHover(): void;
|
|
113
116
|
/**
|
|
114
117
|
* Try to start connection from a hovered anchor point.
|
|
115
|
-
* When attachToOutline
|
|
118
|
+
* When attachToOutline: drag the outline handle, or Shift+drag from the node body.
|
|
116
119
|
* Otherwise: requires clicking on an anchor/port so that node drag still works.
|
|
117
120
|
*/
|
|
118
121
|
tryStartConnectionAtPoint(event: InputEvent): boolean;
|
|
@@ -191,6 +194,13 @@ export declare class ConnectionManager extends EventEmitter<ConnectionEvents> {
|
|
|
191
194
|
private renderAnchorHighlights;
|
|
192
195
|
private drawCross;
|
|
193
196
|
private getNodeAtPoint;
|
|
197
|
+
private startOutlineConnection;
|
|
198
|
+
private outlineHandleHysteresis;
|
|
199
|
+
private outlineConnectHandleFor;
|
|
200
|
+
private outlineHandleHitRadius;
|
|
201
|
+
private findOutlineConnectHandleAt;
|
|
202
|
+
private renderOutlineConnectHandle;
|
|
203
|
+
private clearOutlineHandleCursor;
|
|
194
204
|
private updateHover;
|
|
195
205
|
private getAnchorAtPoint;
|
|
196
206
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectionManager.d.ts","sourceRoot":"","sources":["../../src/core/ConnectionManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAY,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"ConnectionManager.d.ts","sourceRoot":"","sources":["../../src/core/ConnectionManager.ts"],"names":[],"mappings":"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"}
|
package/dist/papirus.js
CHANGED
|
@@ -1731,6 +1731,101 @@ function directionToVector(dir) {
|
|
|
1731
1731
|
};
|
|
1732
1732
|
}
|
|
1733
1733
|
}
|
|
1734
|
+
function clamp$1(value, min, max) {
|
|
1735
|
+
return Math.max(min, Math.min(max, value));
|
|
1736
|
+
}
|
|
1737
|
+
function dist(a, b) {
|
|
1738
|
+
return Math.hypot(a.x - b.x, a.y - b.y);
|
|
1739
|
+
}
|
|
1740
|
+
function closestPointOnRectSide(bounds, side, pointer) {
|
|
1741
|
+
const { x, y, width, height } = bounds;
|
|
1742
|
+
switch (side) {
|
|
1743
|
+
case "top": return {
|
|
1744
|
+
x: clamp$1(pointer.x, x, x + width),
|
|
1745
|
+
y
|
|
1746
|
+
};
|
|
1747
|
+
case "bottom": return {
|
|
1748
|
+
x: clamp$1(pointer.x, x, x + width),
|
|
1749
|
+
y: y + height
|
|
1750
|
+
};
|
|
1751
|
+
case "left": return {
|
|
1752
|
+
x,
|
|
1753
|
+
y: clamp$1(pointer.y, y, y + height)
|
|
1754
|
+
};
|
|
1755
|
+
case "right": return {
|
|
1756
|
+
x: x + width,
|
|
1757
|
+
y: clamp$1(pointer.y, y, y + height)
|
|
1758
|
+
};
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
function closestPointOnRectOutline(bounds, pointer) {
|
|
1762
|
+
const sides = [
|
|
1763
|
+
"top",
|
|
1764
|
+
"right",
|
|
1765
|
+
"bottom",
|
|
1766
|
+
"left"
|
|
1767
|
+
];
|
|
1768
|
+
let side = sides[0];
|
|
1769
|
+
let point = closestPointOnRectSide(bounds, side, pointer);
|
|
1770
|
+
let best = dist(pointer, point);
|
|
1771
|
+
for (let i = 1; i < sides.length; i++) {
|
|
1772
|
+
const nextSide = sides[i];
|
|
1773
|
+
const nextPoint = closestPointOnRectSide(bounds, nextSide, pointer);
|
|
1774
|
+
const nextDist = dist(pointer, nextPoint);
|
|
1775
|
+
if (nextDist < best) {
|
|
1776
|
+
side = nextSide;
|
|
1777
|
+
point = nextPoint;
|
|
1778
|
+
best = nextDist;
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
return {
|
|
1782
|
+
side,
|
|
1783
|
+
point
|
|
1784
|
+
};
|
|
1785
|
+
}
|
|
1786
|
+
function getOutlineConnectHandle(bounds, pointer, offset, prevSide, hysteresis = 8) {
|
|
1787
|
+
const closest = closestPointOnRectOutline(bounds, pointer);
|
|
1788
|
+
let side = closest.side;
|
|
1789
|
+
let attach = closest.point;
|
|
1790
|
+
if (prevSide && prevSide !== closest.side) {
|
|
1791
|
+
const stay = closestPointOnRectSide(bounds, prevSide, pointer);
|
|
1792
|
+
if (dist(pointer, stay) <= dist(pointer, closest.point) + hysteresis) {
|
|
1793
|
+
side = prevSide;
|
|
1794
|
+
attach = stay;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
if (offset === 0) return {
|
|
1798
|
+
side,
|
|
1799
|
+
attach,
|
|
1800
|
+
handle: attach
|
|
1801
|
+
};
|
|
1802
|
+
const delta = {
|
|
1803
|
+
top: {
|
|
1804
|
+
x: 0,
|
|
1805
|
+
y: -offset
|
|
1806
|
+
},
|
|
1807
|
+
right: {
|
|
1808
|
+
x: offset,
|
|
1809
|
+
y: 0
|
|
1810
|
+
},
|
|
1811
|
+
bottom: {
|
|
1812
|
+
x: 0,
|
|
1813
|
+
y: offset
|
|
1814
|
+
},
|
|
1815
|
+
left: {
|
|
1816
|
+
x: -offset,
|
|
1817
|
+
y: 0
|
|
1818
|
+
}
|
|
1819
|
+
}[side];
|
|
1820
|
+
return {
|
|
1821
|
+
side,
|
|
1822
|
+
attach,
|
|
1823
|
+
handle: {
|
|
1824
|
+
x: attach.x + delta.x,
|
|
1825
|
+
y: attach.y + delta.y
|
|
1826
|
+
}
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1734
1829
|
//#endregion
|
|
1735
1830
|
//#region src/core/ConnectionManager.ts
|
|
1736
1831
|
/**
|
|
@@ -1747,6 +1842,9 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
1747
1842
|
this.sourceAnchorId = null;
|
|
1748
1843
|
this.hoverNodeId = null;
|
|
1749
1844
|
this.hoverAnchorId = null;
|
|
1845
|
+
this.hoverPoint = null;
|
|
1846
|
+
this.hoverOutlineHandle = false;
|
|
1847
|
+
this.hoverOutlineSide = null;
|
|
1750
1848
|
this.hoverDisabled = false;
|
|
1751
1849
|
this.reconnectPoint = null;
|
|
1752
1850
|
this.previewTargetAnchorId = null;
|
|
@@ -1808,9 +1906,12 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
1808
1906
|
*/
|
|
1809
1907
|
clearPointerHover() {
|
|
1810
1908
|
if (this.hoverDisabled) return;
|
|
1811
|
-
if (this.hoverNodeId !== null || this.hoverAnchorId !== null) {
|
|
1909
|
+
if (this.hoverNodeId !== null || this.hoverAnchorId !== null || this.hoverOutlineHandle) {
|
|
1812
1910
|
this.hoverNodeId = null;
|
|
1813
1911
|
this.hoverAnchorId = null;
|
|
1912
|
+
this.hoverPoint = null;
|
|
1913
|
+
this.hoverOutlineSide = null;
|
|
1914
|
+
this.clearOutlineHandleCursor();
|
|
1814
1915
|
this.renderer.markDirty();
|
|
1815
1916
|
}
|
|
1816
1917
|
}
|
|
@@ -1837,9 +1938,12 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
1837
1938
|
*/
|
|
1838
1939
|
disableHover() {
|
|
1839
1940
|
this.hoverDisabled = true;
|
|
1840
|
-
if (this.hoverNodeId !== null || this.hoverAnchorId !== null) {
|
|
1941
|
+
if (this.hoverNodeId !== null || this.hoverAnchorId !== null || this.hoverOutlineHandle) {
|
|
1841
1942
|
this.hoverNodeId = null;
|
|
1842
1943
|
this.hoverAnchorId = null;
|
|
1944
|
+
this.hoverPoint = null;
|
|
1945
|
+
this.hoverOutlineSide = null;
|
|
1946
|
+
this.clearOutlineHandleCursor();
|
|
1843
1947
|
this.renderer.markDirty();
|
|
1844
1948
|
}
|
|
1845
1949
|
}
|
|
@@ -1851,7 +1955,7 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
1851
1955
|
}
|
|
1852
1956
|
/**
|
|
1853
1957
|
* Try to start connection from a hovered anchor point.
|
|
1854
|
-
* When attachToOutline
|
|
1958
|
+
* When attachToOutline: drag the outline handle, or Shift+drag from the node body.
|
|
1855
1959
|
* Otherwise: requires clicking on an anchor/port so that node drag still works.
|
|
1856
1960
|
*/
|
|
1857
1961
|
tryStartConnectionAtPoint(event) {
|
|
@@ -1860,18 +1964,18 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
1860
1964
|
x: event.worldX,
|
|
1861
1965
|
y: event.worldY
|
|
1862
1966
|
};
|
|
1967
|
+
if (this.attachToOutline) {
|
|
1968
|
+
const handleHit = this.findOutlineConnectHandleAt(point);
|
|
1969
|
+
if (handleHit) {
|
|
1970
|
+
this.startOutlineConnection(handleHit.node, handleHit.attach);
|
|
1971
|
+
return true;
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1863
1974
|
const node = this.getNodeAtPoint(point, false);
|
|
1864
1975
|
if (!node) return false;
|
|
1865
1976
|
if (this.attachToOutline && event.shiftKey) {
|
|
1866
|
-
const { point: outlinePoint
|
|
1867
|
-
this.
|
|
1868
|
-
this.isConnecting = true;
|
|
1869
|
-
this.sourceAnchorId = null;
|
|
1870
|
-
this.sourcePoint = outlinePoint;
|
|
1871
|
-
this.sourceOutlineParam = param;
|
|
1872
|
-
this.previewEndpoint = point;
|
|
1873
|
-
this.emit("connectionStart", node);
|
|
1874
|
-
this.renderer.markDirty();
|
|
1977
|
+
const { point: outlinePoint } = node.getClosestPointOnOutline(point);
|
|
1978
|
+
this.startOutlineConnection(node, outlinePoint);
|
|
1875
1979
|
return true;
|
|
1876
1980
|
}
|
|
1877
1981
|
const hover = this.getAnchorAtPoint(node, point);
|
|
@@ -2473,7 +2577,10 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2473
2577
|
renderHoverAnchors(ctx) {
|
|
2474
2578
|
if (this.isConnecting || this.isReconnecting) return;
|
|
2475
2579
|
this.renderEditablePolylineControls(ctx);
|
|
2476
|
-
if (this.attachToOutline)
|
|
2580
|
+
if (this.attachToOutline) {
|
|
2581
|
+
this.renderOutlineConnectHandle(ctx);
|
|
2582
|
+
return;
|
|
2583
|
+
}
|
|
2477
2584
|
if (!this.hoverNodeId) return;
|
|
2478
2585
|
const node = this.renderer.getNode(this.hoverNodeId);
|
|
2479
2586
|
if (!node) return;
|
|
@@ -2488,7 +2595,7 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2488
2595
|
ctx.beginPath();
|
|
2489
2596
|
ctx.arc(anchor.point.x, anchor.point.y, radius, 0, Math.PI * 2);
|
|
2490
2597
|
ctx.fill();
|
|
2491
|
-
if (isHovered) this.drawPlus(radius, ctx, anchor);
|
|
2598
|
+
if (isHovered) this.drawPlus(radius, ctx, anchor.point);
|
|
2492
2599
|
}
|
|
2493
2600
|
ctx.restore();
|
|
2494
2601
|
}
|
|
@@ -2639,15 +2746,15 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2639
2746
|
y
|
|
2640
2747
|
};
|
|
2641
2748
|
}
|
|
2642
|
-
drawPlus(radius, ctx,
|
|
2749
|
+
drawPlus(radius, ctx, point) {
|
|
2643
2750
|
const plusSize = radius * .5;
|
|
2644
2751
|
ctx.strokeStyle = "#ffffff";
|
|
2645
2752
|
ctx.lineWidth = 1.5;
|
|
2646
2753
|
ctx.beginPath();
|
|
2647
|
-
ctx.moveTo(
|
|
2648
|
-
ctx.lineTo(
|
|
2649
|
-
ctx.moveTo(
|
|
2650
|
-
ctx.lineTo(
|
|
2754
|
+
ctx.moveTo(point.x - plusSize, point.y);
|
|
2755
|
+
ctx.lineTo(point.x + plusSize, point.y);
|
|
2756
|
+
ctx.moveTo(point.x, point.y - plusSize);
|
|
2757
|
+
ctx.lineTo(point.x, point.y + plusSize);
|
|
2651
2758
|
ctx.stroke();
|
|
2652
2759
|
}
|
|
2653
2760
|
renderAnchorHighlights(ctx, point, reconnecting) {
|
|
@@ -2668,7 +2775,7 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2668
2775
|
ctx.arc(anchor.point.x, anchor.point.y, radius, 0, Math.PI * 2);
|
|
2669
2776
|
ctx.fill();
|
|
2670
2777
|
if (isNearest) if (forbidden) this.drawCross(radius, ctx, anchor);
|
|
2671
|
-
else this.drawPlus(radius, ctx, anchor);
|
|
2778
|
+
else this.drawPlus(radius, ctx, anchor.point);
|
|
2672
2779
|
}
|
|
2673
2780
|
ctx.restore();
|
|
2674
2781
|
}
|
|
@@ -2693,19 +2800,94 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2693
2800
|
}
|
|
2694
2801
|
return null;
|
|
2695
2802
|
}
|
|
2803
|
+
startOutlineConnection(node, attach) {
|
|
2804
|
+
const { point: outlinePoint, param } = node.getClosestPointOnOutline(attach);
|
|
2805
|
+
this.sourceNode = node;
|
|
2806
|
+
this.isConnecting = true;
|
|
2807
|
+
this.sourceAnchorId = null;
|
|
2808
|
+
this.sourcePoint = outlinePoint;
|
|
2809
|
+
this.sourceOutlineParam = param;
|
|
2810
|
+
this.previewEndpoint = attach;
|
|
2811
|
+
this.emit("connectionStart", node);
|
|
2812
|
+
this.renderer.markDirty();
|
|
2813
|
+
}
|
|
2814
|
+
outlineHandleHysteresis() {
|
|
2815
|
+
return 8 / Math.max(this.renderer.zoom, 1e-4);
|
|
2816
|
+
}
|
|
2817
|
+
outlineConnectHandleFor(node, pointer) {
|
|
2818
|
+
const prevSide = node.id === this.hoverNodeId ? this.hoverOutlineSide : null;
|
|
2819
|
+
const geom = getOutlineConnectHandle(node.getBounds(), pointer, 0, prevSide, this.outlineHandleHysteresis());
|
|
2820
|
+
const { point: onOutline } = node.getClosestPointOnOutline(geom.attach);
|
|
2821
|
+
return {
|
|
2822
|
+
attach: onOutline,
|
|
2823
|
+
handle: onOutline,
|
|
2824
|
+
side: geom.side
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
outlineHandleHitRadius() {
|
|
2828
|
+
return 10 / Math.max(this.renderer.zoom, 1e-4);
|
|
2829
|
+
}
|
|
2830
|
+
findOutlineConnectHandleAt(point) {
|
|
2831
|
+
if (!this.attachToOutline) return null;
|
|
2832
|
+
const radiusSq = this.outlineHandleHitRadius() ** 2;
|
|
2833
|
+
const nodes = Array.from(this.renderer.nodes.values());
|
|
2834
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
2835
|
+
const node = nodes[i];
|
|
2836
|
+
if (!node.visible || !this.isCompatibleTarget(node)) continue;
|
|
2837
|
+
const { attach, handle } = this.outlineConnectHandleFor(node, point);
|
|
2838
|
+
const dx = point.x - handle.x;
|
|
2839
|
+
const dy = point.y - handle.y;
|
|
2840
|
+
if (dx * dx + dy * dy <= radiusSq) return {
|
|
2841
|
+
node,
|
|
2842
|
+
attach,
|
|
2843
|
+
handle
|
|
2844
|
+
};
|
|
2845
|
+
}
|
|
2846
|
+
return null;
|
|
2847
|
+
}
|
|
2848
|
+
renderOutlineConnectHandle(ctx) {
|
|
2849
|
+
if (!this.hoverNodeId || !this.hoverPoint) return;
|
|
2850
|
+
const node = this.renderer.getNode(this.hoverNodeId);
|
|
2851
|
+
if (!node) return;
|
|
2852
|
+
const { handle } = this.outlineConnectHandleFor(node, this.hoverPoint);
|
|
2853
|
+
const radius = this.hoverOutlineHandle ? 6 : 4;
|
|
2854
|
+
ctx.save();
|
|
2855
|
+
ctx.setLineDash([]);
|
|
2856
|
+
ctx.fillStyle = "#3b82f6";
|
|
2857
|
+
ctx.beginPath();
|
|
2858
|
+
ctx.arc(handle.x, handle.y, radius, 0, Math.PI * 2);
|
|
2859
|
+
ctx.fill();
|
|
2860
|
+
this.drawPlus(radius, ctx, handle);
|
|
2861
|
+
ctx.restore();
|
|
2862
|
+
}
|
|
2863
|
+
clearOutlineHandleCursor() {
|
|
2864
|
+
if (this.hoverOutlineHandle) {
|
|
2865
|
+
this.hoverOutlineHandle = false;
|
|
2866
|
+
this.setCursor("");
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2696
2869
|
updateHover(point) {
|
|
2697
2870
|
if (this.hoverDisabled) return;
|
|
2698
|
-
const
|
|
2871
|
+
const handleHit = this.findOutlineConnectHandleAt(point);
|
|
2872
|
+
const node = handleHit?.node ?? this.getNodeAtPoint(point, false);
|
|
2699
2873
|
const prevNodeId = this.hoverNodeId;
|
|
2700
2874
|
const prevAnchorId = this.hoverAnchorId;
|
|
2875
|
+
const prevOutlineHandle = this.hoverOutlineHandle;
|
|
2876
|
+
this.hoverPoint = node ? point : null;
|
|
2701
2877
|
if (!node) {
|
|
2702
2878
|
this.hoverNodeId = null;
|
|
2703
2879
|
this.hoverAnchorId = null;
|
|
2880
|
+
this.hoverOutlineSide = null;
|
|
2881
|
+
this.clearOutlineHandleCursor();
|
|
2704
2882
|
} else {
|
|
2705
2883
|
this.hoverNodeId = node.id;
|
|
2706
|
-
this.hoverAnchorId = this.getAnchorAtPoint(node, point)?.id ?? null;
|
|
2884
|
+
this.hoverAnchorId = handleHit ? null : this.getAnchorAtPoint(node, point)?.id ?? null;
|
|
2885
|
+
this.hoverOutlineHandle = handleHit !== null;
|
|
2886
|
+
if (this.attachToOutline) this.hoverOutlineSide = this.outlineConnectHandleFor(node, point).side;
|
|
2887
|
+
if (this.hoverOutlineHandle) this.setCursor("crosshair");
|
|
2888
|
+
else if (prevOutlineHandle) this.setCursor("");
|
|
2707
2889
|
}
|
|
2708
|
-
if (prevNodeId !== this.hoverNodeId || prevAnchorId !== this.hoverAnchorId) this.renderer.markDirty();
|
|
2890
|
+
if (prevNodeId !== this.hoverNodeId || prevAnchorId !== this.hoverAnchorId || prevOutlineHandle !== this.hoverOutlineHandle || this.attachToOutline && node !== null) this.renderer.markDirty();
|
|
2709
2891
|
}
|
|
2710
2892
|
getAnchorAtPoint(node, point) {
|
|
2711
2893
|
const anchorIds = !this.attachToOutline && node.ports.length > 0 ? node.getPortAnchorIds() : null;
|