@tldraw/editor 3.13.0-canary.88076103433b → 3.13.0-canary.8e04030e54fe

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist-cjs/index.d.ts +98 -83
  2. package/dist-cjs/index.js +22 -7
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +5 -9
  5. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  6. package/dist-cjs/lib/editor/Editor.js +7 -19
  7. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  8. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +2 -2
  9. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +1 -1
  10. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  11. package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
  12. package/dist-cjs/lib/hooks/useEditorComponents.js +2 -1
  13. package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
  14. package/dist-cjs/lib/primitives/Box.js +0 -16
  15. package/dist-cjs/lib/primitives/Box.js.map +2 -2
  16. package/dist-cjs/lib/primitives/Mat.js +1 -1
  17. package/dist-cjs/lib/primitives/Mat.js.map +2 -2
  18. package/dist-cjs/lib/primitives/Vec.js +0 -20
  19. package/dist-cjs/lib/primitives/Vec.js.map +2 -2
  20. package/dist-cjs/lib/primitives/geometry/Arc2d.js +2 -2
  21. package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
  22. package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
  23. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
  24. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +1 -1
  25. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
  26. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
  27. package/dist-cjs/lib/primitives/geometry/Edge2d.js +1 -1
  28. package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
  29. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
  30. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +20 -91
  31. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  32. package/dist-cjs/lib/primitives/geometry/Group2d.js +2 -55
  33. package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
  34. package/dist-cjs/lib/primitives/geometry/Point2d.js.map +2 -2
  35. package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
  36. package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
  37. package/dist-cjs/lib/utils/debug-flags.js +2 -5
  38. package/dist-cjs/lib/utils/debug-flags.js.map +2 -2
  39. package/dist-cjs/version.js +3 -3
  40. package/dist-cjs/version.js.map +1 -1
  41. package/dist-esm/index.d.mts +98 -83
  42. package/dist-esm/index.mjs +41 -9
  43. package/dist-esm/index.mjs.map +2 -2
  44. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +5 -9
  45. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  46. package/dist-esm/lib/editor/Editor.mjs +7 -19
  47. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  48. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +2 -2
  49. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +1 -1
  50. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  51. package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
  52. package/dist-esm/lib/hooks/useEditorComponents.mjs +4 -1
  53. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
  54. package/dist-esm/lib/primitives/Box.mjs +0 -16
  55. package/dist-esm/lib/primitives/Box.mjs.map +2 -2
  56. package/dist-esm/lib/primitives/Mat.mjs +1 -1
  57. package/dist-esm/lib/primitives/Mat.mjs.map +2 -2
  58. package/dist-esm/lib/primitives/Vec.mjs +0 -20
  59. package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
  60. package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
  61. package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
  62. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -1
  63. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
  64. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +1 -1
  65. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
  66. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
  67. package/dist-esm/lib/primitives/geometry/Edge2d.mjs +1 -1
  68. package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
  69. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
  70. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +21 -92
  71. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  72. package/dist-esm/lib/primitives/geometry/Group2d.mjs +2 -55
  73. package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
  74. package/dist-esm/lib/primitives/geometry/Point2d.mjs.map +2 -2
  75. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
  76. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
  77. package/dist-esm/lib/utils/debug-flags.mjs +2 -5
  78. package/dist-esm/lib/utils/debug-flags.mjs.map +2 -2
  79. package/dist-esm/version.mjs +3 -3
  80. package/dist-esm/version.mjs.map +1 -1
  81. package/editor.css +4 -36
  82. package/package.json +7 -7
  83. package/src/index.ts +31 -16
  84. package/src/lib/components/default-components/DefaultCanvas.tsx +5 -9
  85. package/src/lib/editor/Editor.test.ts +1 -1
  86. package/src/lib/editor/Editor.ts +7 -19
  87. package/src/lib/editor/managers/SnapManager/HandleSnaps.ts +1 -0
  88. package/src/lib/editor/shapes/ShapeUtil.ts +2 -10
  89. package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +9 -9
  90. package/src/lib/hooks/useEditorComponents.tsx +5 -2
  91. package/src/lib/primitives/Box.ts +0 -20
  92. package/src/lib/primitives/Mat.ts +4 -5
  93. package/src/lib/primitives/Vec.ts +0 -23
  94. package/src/lib/primitives/geometry/Arc2d.ts +5 -5
  95. package/src/lib/primitives/geometry/Circle2d.ts +4 -4
  96. package/src/lib/primitives/geometry/CubicBezier2d.ts +4 -4
  97. package/src/lib/primitives/geometry/CubicSpline2d.ts +3 -3
  98. package/src/lib/primitives/geometry/Edge2d.ts +3 -3
  99. package/src/lib/primitives/geometry/Ellipse2d.ts +3 -3
  100. package/src/lib/primitives/geometry/Geometry2d.ts +35 -123
  101. package/src/lib/primitives/geometry/Group2d.ts +7 -70
  102. package/src/lib/primitives/geometry/Point2d.ts +2 -2
  103. package/src/lib/primitives/geometry/Polyline2d.ts +3 -3
  104. package/src/lib/primitives/geometry/Stadium2d.ts +3 -3
  105. package/src/lib/test/currentToolIdMask.test.ts +1 -1
  106. package/src/lib/test/user.test.ts +1 -1
  107. package/src/lib/utils/debug-flags.ts +2 -7
  108. package/src/lib/utils/sync/LocalIndexedDb.test.ts +1 -1
  109. package/src/lib/utils/sync/TLLocalSyncClient.test.ts +1 -1
  110. package/src/version.ts +3 -3
  111. package/src/lib/primitives/geometry/Geometry2d.test.ts +0 -42
