in src/helpers/intersect-helpers.js [7:104]
export function getRotatedRectIntersect(
defSvgRotatedRectElement: any,
src: any,
trg: any,
includesArrow: boolean,
viewWrapperElem: HTMLDivElement
) {
const response = getDefaultIntersectResponse();
const arrowSize = getArrowSize(viewWrapperElem);
const clientRect = defSvgRotatedRectElement.getBoundingClientRect();
const widthAttr = defSvgRotatedRectElement.getAttribute('width');
const heightAttr = defSvgRotatedRectElement.getAttribute('height');
const w = widthAttr ? parseFloat(widthAttr) : clientRect.width;
const h = heightAttr ? parseFloat(heightAttr) : clientRect.height;
const trgX = trg.x || 0;
const trgY = trg.y || 0;
const srcX = src.x || 0;
const srcY = src.y || 0;
const top = trgY - h / 2;
const bottom = trgY + h / 2;
const left = trgX - w / 2;
const right = trgX + w / 2;
const line = shape('line', { x1: srcX, y1: srcY, x2: trgX, y2: trgY });
// define rectangle
const rect = {
topLeft: new Point2D(left, top),
bottomRight: new Point2D(right, bottom),
};
// convert rectangle corners to polygon (list of points)
const poly = [
rect.topLeft,
new Point2D(rect.bottomRight.x, rect.topLeft.y),
rect.bottomRight,
new Point2D(rect.topLeft.x, rect.bottomRight.y),
];
// find center point of rectangle
const center = rect.topLeft.lerp(rect.bottomRight, 0.5);
// get the rotation
const transform = defSvgRotatedRectElement.getAttribute('transform');
let rotate = transform
? transform.replace(/(rotate.[0-9]*.)|[^]/g, '$1')
: null;
let angle = 0;
if (rotate) {
// get the number
rotate = rotate.replace(/^rotate\(|\)$/g, '');
// define rotation in radians
angle = (parseFloat(rotate) * Math.PI) / 180.0;
}
// create matrix for rotating around center of rectangle
const rotation = Matrix2D.rotationAt(angle, center);
// create new rotated polygon
const rotatedPoly = poly.map(p => p.transform(rotation));
// find intersections
const pathIntersect = Intersection.intersectLinePolygon(
line.params[0],
line.params[1],
rotatedPoly
);
if (pathIntersect.points.length > 0) {
let arrowWidth = 0; //arrowSize.width;
let arrowHeight = 0; //arrowSize.height;
const xIntersect = pathIntersect.points[0].x;
const yIntersect = pathIntersect.points[0].y;
if (xIntersect > left && xIntersect < right && yIntersect > trgY) {
// arrow points to the bottom of the node
arrowHeight = arrowSize.height;
} else if (xIntersect > left && xIntersect < right && yIntersect < trgY) {
// arrow points to the top of the node
arrowHeight = -arrowSize.height;
} else if (yIntersect > top && yIntersect < bottom && xIntersect < trgX) {
// arrow points to the left of the node
arrowWidth = -arrowSize.width;
} else {
// arrow points to the right of the node
arrowWidth = arrowSize.width;
}
response.xOff = trgX - xIntersect - (includesArrow ? arrowWidth / 1.25 : 0);
response.yOff =
trgY - yIntersect - (includesArrow ? arrowHeight / 1.25 : 0);
response.intersect = pathIntersect.points[0];
}
return response;
}