mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
fix(editor): connector target position NaN (#11606)
Close [BS-3086](https://linear.app/affine-design/issue/BS-3086/frame里套frame,连一下connector,拖两下,白板损坏) ### What Changes - Fixed `bound.toRelative` may be return `NaN` when `bound.w === 0 || bound.h ===0` - Remove type assertions from `connector-manager.ts` for more type safety
This commit is contained in:
@@ -11,6 +11,24 @@ export function randomSeed(): number {
|
||||
return Math.floor(Math.random() * 2 ** 31);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the intersection point of two line segments.
|
||||
*
|
||||
* @param sp - Start point of the first line segment [x, y]
|
||||
* @param ep - End point of the first line segment [x, y]
|
||||
* @param sp2 - Start point of the second line segment [x, y]
|
||||
* @param ep2 - End point of the second line segment [x, y]
|
||||
* @param infinite - If true, treats the lines as infinite lines rather than line segments
|
||||
* @returns The intersection point [x, y] if the lines intersect, null if they are parallel or coincident
|
||||
*
|
||||
* @example
|
||||
* const intersection = lineIntersects([0, 0], [2, 2], [0, 2], [2, 0]);
|
||||
* // Returns [1, 1] - the intersection point of the two line segments
|
||||
*
|
||||
* @example
|
||||
* const parallel = lineIntersects([0, 0], [2, 2], [0, 1], [2, 3], true);
|
||||
* // Returns null - the lines are parallel
|
||||
*/
|
||||
export function lineIntersects(
|
||||
sp: IVec,
|
||||
ep: IVec,
|
||||
@@ -45,10 +63,23 @@ export function lineIntersects(
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the nearest point on a polygon to a given point.
|
||||
*
|
||||
* @param points - Array of points defining the polygon vertices [x, y][]
|
||||
* @param point - The point to find the nearest point to [x, y]
|
||||
* @returns The nearest point on the polygon to the given point
|
||||
* @throws Error if points array is empty or has less than 2 points
|
||||
*/
|
||||
export function polygonNearestPoint(points: IVec[], point: IVec) {
|
||||
const len = points.length;
|
||||
let rst: IVec;
|
||||
let dis = Infinity;
|
||||
if (len < 2) {
|
||||
throw new Error('Polygon must have at least 2 points');
|
||||
}
|
||||
|
||||
let rst: IVec = points[0]; // Initialize with first point as fallback
|
||||
let dis = Vec.dist(points[0], point);
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const p = points[i];
|
||||
const p2 = points[(i + 1) % len];
|
||||
@@ -59,7 +90,7 @@ export function polygonNearestPoint(points: IVec[], point: IVec) {
|
||||
rst = temp;
|
||||
}
|
||||
}
|
||||
return rst!;
|
||||
return rst;
|
||||
}
|
||||
|
||||
export function polygonPointDistance(points: IVec[], point: IVec) {
|
||||
|
||||
@@ -341,8 +341,15 @@ export class Bound implements IBound {
|
||||
return serializeXYWH(this.x, this.y, this.w, this.h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a point to relative coordinates.
|
||||
* @param point - The point to convert.
|
||||
* @returns The normalized relative coordinates of the point.
|
||||
*/
|
||||
toRelative([x, y]: IVec): IVec {
|
||||
return [(x - this.x) / this.w, (y - this.y) / this.h];
|
||||
const normalizedX = this.w === 0 ? 0 : (x - this.x) / this.w;
|
||||
const normalizedY = this.h === 0 ? 0 : (y - this.y) / this.h;
|
||||
return [normalizedX, normalizedY];
|
||||
}
|
||||
|
||||
toXYWH(): XYWH {
|
||||
|
||||
@@ -565,6 +565,8 @@ export class Vec {
|
||||
* @param n
|
||||
* @param min
|
||||
*/
|
||||
static clampV(A: IVec, min: number, max?: number): IVec;
|
||||
|
||||
static clampV(A: number[], min: number): number[];
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
||||
|
||||
@@ -214,7 +214,12 @@ export class Viewport {
|
||||
* This property is used to calculate the scale of the editor.
|
||||
*/
|
||||
get viewScale() {
|
||||
if (!this._shell || this._cachedOffsetWidth === null) return 1;
|
||||
if (
|
||||
!this._shell ||
|
||||
this._cachedOffsetWidth === null ||
|
||||
this._cachedOffsetWidth === 0
|
||||
)
|
||||
return 1;
|
||||
return this.boundingClientRect.width / this._cachedOffsetWidth;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user