105 lines
3.6 KiB
JavaScript
105 lines
3.6 KiB
JavaScript
import { ObjectExt, Dom } from '@antv/x6-common';
|
|
import { Path, Rectangle, Ellipse } from '@antv/x6-geometry';
|
|
import { offset, getStrokeWidth, findShapeNode } from './util';
|
|
import { Util } from '../../util';
|
|
/**
|
|
* Places the connection point at the intersection between the
|
|
* edge path end segment and the actual shape of the target magnet.
|
|
*/
|
|
export const boundary = function (line, view, magnet, options) {
|
|
let node;
|
|
let intersection;
|
|
const anchor = line.end;
|
|
const selector = options.selector;
|
|
if (typeof selector === 'string') {
|
|
node = view.findOne(selector);
|
|
}
|
|
else if (Array.isArray(selector)) {
|
|
node = ObjectExt.getByPath(magnet, selector);
|
|
}
|
|
else {
|
|
node = findShapeNode(magnet);
|
|
}
|
|
if (!Dom.isSVGGraphicsElement(node)) {
|
|
if (node === magnet || !Dom.isSVGGraphicsElement(magnet)) {
|
|
return anchor;
|
|
}
|
|
node = magnet;
|
|
}
|
|
const localShape = view.getShapeOfElement(node);
|
|
const magnetMatrix = view.getMatrixOfElement(node);
|
|
const translateMatrix = view.getRootTranslatedMatrix();
|
|
const rotateMatrix = view.getRootRotatedMatrix();
|
|
const targetMatrix = translateMatrix
|
|
.multiply(rotateMatrix)
|
|
.multiply(magnetMatrix);
|
|
const localMatrix = targetMatrix.inverse();
|
|
const localLine = Util.transformLine(line, localMatrix);
|
|
const localRef = localLine.start.clone();
|
|
const data = view.getDataOfElement(node);
|
|
if (options.insideout === false) {
|
|
if (data.shapeBBox == null) {
|
|
data.shapeBBox = localShape.bbox();
|
|
}
|
|
const localBBox = data.shapeBBox;
|
|
if (localBBox != null && localBBox.containsPoint(localRef)) {
|
|
return anchor;
|
|
}
|
|
}
|
|
if (options.extrapolate === true) {
|
|
localLine.setLength(1e6);
|
|
}
|
|
// Caching segment subdivisions for paths
|
|
let pathOptions;
|
|
if (Path.isPath(localShape)) {
|
|
const precision = options.precision || 2;
|
|
if (data.segmentSubdivisions == null) {
|
|
data.segmentSubdivisions = localShape.getSegmentSubdivisions({
|
|
precision,
|
|
});
|
|
}
|
|
pathOptions = {
|
|
precision,
|
|
segmentSubdivisions: data.segmentSubdivisions,
|
|
};
|
|
intersection = localLine.intersect(localShape, pathOptions);
|
|
}
|
|
else {
|
|
intersection = localLine.intersect(localShape);
|
|
}
|
|
if (intersection) {
|
|
if (Array.isArray(intersection)) {
|
|
intersection = localRef.closest(intersection);
|
|
}
|
|
}
|
|
else if (options.sticky === true) {
|
|
// No intersection, find the closest point instead
|
|
if (Rectangle.isRectangle(localShape)) {
|
|
intersection = localShape.getNearestPointToPoint(localRef);
|
|
}
|
|
else if (Ellipse.isEllipse(localShape)) {
|
|
intersection = localShape.intersectsWithLineFromCenterToPoint(localRef);
|
|
}
|
|
else {
|
|
intersection = localShape.closestPoint(localRef, pathOptions);
|
|
}
|
|
}
|
|
const cp = intersection
|
|
? Util.transformPoint(intersection, targetMatrix)
|
|
: anchor;
|
|
let cpOffset = options.offset || 0;
|
|
if (options.stroked !== false) {
|
|
if (typeof cpOffset === 'object') {
|
|
cpOffset = Object.assign({}, cpOffset);
|
|
if (cpOffset.x == null) {
|
|
cpOffset.x = 0;
|
|
}
|
|
cpOffset.x += getStrokeWidth(node) / 2;
|
|
}
|
|
else {
|
|
cpOffset += getStrokeWidth(node) / 2;
|
|
}
|
|
}
|
|
return offset(cp, line.start, cpOffset);
|
|
};
|
|
//# sourceMappingURL=boundary.js.map
|