@@ -1,4 +1,4 @@
1
- import { assert, invLerp } from '@tldraw/utils'
1
+ import { assert } from '@tldraw/utils'
2
2
  import { Box } from '../Box'
3
3
  import { Mat, MatModel } from '../Mat'
4
4
  import { Vec, VecLike } from '../Vec'
@@ -81,9 +81,9 @@ export abstract class Geometry2d {
81
81
 
82
82
  abstract getVertices(filters: Geometry2dFilters): Vec[]
83
83
 
84
- abstract nearestPoint(point: VecLike, _filters?: Geometry2dFilters): Vec
84
+ abstract nearestPoint(point: Vec, _filters?: Geometry2dFilters): Vec
85
85
 
86
- hitTestPoint(point: VecLike, margin = 0, hitInside = false, _filters?: Geometry2dFilters) {
86
+ hitTestPoint(point: Vec, margin = 0, hitInside = false, _filters?: Geometry2dFilters) {
87
87
  // First check whether the point is inside
88
88
  if (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) {
89
89
  return true
@@ -92,17 +92,17 @@ export abstract class Geometry2d {
92
92
  return Vec.Dist2(point, this.nearestPoint(point)) <= margin * margin
93
93
  }
94
94
 
95
- distanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {
95
+ distanceToPoint(point: Vec, hitInside = false, filters?: Geometry2dFilters) {
96
96
  return (
97
- Vec.Dist(point, this.nearestPoint(point, filters)) *
97
+ point.dist(this.nearestPoint(point, filters)) *
98
98
  (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)
99
99
  ? -1
100
100
  : 1)
101
101
  )
102
102
  }
103
103
 
104
- distanceToLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {
105
- if (Vec.Equals(A, B)) return this.distanceToPoint(A, false, filters)
104
+ distanceToLineSegment(A: Vec, B: Vec, filters?: Geometry2dFilters) {
105
+ if (A.equals(B)) return this.distanceToPoint(A, false, filters)
106
106
  const { vertices } = this
107
107
  let nearest: Vec | undefined
108
108
  let dist = Infinity
@@ -120,7 +120,7 @@ export abstract class Geometry2d {
120
120
  return this.isClosed && this.isFilled && pointInPolygon(nearest, this.vertices) ? -dist : dist
121
121
  }
122
122
 
123
- hitTestLineSegment(A: VecLike, B: VecLike, distance = 0, filters?: Geometry2dFilters): boolean {
123
+ hitTestLineSegment(A: Vec, B: Vec, distance = 0, filters?: Geometry2dFilters): boolean {
124
124
  return this.distanceToLineSegment(A, B, filters) <= distance
125
125
  }
126
126
 
@@ -148,76 +148,8 @@ export abstract class Geometry2d {
148
148
  return intersectPolys(polyline, this.vertices, false, this.isClosed)
149
149
  }
150
150
 
151
- /**
152
- * Find a point along the edge of the geometry that is a fraction `t` along the entire way round.
153
- */
154
- interpolateAlongEdge(t: number, _filters?: Geometry2dFilters): Vec {
155
- const { vertices } = this
156
-
157
- if (t <= 0) return vertices[0]
158
-
159
- const distanceToTravel = t * this.length
160
- let distanceTraveled = 0
161
-
162
- for (let i = 0; i < (this.isClosed ? vertices.length : vertices.length - 1); i++) {
163
- const curr = vertices[i]
164
- const next = vertices[(i + 1) % vertices.length]
165
- const dist = Vec.Dist(curr, next)
166
- const newDistanceTraveled = distanceTraveled + dist
167
- if (newDistanceTraveled >= distanceToTravel) {
168
- const p = Vec.Lrp(
169
- curr,
170
- next,
171
- invLerp(distanceTraveled, newDistanceTraveled, distanceToTravel)
172
- )
173
- return p
174
- }
175
- distanceTraveled = newDistanceTraveled
176
- }
177
-
178
- return this.isClosed ? vertices[0] : vertices[vertices.length - 1]
179
- }
180
-
181
- /**
182
- * Take `point`, find the closest point to it on the edge of the geometry, and return how far
183
- * along the edge it is as a fraction of the total length.
184
- */
185
- uninterpolateAlongEdge(point: VecLike, _filters?: Geometry2dFilters): number {
186
- const { vertices, length } = this
187
- let closestSegment = null
188
- let closestDistance = Infinity
189
- let distanceTraveled = 0
190
-
191
- for (let i = 0; i < (this.isClosed ? vertices.length : vertices.length - 1); i++) {
192
- const curr = vertices[i]
193
- const next = vertices[(i + 1) % vertices.length]
194
-
195
- const nearestPoint = Vec.NearestPointOnLineSegment(curr, next, point, true)
196
- const distance = Vec.Dist(nearestPoint, point)
197
-
198
- if (distance < closestDistance) {
199
- closestDistance = distance
200
- closestSegment = {
201
- start: curr,
202
- end: next,
203
- nearestPoint,
204
- distanceToStart: distanceTraveled,
205
- }
206
- }
207
-
208
- distanceTraveled += Vec.Dist(curr, next)
209
- }
210
-
211
- assert(closestSegment)
212
-
213
- const distanceAlongRoute =
214
- closestSegment.distanceToStart + Vec.Dist(closestSegment.start, closestSegment.nearestPoint)
215
-
216
- return distanceAlongRoute / length
217
- }
218
-
219
151
  /** @deprecated Iterate the vertices instead. */
220
- nearestPointOnLineSegment(A: VecLike, B: VecLike): Vec {
152
+ nearestPointOnLineSegment(A: Vec, B: Vec): Vec {
221
153
  const { vertices } = this
222
154
  let nearest: Vec | undefined
223
155
  let dist = Infinity
@@ -235,7 +167,7 @@ export abstract class Geometry2d {
235
167
  return nearest
236
168
  }
237
169
 
238
- isPointInBounds(point: VecLike, margin = 0) {
170
+ isPointInBounds(point: Vec, margin = 0) {
239
171
  const { bounds } = this
240
172
  return !(
241
173
  point.x < bounds.minX - margin ||
@@ -329,24 +261,21 @@ export abstract class Geometry2d {
329
261
  // eslint-disable-next-line no-restricted-syntax
330
262
  get length() {
331
263
  if (this._length) return this._length
332
- this._length = this.getLength(Geometry2dFilters.EXCLUDE_LABELS)
264
+ this._length = this.getLength()
333
265
  return this._length
334
266
  }
335
267
 
336
- getLength(_filters?: Geometry2dFilters) {
337
- const vertices = this.getVertices(_filters ?? Geometry2dFilters.EXCLUDE_LABELS)
338
- if (vertices.length === 0) return 0
339
- let prev = vertices[0]
340
- let length = 0
268
+ getLength() {
269
+ const { vertices } = this
270
+ let n1: Vec,
271
+ p1 = vertices[0],
272
+ length = 0
341
273
  for (let i = 1; i < vertices.length; i++) {
342
- const next = vertices[i]
343
- length += Vec.Dist(prev, next)
344
- prev = next
345
- }
346
- if (this.isClosed) {
347
- length += Vec.Dist(vertices[vertices.length - 1], vertices[0])
274
+ n1 = vertices[i]
275
+ length += Vec.Dist2(p1, n1)
276
+ p1 = n1
348
277
  }
349
- return length
278
+ return Math.sqrt(length)
350
279
  }
351
280
 
352
281
  abstract getSvgPathData(first: boolean): string
@@ -388,7 +317,7 @@ export class TransformedGeometry2d extends Geometry2d {
388
317
  return this.geometry.getVertices(filters).map((v) => Mat.applyToPoint(this.matrix, v))
389
318
  }
390
319
 
391
- nearestPoint(point: VecLike, filters?: Geometry2dFilters): Vec {
320
+ nearestPoint(point: Vec, filters?: Geometry2dFilters): Vec {
392
321
  return Mat.applyToPoint(
393
322
  this.matrix,
394
323
  this.geometry.nearestPoint(Mat.applyToPoint(this.inverse, point), filters)
@@ -396,7 +325,7 @@ export class TransformedGeometry2d extends Geometry2d {
396
325
  }
397
326
 
398
327
  override hitTestPoint(
399
- point: VecLike,
328
+ point: Vec,
400
329
  margin = 0,
401
330
  hitInside?: boolean,
402
331
  filters?: Geometry2dFilters
@@ -409,14 +338,14 @@ export class TransformedGeometry2d extends Geometry2d {
409
338
  )
410
339
  }
411
340
 
412
- override distanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {
341
+ override distanceToPoint(point: Vec, hitInside = false, filters?: Geometry2dFilters) {
413
342
  return (
414
343
  this.geometry.distanceToPoint(Mat.applyToPoint(this.inverse, point), hitInside, filters) *
415
344
  this.decomposed.scaleX
416
345
  )
417
346
  }
418
347
 
419
- override distanceToLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {
348
+ override distanceToLineSegment(A: Vec, B: Vec, filters?: Geometry2dFilters) {
420
349
  return (
421
350
  this.geometry.distanceToLineSegment(
422
351
  Mat.applyToPoint(this.inverse, A),
@@ -426,12 +355,7 @@ export class TransformedGeometry2d extends Geometry2d {
426
355
  )
427
356
  }
428
357
 
429
- override hitTestLineSegment(
430
- A: VecLike,
431
- B: VecLike,
432
- distance = 0,
433
- filters?: Geometry2dFilters
434
- ): boolean {
358
+ override hitTestLineSegment(A: Vec, B: Vec, distance = 0, filters?: Geometry2dFilters): boolean {
435
359
  return this.geometry.hitTestLineSegment(
436
360
  Mat.applyToPoint(this.inverse, A),
437
361
  Mat.applyToPoint(this.inverse, B),
@@ -441,39 +365,27 @@ export class TransformedGeometry2d extends Geometry2d {
441
365
  }
442
366
 
443
367
  override intersectLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {
444
- return Mat.applyToPoints(
445
- this.matrix,
446
- this.geometry.intersectLineSegment(
447
- Mat.applyToPoint(this.inverse, A),
448
- Mat.applyToPoint(this.inverse, B),
449
- filters
450
- )
368
+ return this.geometry.intersectLineSegment(
369
+ Mat.applyToPoint(this.inverse, A),
370
+ Mat.applyToPoint(this.inverse, B),
371
+ filters
451
372
  )
452
373
  }
453
374
 
454
375
  override intersectCircle(center: VecLike, radius: number, filters?: Geometry2dFilters) {
455
- return Mat.applyToPoints(
456
- this.matrix,
457
- this.geometry.intersectCircle(
458
- Mat.applyToPoint(this.inverse, center),
459
- radius / this.decomposed.scaleX,
460
- filters
461
- )
376
+ return this.geometry.intersectCircle(
377
+ Mat.applyToPoint(this.inverse, center),
378
+ radius / this.decomposed.scaleX,
379
+ filters
462
380
  )
463
381
  }
464
382
 
465
383
  override intersectPolygon(polygon: VecLike[], filters?: Geometry2dFilters): VecLike[] {
466
- return Mat.applyToPoints(
467
- this.matrix,
468
- this.geometry.intersectPolygon(Mat.applyToPoints(this.inverse, polygon), filters)
469
- )
384
+ return this.geometry.intersectPolygon(Mat.applyToPoints(this.inverse, polygon), filters)
470
385
  }
471
386
 
472
387
  override intersectPolyline(polyline: VecLike[], filters?: Geometry2dFilters): VecLike[] {
473
- return Mat.applyToPoints(
474
- this.matrix,
475
- this.geometry.intersectPolyline(Mat.applyToPoints(this.inverse, polyline), filters)
476
- )
388
+ return this.geometry.intersectPolyline(Mat.applyToPoints(this.inverse, polyline), filters)
477
389
  }
478
390
 
479
391
  override transform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d {
@@ -1,5 +1,4 @@
1
1
  import { EMPTY_ARRAY } from '@tldraw/state'
2
- import { assert, invLerp, lerp } from '@tldraw/utils'
3
2
  import { Box } from '../Box'
4
3
  import { Mat } from '../Mat'
5
4
  import { Vec, VecLike } from '../Vec'
@@ -35,7 +34,7 @@ export class Group2d extends Geometry2d {
35
34
  .flatMap((c) => c.getVertices(filters))
36
35
  }
37
36
 
38
- override nearestPoint(point: VecLike, filters?: Geometry2dFilters): Vec {
37
+ override nearestPoint(point: Vec, filters?: Geometry2dFilters): Vec {
39
38
  let dist = Infinity
40
39
  let nearest: Vec | undefined
41
40
 
@@ -60,7 +59,7 @@ export class Group2d extends Geometry2d {
60
59
  return nearest
61
60
  }
62
61
 
63
- override distanceToPoint(point: VecLike, hitInside = false, filters?: Geometry2dFilters) {
62
+ override distanceToPoint(point: Vec, hitInside = false, filters?: Geometry2dFilters) {
64
63
  let smallestDistance = Infinity
65
64
  for (const child of this.children) {
66
65
  if (child.isExcludedByFilter(filters)) continue
@@ -73,7 +72,7 @@ export class Group2d extends Geometry2d {
73
72
  }
74
73
 
75
74
  override hitTestPoint(
76
- point: VecLike,
75
+ point: Vec,
77
76
  margin: number,
78
77
  hitInside: boolean,
79
78
  filters = Geometry2dFilters.EXCLUDE_LABELS
@@ -84,8 +83,8 @@ export class Group2d extends Geometry2d {
84
83
  }
85
84
 
86
85
  override hitTestLineSegment(
87
- A: VecLike,
88
- B: VecLike,
86
+ A: Vec,
87
+ B: Vec,
89
88
  zoom: number,
90
89
  filters = Geometry2dFilters.EXCLUDE_LABELS
91
90
  ): boolean {
@@ -122,63 +121,6 @@ export class Group2d extends Geometry2d {
122
121
  })
123
122
  }
124
123
 
125
- override interpolateAlongEdge(t: number, filters?: Geometry2dFilters): Vec {
126
- const totalLength = this.getLength(filters)
127
-
128
- const distanceToTravel = t * totalLength
129
- let distanceTraveled = 0
130
- for (const child of this.children) {
131
- if (child.isExcludedByFilter(filters)) continue
132
- const childLength = child.length
133
- const newDistanceTraveled = distanceTraveled + childLength
134
- if (newDistanceTraveled >= distanceToTravel) {
135
- return child.interpolateAlongEdge(
136
- invLerp(distanceTraveled, newDistanceTraveled, distanceToTravel),
137
- filters
138
- )
139
- }
140
- distanceTraveled = newDistanceTraveled
141
- }
142
-
143
- return this.children[this.children.length - 1].interpolateAlongEdge(1, filters)
144
- }
145
-
146
- override uninterpolateAlongEdge(point: VecLike, filters?: Geometry2dFilters): number {
147
- const totalLength = this.getLength(filters)
148
-
149
- let closestChild = null
150
- let closestDistance = Infinity
151
- let distanceTraveled = 0
152
-
153
- for (const child of this.children) {
154
- if (child.isExcludedByFilter(filters)) continue
155
- const childLength = child.getLength(filters)
156
- const newDistanceTraveled = distanceTraveled + childLength
157
-
158
- const distance = child.distanceToPoint(point, false, filters)
159
- if (distance < closestDistance) {
160
- closestDistance = distance
161
- closestChild = {
162
- startLength: distanceTraveled,
163
- endLength: newDistanceTraveled,
164
- child,
165
- }
166
- }
167
-
168
- distanceTraveled = newDistanceTraveled
169
- }
170
-
171
- assert(closestChild)
172
-
173
- const normalizedDistanceInChild = closestChild.child.uninterpolateAlongEdge(point, filters)
174
- const childTLength = lerp(
175
- closestChild.startLength,
176
- closestChild.endLength,
177
- normalizedDistanceInChild
178
- )
179
- return childTLength / totalLength
180
- }
181
-
182
124
  override transform(transform: Mat): Geometry2d {
183
125
  return new Group2d({
184
126
  children: this.children.map((c) => c.transform(transform)),
@@ -218,13 +160,8 @@ export class Group2d extends Geometry2d {
218
160
  return path
219
161
  }
220
162
 
221
- getLength(filters?: Geometry2dFilters): number {
222
- let length = 0
223
- for (const child of this.children) {
224
- if (child.isExcludedByFilter(filters)) continue
225
- length += child.length
226
- }
227
- return length
163
+ getLength(): number {
164
+ return this.children.reduce((a, c) => (c.isLabel ? a : a + c.length), 0)
228
165
  }
229
166
 
230
167
  getSvgPathData(): string {
@@ -1,4 +1,4 @@
1
- import { Vec, VecLike } from '../Vec'
1
+ import { Vec } from '../Vec'
2
2
  import { Geometry2d, Geometry2dOptions } from './Geometry2d'
3
3
 
4
4
  /** @public */
@@ -22,7 +22,7 @@ export class Point2d extends Geometry2d {
22
22
  return this.point
23
23
  }
24
24
 
25
- hitTestLineSegment(A: VecLike, B: VecLike, margin: number): boolean {
25
+ hitTestLineSegment(A: Vec, B: Vec, margin: number): boolean {
26
26
  return Vec.DistanceToLineSegment(A, B, this.point) < margin
27
27
  }
28
28
 
@@ -1,4 +1,4 @@
1
- import { Vec, VecLike } from '../Vec'
1
+ import { Vec } from '../Vec'
2
2
  import { Edge2d } from './Edge2d'
3
3
  import { Geometry2d, Geometry2dOptions } from './Geometry2d'
4
4
 
@@ -41,7 +41,7 @@ export class Polyline2d extends Geometry2d {
41
41
  return this.points
42
42
  }
43
43
 
44
- nearestPoint(A: VecLike): Vec {
44
+ nearestPoint(A: Vec): Vec {
45
45
  const { segments } = this
46
46
  let nearest = this.points[0]
47
47
  let dist = Infinity
@@ -59,7 +59,7 @@ export class Polyline2d extends Geometry2d {
59
59
  return nearest
60
60
  }
61
61
 
62
- hitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {
62
+ hitTestLineSegment(A: Vec, B: Vec, distance = 0): boolean {
63
63
  const { segments } = this
64
64
  for (let i = 0, n = segments.length; i < n; i++) {
65
65
  if (segments[i].hitTestLineSegment(A, B, distance)) {
@@ -1,5 +1,5 @@
1
1
  import { Box } from '../Box'
2
- import { Vec, VecLike } from '../Vec'
2
+ import { Vec } from '../Vec'
3
3
  import { PI } from '../utils'
4
4
  import { Arc2d } from './Arc2d'
5
5
  import { Edge2d } from './Edge2d'
@@ -65,7 +65,7 @@ export class Stadium2d extends Geometry2d {
65
65
  }
66
66
  }
67
67
 
68
- nearestPoint(A: VecLike): Vec {
68
+ nearestPoint(A: Vec): Vec {
69
69
  let nearest: Vec | undefined
70
70
  let dist = Infinity
71
71
  let _d: number
@@ -84,7 +84,7 @@ export class Stadium2d extends Geometry2d {
84
84
  return nearest
85
85
  }
86
86
 
87
- hitTestLineSegment(A: VecLike, B: VecLike): boolean {
87
+ hitTestLineSegment(A: Vec, B: Vec): boolean {
88
88
  const { a, b, c, d } = this
89
89
  return [a, b, c, d].some((edge) => edge.hitTestLineSegment(A, B))
90
90
  }
@@ -27,7 +27,7 @@ beforeEach(() => {
27
27
  shapeUtils: [],
28
28
  bindingUtils: [],
29
29
  tools: [A, B, C],
30
- store: createTLStore({ shapeUtils: [], bindingUtils: [] }),
30
+ store: createTLStore({ shapeUtils: [] }),
31
31
  getContainer: () => document.body,
32
32
  })
33
33
  })
@@ -8,7 +8,7 @@ beforeEach(() => {
8
8
  shapeUtils: [],
9
9
  bindingUtils: [],
10
10
  tools: [],
11
- store: createTLStore({ shapeUtils: [], bindingUtils: [] }),
11
+ store: createTLStore({ shapeUtils: [] }),
12
12
  getContainer: () => document.body,
13
13
  })
14
14
  })
@@ -54,7 +54,6 @@ export const debugFlags = {
54
54
  hideShapes: createDebugValue('hideShapes', { defaults: { all: false } }),
55
55
  editOnType: createDebugValue('editOnType', { defaults: { all: false } }),
56
56
  a11y: createDebugValue('a11y', { defaults: { all: false } }),
57
- debugElbowArrows: createDebugValue('debugElbowArrows', { defaults: { all: false } }),
58
57
  } as const
59
58
 
60
59
  declare global {
@@ -150,9 +149,7 @@ function createDebugValueBase<T>(def: DebugFlagDef<T>): DebugFlag<T> {
150
149
  })
151
150
  }
152
151
 
153
- return Object.assign(valueAtom, def, {
154
- reset: () => valueAtom.set(defaultValue),
155
- })
152
+ return Object.assign(valueAtom, def)
156
153
  }
157
154
 
158
155
  function getStoredInitialValue(name: string) {
@@ -209,6 +206,4 @@ export interface DebugFlagDef<T> {
209
206
  }
210
207
 
211
208
  /** @internal */
212
- export interface DebugFlag<T> extends DebugFlagDef<T>, Atom<T> {
213
- reset(): void
214
- }
209
+ export type DebugFlag<T> = DebugFlagDef<T> & Atom<T>
@@ -3,7 +3,7 @@ import { openDB } from 'idb'
3
3
  import { hardReset } from './hardReset'
4
4
  import { getAllIndexDbNames, LocalIndexedDb } from './LocalIndexedDb'
5
5
 
6
- const schema = createTLSchema({ shapes: {}, bindings: {} })
6
+ const schema = createTLSchema({ shapes: {} })
7
7
  describe('LocalIndexedDb', () => {
8
8
  beforeEach(() => {
9
9
  jest.useRealTimers()
@@ -19,7 +19,7 @@ class BroadcastChannelMock {
19
19
  }
20
20
 
21
21
  function testClient(channel = new BroadcastChannelMock('test')) {
22
- const store = createTLStore({ shapeUtils: [], bindingUtils: [] })
22
+ const store = createTLStore({ shapeUtils: [] })
23
23
  const onLoad = jest.fn(() => {
24
24
  return
25
25
  })
package/src/version.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '3.13.0-canary.88076103433b'
4
+ export const version = '3.13.0-canary.8e04030e54fe'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-05-12T13:37:28.205Z',
8
- patch: '2025-05-12T13:37:28.205Z',
7
+ minor: '2025-05-07T09:08:57.011Z',
8
+ patch: '2025-05-07T09:08:57.011Z',
9
9
  }
@@ -1,42 +0,0 @@
1
- import { Mat } from '../Mat'
2
- import { Vec, VecLike } from '../Vec'
3
- import { Geometry2dFilters } from './Geometry2d'
4
- import { Rectangle2d } from './Rectangle2d'
5
-
6
- describe('TransformedGeometry2d', () => {
7
- const rect = new Rectangle2d({ width: 100, height: 50, isFilled: true }).transform(
8
- Mat.Translate(50, 100).scale(2, 2)
9
- )
10
-
11
- test('getVertices', () => {
12
- expect(rect.getVertices(Geometry2dFilters.INCLUDE_ALL)).toMatchObject([
13
- { x: 50, y: 100, z: 1 },
14
- { x: 250, y: 100, z: 1 },
15
- { x: 250, y: 200, z: 1 },
16
- { x: 50, y: 200, z: 1 },
17
- ])
18
- })
19
-
20
- test('nearestPoint', () => {
21
- expectApproxMatch(rect.nearestPoint(new Vec(100, 300)), { x: 100, y: 200 })
22
- })
23
-
24
- test('hitTestPoint', () => {
25
- // basic case - no margin / scaling:
26
- expect(rect.hitTestPoint(new Vec(0, 0), 0, true)).toBe(false)
27
- expect(rect.hitTestPoint(new Vec(50, 100), 0, true)).toBe(true)
28
- expect(rect.hitTestPoint(new Vec(49, 100), 0, true)).toBe(false)
29
- expect(rect.hitTestPoint(new Vec(100, 150), 0, true)).toBe(true)
30
-
31
- // with margin:
32
- // move away 8 px and test with 10px margin:
33
- expect(rect.hitTestPoint(new Vec(42, 100), 10, true)).toBe(true)
34
- // move away 12 px and test with 10px margin:
35
- expect(rect.hitTestPoint(new Vec(38, 100), 10, true)).toBe(false)
36
- })
37
- })
38
-
39
- function expectApproxMatch(a: VecLike, b: VecLike) {
40
- expect(a.x).toBeCloseTo(b.x, 0.0001)
41
- expect(a.y).toBeCloseTo(b.y, 0.0001)
42
- }