fix(line): hover detection of the fold line (#167)

This commit is contained in:
Louis Young 2025-04-23 12:30:58 +08:00 committed by GitHub
parent 1887d53ce9
commit cb942616ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,26 +1,46 @@
import { type IPoint, Point, Rectangle } from '@flowgram.ai/utils'; import { type IPoint, Point, Rectangle } from '@flowgram.ai/utils';
/** /**
* 线 * 线
* @param p1 * @param point
* @param p2 * @param segStart 线
* @param p3 * @param segEnd 线
*/ */
function pointLineDistance(p1: IPoint, p2: IPoint, p3: IPoint): number { const getPointToSegmentDistance = (point: IPoint, segStart: IPoint, segEnd: IPoint): number => {
let len; const { x: px, y: py } = point;
const { x: x1, y: y1 } = segStart;
const { x: x2, y: y2 } = segEnd;
// 竖着的线 const A = px - x1;
if (p1.x - p2.x === 0) { const B = py - y1;
len = Math.abs(p3.x - p1.x); const C = x2 - x1;
const D = y2 - y1;
const dot = A * C + B * D;
const lenSq = C * C + D * D;
// 参数方程中的t参数
const param = lenSq === 0 ? -1 : dot / lenSq;
let xx: number;
let yy: number;
if (param < 0) {
xx = x1;
yy = y1;
} else if (param > 1) {
xx = x2;
yy = y2;
} else { } else {
const A = (p1.y - p2.y) / (p1.x - p2.x); xx = x1 + param * C;
const B = p1.y - A * p1.x; yy = y1 + param * D;
len = Math.abs((A * p3.x + B - p3.y) / Math.sqrt(A * A + 1));
} }
return len; const dx = px - xx;
} const dy = py - yy;
return Math.sqrt(dx * dx + dy * dy);
};
export namespace FoldLine { export namespace FoldLine {
const EDGE_RADIUS = 5; const EDGE_RADIUS = 5;
@ -218,22 +238,33 @@ export namespace FoldLine {
); );
} }
/** /**
* 线 * 线
* @param linePosition * @param points 线
* @param pos * @param pos
* @returns
*/ */
export function getFoldLineToPointDistance(points: IPoint[], pos: IPoint): number { export const getFoldLineToPointDistance = (points: IPoint[], pos: IPoint): number => {
const bounds = getBounds(points); // 特殊情况处理
if (bounds.contains(pos.x, pos.y)) { if (points.length === 0) {
const lines = points.reduce((res, point, index) => { return Infinity;
if (index === 0) {
return res;
}
res.push([points[index - 1]!, point]);
return res;
}, [] as [IPoint, IPoint][]);
return Math.min(...lines.map((l) => pointLineDistance(...l, pos)));
} }
return Math.min(...points.map((p) => Point.getDistance(p, pos)));
} if (points.length === 1) {
return Point.getDistance(points[0]!, pos);
}
// 构建线段数组
const lines: [IPoint, IPoint][] = [];
for (let i = 0; i < points.length - 1; i++) {
lines.push([points[i]!, points[i + 1]!]);
}
// 计算点到每个线段的最短距离
const distances = lines.map((line) => {
const [p1, p2] = line;
return getPointToSegmentDistance(pos, p1, p2);
});
return Math.min(...distances);
};
} }