UNPKG

@tldraw/editor

Version:

tldraw infinite canvas SDK (editor).

8 lines (7 loc) 3.95 kB
{ "version": 3, "sources": ["../../../../src/lib/primitives/geometry/Edge2d.ts"], "sourcesContent": ["import { Vec, VecLike } from '../Vec'\nimport { Geometry2d } from './Geometry2d'\n\n/** @public */\nexport class Edge2d extends Geometry2d {\n\tprivate _start: Vec\n\tprivate _end: Vec\n\tprivate _dx: number\n\tprivate _dy: number\n\tprivate _len2: number\n\n\tconstructor(config: { start: Vec; end: Vec }) {\n\t\tsuper({ ...config, isClosed: false, isFilled: false })\n\t\tconst { start, end } = config\n\n\t\tthis._start = start\n\t\tthis._end = end\n\n\t\t// Precomputed segment delta and squared length (replaces Vec.Sub(end, start) and Vec.Len2)\n\t\tthis._dx = end.x - start.x\n\t\tthis._dy = end.y - start.y\n\t\tthis._len2 = this._dx * this._dx + this._dy * this._dy\n\t}\n\n\toverride getLength() {\n\t\treturn Math.sqrt(this._len2)\n\t}\n\n\toverride getVertices(): Vec[] {\n\t\treturn [this._start, this._end]\n\t}\n\n\toverride nearestPoint(point: VecLike): Vec {\n\t\t// Inlined: Vec.NearestPointOnLineSegment(start, end, point)\n\t\t// Uses precomputed dx/dy/len2 and parametric t-clamping instead of Vec allocations.\n\t\tconst { _start: start, _end: end, _dx: dx, _dy: dy, _len2: len2 } = this\n\t\tif (len2 === 0) return start\n\n\t\tconst t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / len2\n\t\tif (t <= 0) return start\n\t\tif (t >= 1) return end\n\t\treturn new Vec(start.x + dx * t, start.y + dy * t)\n\t}\n\n\toverride distanceToPoint(point: VecLike, _hitInside = false): number {\n\t\t// Inlined: Vec.Dist(point, this.nearestPoint(point))\n\t\t// Finds nearest point via parametric t-projection then returns scalar distance directly,\n\t\t// avoiding the Vec allocation that nearestPoint would create.\n\t\tconst { _start: start, _end: end, _dx: dx, _dy: dy, _len2: len2 } = this\n\t\tif (len2 === 0) return Vec.Dist(point, start)\n\n\t\tconst t = ((point.x - start.x) * dx + (point.y - start.y) * dy) / len2\n\t\tlet nx: number, ny: number\n\t\tif (t <= 0) {\n\t\t\tnx = start.x\n\t\t\tny = start.y\n\t\t} else if (t >= 1) {\n\t\t\tnx = end.x\n\t\t\tny = end.y\n\t\t} else {\n\t\t\tnx = start.x + dx * t\n\t\t\tny = start.y + dy * t\n\t\t}\n\t\tconst ex = point.x - nx\n\t\tconst ey = point.y - ny\n\t\treturn Math.sqrt(ex * ex + ey * ey)\n\t}\n\n\tgetSvgPathData(first = true) {\n\t\tconst { _start: start, _end: end } = this\n\t\treturn `${first ? `M${start.toFixed()}` : ``} L${end.toFixed()}`\n\t}\n}\n"], "mappings": "AAAA,SAAS,WAAoB;AAC7B,SAAS,kBAAkB;AAGpB,MAAM,eAAe,WAAW;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,QAAkC;AAC7C,UAAM,EAAE,GAAG,QAAQ,UAAU,OAAO,UAAU,MAAM,CAAC;AACrD,UAAM,EAAE,OAAO,IAAI,IAAI;AAEvB,SAAK,SAAS;AACd,SAAK,OAAO;AAGZ,SAAK,MAAM,IAAI,IAAI,MAAM;AACzB,SAAK,MAAM,IAAI,IAAI,MAAM;AACzB,SAAK,QAAQ,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK;AAAA,EACpD;AAAA,EAES,YAAY;AACpB,WAAO,KAAK,KAAK,KAAK,KAAK;AAAA,EAC5B;AAAA,EAES,cAAqB;AAC7B,WAAO,CAAC,KAAK,QAAQ,KAAK,IAAI;AAAA,EAC/B;AAAA,EAES,aAAa,OAAqB;AAG1C,UAAM,EAAE,QAAQ,OAAO,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,OAAO,KAAK,IAAI;AACpE,QAAI,SAAS,EAAG,QAAO;AAEvB,UAAM,MAAM,MAAM,IAAI,MAAM,KAAK,MAAM,MAAM,IAAI,MAAM,KAAK,MAAM;AAClE,QAAI,KAAK,EAAG,QAAO;AACnB,QAAI,KAAK,EAAG,QAAO;AACnB,WAAO,IAAI,IAAI,MAAM,IAAI,KAAK,GAAG,MAAM,IAAI,KAAK,CAAC;AAAA,EAClD;AAAA,EAES,gBAAgB,OAAgB,aAAa,OAAe;AAIpE,UAAM,EAAE,QAAQ,OAAO,MAAM,KAAK,KAAK,IAAI,KAAK,IAAI,OAAO,KAAK,IAAI;AACpE,QAAI,SAAS,EAAG,QAAO,IAAI,KAAK,OAAO,KAAK;AAE5C,UAAM,MAAM,MAAM,IAAI,MAAM,KAAK,MAAM,MAAM,IAAI,MAAM,KAAK,MAAM;AAClE,QAAI,IAAY;AAChB,QAAI,KAAK,GAAG;AACX,WAAK,MAAM;AACX,WAAK,MAAM;AAAA,IACZ,WAAW,KAAK,GAAG;AAClB,WAAK,IAAI;AACT,WAAK,IAAI;AAAA,IACV,OAAO;AACN,WAAK,MAAM,IAAI,KAAK;AACpB,WAAK,MAAM,IAAI,KAAK;AAAA,IACrB;AACA,UAAM,KAAK,MAAM,IAAI;AACrB,UAAM,KAAK,MAAM,IAAI;AACrB,WAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAAA,EACnC;AAAA,EAEA,eAAe,QAAQ,MAAM;AAC5B,UAAM,EAAE,QAAQ,OAAO,MAAM,IAAI,IAAI;AACrC,WAAO,GAAG,QAAQ,IAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,KAAK,IAAI,QAAQ,CAAC;AAAA,EAC/D;AACD;", "names": [] }