import { Angle, Point, Line } from '@antv/x6-geometry'; function rollup(points, merge) { if (merge != null && merge !== false) { const amount = typeof merge === 'boolean' ? 0 : merge; if (amount > 0) { const center1 = Point.create(points[1]).move(points[2], amount); const center2 = Point.create(points[1]).move(points[0], amount); return [center1.toJSON(), ...points, center2.toJSON()]; } { const center = points[1]; return [Object.assign({}, center), ...points, Object.assign({}, center)]; } } return points; } export const loop = function (vertices, options, edgeView) { const width = options.width || 50; const height = options.height || 80; const halfHeight = height / 2; const angle = options.angle || 'auto'; const sourceAnchor = edgeView.sourceAnchor; const targetAnchor = edgeView.targetAnchor; const sourceBBox = edgeView.sourceBBox; const targetBBox = edgeView.targetBBox; if (sourceAnchor.equals(targetAnchor)) { const getVertices = (angle) => { const rad = Angle.toRad(angle); const sin = Math.sin(rad); const cos = Math.cos(rad); const center = new Point(sourceAnchor.x + cos * width, sourceAnchor.y + sin * width); const ref = new Point(center.x - cos * halfHeight, center.y - sin * halfHeight); const p1 = ref.clone().rotate(-90, center); const p2 = ref.clone().rotate(90, center); return [p1.toJSON(), center.toJSON(), p2.toJSON()]; }; const validate = (end) => { const start = sourceAnchor.clone().move(end, -1); const line = new Line(start, end); return (!sourceBBox.containsPoint(end) && !sourceBBox.intersectsWithLine(line)); }; const angles = [0, 90, 180, 270, 45, 135, 225, 315]; if (typeof angle === 'number') { return rollup(getVertices(angle), options.merge); } const center = sourceBBox.getCenter(); if (center.equals(sourceAnchor)) { return rollup(getVertices(0), options.merge); } const deg = center.angleBetween(sourceAnchor, center.clone().translate(1, 0)); let ret = getVertices(deg); if (validate(ret[1])) { return rollup(ret, options.merge); } // return the best vertices for (let i = 1, l = angles.length; i < l; i += 1) { ret = getVertices(deg + angles[i]); if (validate(ret[1])) { return rollup(ret, options.merge); } } return rollup(ret, options.merge); } { const line = new Line(sourceAnchor, targetAnchor); let parallel = line.parallel(-width); let center = parallel.getCenter(); let p1 = parallel.start.clone().move(parallel.end, halfHeight); let p2 = parallel.end.clone().move(parallel.start, halfHeight); const ref = line.parallel(-1); const line1 = new Line(ref.start, center); const line2 = new Line(ref.end, center); if (sourceBBox.containsPoint(center) || targetBBox.containsPoint(center) || sourceBBox.intersectsWithLine(line1) || sourceBBox.intersectsWithLine(line2) || targetBBox.intersectsWithLine(line1) || targetBBox.intersectsWithLine(line2)) { parallel = line.parallel(width); center = parallel.getCenter(); p1 = parallel.start.clone().move(parallel.end, halfHeight); p2 = parallel.end.clone().move(parallel.start, halfHeight); } if (options.merge) { const line = new Line(sourceAnchor, targetAnchor); const normal = new Line(center, line.center).setLength(Number.MAX_SAFE_INTEGER); const intersects1 = sourceBBox.intersectsWithLine(normal); const intersects2 = targetBBox.intersectsWithLine(normal); const intersects = intersects1 ? Array.isArray(intersects1) ? intersects1 : [intersects1] : []; if (intersects2) { if (Array.isArray(intersects2)) { intersects.push(...intersects2); } else { intersects.push(intersects2); } } const anchor = line.center.closest(intersects); if (anchor) { edgeView.sourceAnchor = anchor.clone(); edgeView.targetAnchor = anchor.clone(); } else { edgeView.sourceAnchor = line.center.clone(); edgeView.targetAnchor = line.center.clone(); } } return rollup([p1.toJSON(), center.toJSON(), p2.toJSON()], options.merge); } }; //# sourceMappingURL=loop.js.map