@joint/core 4.0.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/LICENSE +376 -0
- package/README.md +49 -0
- package/dist/geometry.js +6486 -0
- package/dist/geometry.min.js +8 -0
- package/dist/joint.d.ts +5536 -0
- package/dist/joint.js +39629 -0
- package/dist/joint.min.js +8 -0
- package/dist/joint.nowrap.js +39626 -0
- package/dist/joint.nowrap.min.js +8 -0
- package/dist/vectorizer.js +9135 -0
- package/dist/vectorizer.min.js +8 -0
- package/dist/version.mjs +3 -0
- package/index.js +3 -0
- package/joint.mjs +27 -0
- package/package.json +192 -0
- package/src/V/annotation.mjs +0 -0
- package/src/V/index.mjs +2642 -0
- package/src/anchors/index.mjs +123 -0
- package/src/config/index.mjs +12 -0
- package/src/connectionPoints/index.mjs +202 -0
- package/src/connectionStrategies/index.mjs +73 -0
- package/src/connectors/curve.mjs +553 -0
- package/src/connectors/index.mjs +6 -0
- package/src/connectors/jumpover.mjs +452 -0
- package/src/connectors/normal.mjs +12 -0
- package/src/connectors/rounded.mjs +17 -0
- package/src/connectors/smooth.mjs +44 -0
- package/src/connectors/straight.mjs +110 -0
- package/src/dia/Cell.mjs +945 -0
- package/src/dia/CellView.mjs +1316 -0
- package/src/dia/Element.mjs +519 -0
- package/src/dia/ElementView.mjs +859 -0
- package/src/dia/Graph.mjs +1112 -0
- package/src/dia/HighlighterView.mjs +319 -0
- package/src/dia/Link.mjs +565 -0
- package/src/dia/LinkView.mjs +2207 -0
- package/src/dia/Paper.mjs +3171 -0
- package/src/dia/PaperLayer.mjs +75 -0
- package/src/dia/ToolView.mjs +69 -0
- package/src/dia/ToolsView.mjs +128 -0
- package/src/dia/attributes/calc.mjs +128 -0
- package/src/dia/attributes/connection.mjs +75 -0
- package/src/dia/attributes/defs.mjs +76 -0
- package/src/dia/attributes/eval.mjs +64 -0
- package/src/dia/attributes/index.mjs +69 -0
- package/src/dia/attributes/legacy.mjs +148 -0
- package/src/dia/attributes/offset.mjs +53 -0
- package/src/dia/attributes/props.mjs +30 -0
- package/src/dia/attributes/shape.mjs +92 -0
- package/src/dia/attributes/text.mjs +180 -0
- package/src/dia/index.mjs +13 -0
- package/src/dia/layers/GridLayer.mjs +176 -0
- package/src/dia/ports.mjs +874 -0
- package/src/elementTools/Control.mjs +153 -0
- package/src/elementTools/HoverConnect.mjs +37 -0
- package/src/elementTools/index.mjs +5 -0
- package/src/env/index.mjs +43 -0
- package/src/g/bezier.mjs +175 -0
- package/src/g/curve.mjs +956 -0
- package/src/g/ellipse.mjs +245 -0
- package/src/g/extend.mjs +64 -0
- package/src/g/geometry.helpers.mjs +58 -0
- package/src/g/index.mjs +17 -0
- package/src/g/intersection.mjs +511 -0
- package/src/g/line.bearing.mjs +30 -0
- package/src/g/line.length.mjs +5 -0
- package/src/g/line.mjs +356 -0
- package/src/g/line.squaredLength.mjs +10 -0
- package/src/g/path.mjs +2260 -0
- package/src/g/point.mjs +375 -0
- package/src/g/points.mjs +247 -0
- package/src/g/polygon.mjs +51 -0
- package/src/g/polyline.mjs +523 -0
- package/src/g/rect.mjs +556 -0
- package/src/g/types.mjs +10 -0
- package/src/highlighters/addClass.mjs +27 -0
- package/src/highlighters/index.mjs +5 -0
- package/src/highlighters/list.mjs +111 -0
- package/src/highlighters/mask.mjs +220 -0
- package/src/highlighters/opacity.mjs +17 -0
- package/src/highlighters/stroke.mjs +100 -0
- package/src/layout/index.mjs +4 -0
- package/src/layout/ports/port.mjs +188 -0
- package/src/layout/ports/portLabel.mjs +224 -0
- package/src/linkAnchors/index.mjs +76 -0
- package/src/linkTools/Anchor.mjs +235 -0
- package/src/linkTools/Arrowhead.mjs +103 -0
- package/src/linkTools/Boundary.mjs +48 -0
- package/src/linkTools/Button.mjs +121 -0
- package/src/linkTools/Connect.mjs +85 -0
- package/src/linkTools/HoverConnect.mjs +161 -0
- package/src/linkTools/Segments.mjs +393 -0
- package/src/linkTools/Vertices.mjs +253 -0
- package/src/linkTools/helpers.mjs +33 -0
- package/src/linkTools/index.mjs +8 -0
- package/src/mvc/Collection.mjs +560 -0
- package/src/mvc/Data.mjs +46 -0
- package/src/mvc/Dom/Dom.mjs +587 -0
- package/src/mvc/Dom/Event.mjs +130 -0
- package/src/mvc/Dom/animations.mjs +122 -0
- package/src/mvc/Dom/events.mjs +69 -0
- package/src/mvc/Dom/index.mjs +13 -0
- package/src/mvc/Dom/methods.mjs +392 -0
- package/src/mvc/Dom/props.mjs +77 -0
- package/src/mvc/Dom/vars.mjs +5 -0
- package/src/mvc/Events.mjs +337 -0
- package/src/mvc/Listener.mjs +33 -0
- package/src/mvc/Model.mjs +239 -0
- package/src/mvc/View.mjs +323 -0
- package/src/mvc/ViewBase.mjs +182 -0
- package/src/mvc/index.mjs +9 -0
- package/src/mvc/mvcUtils.mjs +90 -0
- package/src/polyfills/array.js +4 -0
- package/src/polyfills/base64.js +68 -0
- package/src/polyfills/index.mjs +5 -0
- package/src/polyfills/number.js +3 -0
- package/src/polyfills/string.js +3 -0
- package/src/polyfills/typedArray.js +47 -0
- package/src/routers/index.mjs +6 -0
- package/src/routers/manhattan.mjs +856 -0
- package/src/routers/metro.mjs +91 -0
- package/src/routers/normal.mjs +6 -0
- package/src/routers/oneSide.mjs +60 -0
- package/src/routers/orthogonal.mjs +323 -0
- package/src/routers/rightAngle.mjs +1056 -0
- package/src/shapes/index.mjs +3 -0
- package/src/shapes/standard.mjs +755 -0
- package/src/util/cloneCells.mjs +67 -0
- package/src/util/getRectPoint.mjs +65 -0
- package/src/util/index.mjs +5 -0
- package/src/util/svgTagTemplate.mjs +110 -0
- package/src/util/util.mjs +1754 -0
- package/src/util/utilHelpers.mjs +2402 -0
- package/src/util/wrappers.mjs +56 -0
- package/types/geometry.d.ts +815 -0
- package/types/index.d.ts +53 -0
- package/types/joint.d.ts +4391 -0
- package/types/joint.head.d.ts +12 -0
- package/types/vectorizer.d.ts +327 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import * as util from '../util/index.mjs';
|
|
2
|
+
import { toRad } from '../g/index.mjs';
|
|
3
|
+
import { resolveRef } from '../linkAnchors/index.mjs';
|
|
4
|
+
|
|
5
|
+
function bboxWrapper(method) {
|
|
6
|
+
|
|
7
|
+
return function(view, magnet, ref, opt) {
|
|
8
|
+
|
|
9
|
+
var rotate = !!opt.rotate;
|
|
10
|
+
var bbox = (rotate) ? view.getNodeUnrotatedBBox(magnet) : view.getNodeBBox(magnet);
|
|
11
|
+
var anchor = bbox[method]();
|
|
12
|
+
|
|
13
|
+
var dx = opt.dx;
|
|
14
|
+
if (dx) {
|
|
15
|
+
var dxPercentage = util.isPercentage(dx);
|
|
16
|
+
dx = parseFloat(dx);
|
|
17
|
+
if (isFinite(dx)) {
|
|
18
|
+
if (dxPercentage) {
|
|
19
|
+
dx /= 100;
|
|
20
|
+
dx *= bbox.width;
|
|
21
|
+
}
|
|
22
|
+
anchor.x += dx;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var dy = opt.dy;
|
|
27
|
+
if (dy) {
|
|
28
|
+
var dyPercentage = util.isPercentage(dy);
|
|
29
|
+
dy = parseFloat(dy);
|
|
30
|
+
if (isFinite(dy)) {
|
|
31
|
+
if (dyPercentage) {
|
|
32
|
+
dy /= 100;
|
|
33
|
+
dy *= bbox.height;
|
|
34
|
+
}
|
|
35
|
+
anchor.y += dy;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (rotate) ? anchor.rotate(view.model.getBBox().center(), -view.model.angle()) : anchor;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function _perpendicular(view, magnet, refPoint, opt) {
|
|
44
|
+
|
|
45
|
+
var angle = view.model.angle();
|
|
46
|
+
var bbox = view.getNodeBBox(magnet);
|
|
47
|
+
var anchor = bbox.center();
|
|
48
|
+
var topLeft = bbox.origin();
|
|
49
|
+
var bottomRight = bbox.corner();
|
|
50
|
+
|
|
51
|
+
var padding = opt.padding;
|
|
52
|
+
if (!isFinite(padding)) padding = 0;
|
|
53
|
+
|
|
54
|
+
if ((topLeft.y + padding) <= refPoint.y && refPoint.y <= (bottomRight.y - padding)) {
|
|
55
|
+
var dy = (refPoint.y - anchor.y);
|
|
56
|
+
anchor.x += (angle === 0 || angle === 180) ? 0 : dy * 1 / Math.tan(toRad(angle));
|
|
57
|
+
anchor.y += dy;
|
|
58
|
+
} else if ((topLeft.x + padding) <= refPoint.x && refPoint.x <= (bottomRight.x - padding)) {
|
|
59
|
+
var dx = (refPoint.x - anchor.x);
|
|
60
|
+
anchor.y += (angle === 90 || angle === 270) ? 0 : dx * Math.tan(toRad(angle));
|
|
61
|
+
anchor.x += dx;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return anchor;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function _midSide(view, magnet, refPoint, opt) {
|
|
68
|
+
|
|
69
|
+
var rotate = !!opt.rotate;
|
|
70
|
+
var bbox, angle, center;
|
|
71
|
+
if (rotate) {
|
|
72
|
+
bbox = view.getNodeUnrotatedBBox(magnet);
|
|
73
|
+
center = view.model.getBBox().center();
|
|
74
|
+
angle = view.model.angle();
|
|
75
|
+
} else {
|
|
76
|
+
bbox = view.getNodeBBox(magnet);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
var padding = opt.padding;
|
|
80
|
+
if (isFinite(padding)) bbox.inflate(padding);
|
|
81
|
+
|
|
82
|
+
if (rotate) refPoint.rotate(center, angle);
|
|
83
|
+
|
|
84
|
+
var side = bbox.sideNearestToPoint(refPoint);
|
|
85
|
+
var anchor;
|
|
86
|
+
switch (side) {
|
|
87
|
+
case 'left':
|
|
88
|
+
anchor = bbox.leftMiddle();
|
|
89
|
+
break;
|
|
90
|
+
case 'right':
|
|
91
|
+
anchor = bbox.rightMiddle();
|
|
92
|
+
break;
|
|
93
|
+
case 'top':
|
|
94
|
+
anchor = bbox.topMiddle();
|
|
95
|
+
break;
|
|
96
|
+
case 'bottom':
|
|
97
|
+
anchor = bbox.bottomMiddle();
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return (rotate) ? anchor.rotate(center, -angle) : anchor;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Can find anchor from model, when there is no selector or the link end
|
|
105
|
+
// is connected to a port
|
|
106
|
+
function _modelCenter(view, _magnet, _refPoint, opt, endType) {
|
|
107
|
+
return view.model.getPointFromConnectedLink(this.model, endType).offset(opt.dx, opt.dy);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
//joint.anchors
|
|
111
|
+
export const center = bboxWrapper('center');
|
|
112
|
+
export const top = bboxWrapper('topMiddle');
|
|
113
|
+
export const bottom = bboxWrapper('bottomMiddle');
|
|
114
|
+
export const left = bboxWrapper('leftMiddle');
|
|
115
|
+
export const right = bboxWrapper('rightMiddle');
|
|
116
|
+
export const topLeft = bboxWrapper('origin');
|
|
117
|
+
export const topRight = bboxWrapper('topRight');
|
|
118
|
+
export const bottomLeft = bboxWrapper('bottomLeft');
|
|
119
|
+
export const bottomRight = bboxWrapper('corner');
|
|
120
|
+
export const perpendicular = resolveRef(_perpendicular);
|
|
121
|
+
export const midSide = resolveRef(_midSide);
|
|
122
|
+
export const modelCenter = _modelCenter;
|
|
123
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const config = {
|
|
2
|
+
// When set to `true` the cell selectors could be defined as CSS selectors.
|
|
3
|
+
// If not, only JSON Markup selectors are taken into account.
|
|
4
|
+
useCSSSelectors: false,
|
|
5
|
+
// The class name prefix config is for advanced use only.
|
|
6
|
+
// Be aware that if you change the prefix, the JointJS CSS will no longer function properly.
|
|
7
|
+
classNamePrefix: 'joint-',
|
|
8
|
+
defaultTheme: 'default',
|
|
9
|
+
// The maximum delay required for two consecutive touchend events to be interpreted
|
|
10
|
+
// as a double-tap.
|
|
11
|
+
doubleTapInterval: 300
|
|
12
|
+
};
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import * as g from '../g/index.mjs';
|
|
2
|
+
import V from '../V/index.mjs';
|
|
3
|
+
import * as util from '../util/index.mjs';
|
|
4
|
+
|
|
5
|
+
function offsetPoint(p1, p2, offset) {
|
|
6
|
+
if (util.isPlainObject(offset)) {
|
|
7
|
+
const { x, y } = offset;
|
|
8
|
+
if (isFinite(y)) {
|
|
9
|
+
const line = new g.Line(p2, p1);
|
|
10
|
+
const { start, end } = line.parallel(y);
|
|
11
|
+
p2 = start;
|
|
12
|
+
p1 = end;
|
|
13
|
+
}
|
|
14
|
+
offset = x;
|
|
15
|
+
}
|
|
16
|
+
if (!isFinite(offset)) return p1;
|
|
17
|
+
var length = p1.distance(p2);
|
|
18
|
+
if (offset === 0 && length > 0) return p1;
|
|
19
|
+
return p1.move(p2, -Math.min(offset, length - 1));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function stroke(magnet) {
|
|
23
|
+
|
|
24
|
+
var stroke = magnet.getAttribute('stroke-width');
|
|
25
|
+
if (stroke === null) return 0;
|
|
26
|
+
return parseFloat(stroke) || 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function alignLine(line, type, offset = 0) {
|
|
30
|
+
let coordinate, a, b, direction;
|
|
31
|
+
const { start, end } = line;
|
|
32
|
+
switch (type) {
|
|
33
|
+
case 'left':
|
|
34
|
+
coordinate = 'x';
|
|
35
|
+
a = end;
|
|
36
|
+
b = start;
|
|
37
|
+
direction = -1;
|
|
38
|
+
break;
|
|
39
|
+
case 'right':
|
|
40
|
+
coordinate = 'x';
|
|
41
|
+
a = start;
|
|
42
|
+
b = end;
|
|
43
|
+
direction = 1;
|
|
44
|
+
break;
|
|
45
|
+
case 'top':
|
|
46
|
+
coordinate = 'y';
|
|
47
|
+
a = end;
|
|
48
|
+
b = start;
|
|
49
|
+
direction = -1;
|
|
50
|
+
break;
|
|
51
|
+
case 'bottom':
|
|
52
|
+
coordinate = 'y';
|
|
53
|
+
a = start;
|
|
54
|
+
b = end;
|
|
55
|
+
direction = 1;
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (start[coordinate] < end[coordinate]) {
|
|
61
|
+
a[coordinate] = b[coordinate];
|
|
62
|
+
} else {
|
|
63
|
+
b[coordinate] = a[coordinate];
|
|
64
|
+
}
|
|
65
|
+
if (isFinite(offset)) {
|
|
66
|
+
a[coordinate] += direction * offset;
|
|
67
|
+
b[coordinate] += direction * offset;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Connection Points
|
|
72
|
+
|
|
73
|
+
function anchorConnectionPoint(line, _view, _magnet, opt) {
|
|
74
|
+
let { offset, alignOffset, align } = opt;
|
|
75
|
+
if (align) alignLine(line, align, alignOffset);
|
|
76
|
+
return offsetPoint(line.end, line.start, offset);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function bboxIntersection(line, view, magnet, opt) {
|
|
80
|
+
|
|
81
|
+
var bbox = view.getNodeBBox(magnet);
|
|
82
|
+
if (opt.stroke) bbox.inflate(stroke(magnet) / 2);
|
|
83
|
+
var intersections = line.intersect(bbox);
|
|
84
|
+
var cp = (intersections)
|
|
85
|
+
? line.start.chooseClosest(intersections)
|
|
86
|
+
: line.end;
|
|
87
|
+
return offsetPoint(cp, line.start, opt.offset);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function rectangleIntersection(line, view, magnet, opt) {
|
|
91
|
+
|
|
92
|
+
var angle = view.model.angle();
|
|
93
|
+
if (angle === 0) {
|
|
94
|
+
return bboxIntersection(line, view, magnet, opt);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
var bboxWORotation = view.getNodeUnrotatedBBox(magnet);
|
|
98
|
+
if (opt.stroke) bboxWORotation.inflate(stroke(magnet) / 2);
|
|
99
|
+
var center = bboxWORotation.center();
|
|
100
|
+
var lineWORotation = line.clone().rotate(center, angle);
|
|
101
|
+
var intersections = lineWORotation.setLength(1e6).intersect(bboxWORotation);
|
|
102
|
+
var cp = (intersections)
|
|
103
|
+
? lineWORotation.start.chooseClosest(intersections).rotate(center, -angle)
|
|
104
|
+
: line.end;
|
|
105
|
+
return offsetPoint(cp, line.start, opt.offset);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function findShapeNode(magnet) {
|
|
109
|
+
if (!magnet) return null;
|
|
110
|
+
var node = magnet;
|
|
111
|
+
do {
|
|
112
|
+
var tagName = node.tagName;
|
|
113
|
+
if (typeof tagName !== 'string') return null;
|
|
114
|
+
tagName = tagName.toUpperCase();
|
|
115
|
+
if (tagName === 'G') {
|
|
116
|
+
node = node.firstElementChild;
|
|
117
|
+
} else if (tagName === 'TITLE') {
|
|
118
|
+
node = node.nextElementSibling;
|
|
119
|
+
} else break;
|
|
120
|
+
} while (node);
|
|
121
|
+
return node;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
var BNDR_SUBDIVISIONS = 'segmentSubdivisons';
|
|
125
|
+
var BNDR_SHAPE_BBOX = 'shapeBBox';
|
|
126
|
+
|
|
127
|
+
function boundaryIntersection(line, view, magnet, opt) {
|
|
128
|
+
|
|
129
|
+
var node, intersection;
|
|
130
|
+
var selector = opt.selector;
|
|
131
|
+
var anchor = line.end;
|
|
132
|
+
|
|
133
|
+
if (typeof selector === 'string') {
|
|
134
|
+
node = view.findNode(selector);
|
|
135
|
+
} else if (selector === false) {
|
|
136
|
+
node = magnet;
|
|
137
|
+
} else if (Array.isArray(selector)) {
|
|
138
|
+
node = util.getByPath(magnet, selector);
|
|
139
|
+
} else {
|
|
140
|
+
node = findShapeNode(magnet);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (!V.isSVGGraphicsElement(node)) {
|
|
144
|
+
if (node === magnet || !V.isSVGGraphicsElement(magnet)) return anchor;
|
|
145
|
+
node = magnet;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
var localShape = view.getNodeShape(node);
|
|
149
|
+
var magnetMatrix = view.getNodeMatrix(node);
|
|
150
|
+
var translateMatrix = view.getRootTranslateMatrix();
|
|
151
|
+
var rotateMatrix = view.getRootRotateMatrix();
|
|
152
|
+
var targetMatrix = translateMatrix.multiply(rotateMatrix).multiply(magnetMatrix);
|
|
153
|
+
var localMatrix = targetMatrix.inverse();
|
|
154
|
+
var localLine = V.transformLine(line, localMatrix);
|
|
155
|
+
var localRef = localLine.start.clone();
|
|
156
|
+
var data = view.getNodeData(node);
|
|
157
|
+
|
|
158
|
+
if (opt.insideout === false) {
|
|
159
|
+
if (!data[BNDR_SHAPE_BBOX]) data[BNDR_SHAPE_BBOX] = localShape.bbox();
|
|
160
|
+
var localBBox = data[BNDR_SHAPE_BBOX];
|
|
161
|
+
if (localBBox.containsPoint(localRef)) return anchor;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Caching segment subdivisions for paths
|
|
165
|
+
var pathOpt;
|
|
166
|
+
if (localShape instanceof g.Path) {
|
|
167
|
+
var precision = opt.precision || 2;
|
|
168
|
+
if (!data[BNDR_SUBDIVISIONS]) data[BNDR_SUBDIVISIONS] = localShape.getSegmentSubdivisions({ precision: precision });
|
|
169
|
+
pathOpt = {
|
|
170
|
+
precision: precision,
|
|
171
|
+
segmentSubdivisions: data[BNDR_SUBDIVISIONS]
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (opt.extrapolate === true) localLine.setLength(1e6);
|
|
176
|
+
|
|
177
|
+
intersection = localLine.intersect(localShape, pathOpt);
|
|
178
|
+
if (intersection) {
|
|
179
|
+
// More than one intersection
|
|
180
|
+
if (V.isArray(intersection)) intersection = localRef.chooseClosest(intersection);
|
|
181
|
+
} else if (opt.sticky === true) {
|
|
182
|
+
// No intersection, find the closest point instead
|
|
183
|
+
if (localShape instanceof g.Rect) {
|
|
184
|
+
intersection = localShape.pointNearestToPoint(localRef);
|
|
185
|
+
} else if (localShape instanceof g.Ellipse) {
|
|
186
|
+
intersection = localShape.intersectionWithLineFromCenterToPoint(localRef);
|
|
187
|
+
} else {
|
|
188
|
+
intersection = localShape.closestPoint(localRef, pathOpt);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
var cp = (intersection) ? V.transformPoint(intersection, targetMatrix) : anchor;
|
|
193
|
+
var cpOffset = opt.offset || 0;
|
|
194
|
+
if (opt.stroke) cpOffset += stroke(node) / 2;
|
|
195
|
+
|
|
196
|
+
return offsetPoint(cp, line.start, cpOffset);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export const anchor = anchorConnectionPoint;
|
|
200
|
+
export const bbox = bboxIntersection;
|
|
201
|
+
export const rectangle = rectangleIntersection;
|
|
202
|
+
export const boundary = boundaryIntersection;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as util from '../util/index.mjs';
|
|
2
|
+
|
|
3
|
+
function abs2rel(absolute, max) {
|
|
4
|
+
|
|
5
|
+
if (max === 0) return '0%';
|
|
6
|
+
// round to 3 decimal places
|
|
7
|
+
const dp = 1000;
|
|
8
|
+
const relative = Math.round(absolute / max * 100 * dp) / dp;
|
|
9
|
+
return `${relative}%`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function pin(relative) {
|
|
13
|
+
|
|
14
|
+
return function(end, view, magnet, coords) {
|
|
15
|
+
var fn = (view.isNodeConnection(magnet)) ? pinnedLinkEnd : pinnedElementEnd;
|
|
16
|
+
return fn(relative, end, view, magnet, coords);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function pinnedElementEnd(relative, end, view, magnet, coords) {
|
|
21
|
+
|
|
22
|
+
var angle = view.model.angle();
|
|
23
|
+
var bbox = view.getNodeUnrotatedBBox(magnet);
|
|
24
|
+
var origin = view.model.getBBox().center();
|
|
25
|
+
coords.rotate(origin, angle);
|
|
26
|
+
var dx = coords.x - bbox.x;
|
|
27
|
+
var dy = coords.y - bbox.y;
|
|
28
|
+
|
|
29
|
+
if (relative) {
|
|
30
|
+
dx = abs2rel(dx, bbox.width);
|
|
31
|
+
dy = abs2rel(dy, bbox.height);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
end.anchor = {
|
|
35
|
+
name: 'topLeft',
|
|
36
|
+
args: {
|
|
37
|
+
dx: dx,
|
|
38
|
+
dy: dy,
|
|
39
|
+
rotate: true
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return end;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function pinnedLinkEnd(relative, end, view, _magnet, coords) {
|
|
47
|
+
|
|
48
|
+
var connection = view.getConnection();
|
|
49
|
+
if (!connection) return end;
|
|
50
|
+
var length = connection.closestPointLength(coords);
|
|
51
|
+
if (relative) {
|
|
52
|
+
var totalLength = connection.length();
|
|
53
|
+
end.anchor = {
|
|
54
|
+
name: 'connectionRatio',
|
|
55
|
+
args: {
|
|
56
|
+
ratio: length / totalLength
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
} else {
|
|
60
|
+
end.anchor = {
|
|
61
|
+
name: 'connectionLength',
|
|
62
|
+
args: {
|
|
63
|
+
length: length
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return end;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const useDefaults = util.noop;
|
|
71
|
+
export const pinAbsolute = pin(false);
|
|
72
|
+
export const pinRelative = pin(true);
|
|
73
|
+
|