@tldraw/editor 3.12.0-canary.3e2ed74b5e86 → 3.12.0-canary.423f9b4f2a86

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 (48) hide show
  1. package/dist-cjs/index.d.ts +12 -78
  2. package/dist-cjs/index.js +1 -3
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/components/GeometryDebuggingView.js +2 -2
  5. package/dist-cjs/lib/components/GeometryDebuggingView.js.map +2 -2
  6. package/dist-cjs/lib/editor/Editor.js +8 -39
  7. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  8. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +13 -1
  9. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
  10. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +16 -133
  11. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +3 -3
  12. package/dist-cjs/lib/primitives/geometry/Group2d.js +11 -54
  13. package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
  14. package/dist-cjs/lib/primitives/intersect.js +0 -20
  15. package/dist-cjs/lib/primitives/intersect.js.map +2 -2
  16. package/dist-cjs/lib/utils/reorderShapes.js +8 -2
  17. package/dist-cjs/lib/utils/reorderShapes.js.map +2 -2
  18. package/dist-cjs/version.js +3 -3
  19. package/dist-cjs/version.js.map +1 -1
  20. package/dist-esm/index.d.mts +12 -78
  21. package/dist-esm/index.mjs +2 -8
  22. package/dist-esm/index.mjs.map +2 -2
  23. package/dist-esm/lib/components/GeometryDebuggingView.mjs +3 -3
  24. package/dist-esm/lib/components/GeometryDebuggingView.mjs.map +2 -2
  25. package/dist-esm/lib/editor/Editor.mjs +8 -39
  26. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  27. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +13 -1
  28. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
  29. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +14 -137
  30. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  31. package/dist-esm/lib/primitives/geometry/Group2d.mjs +12 -55
  32. package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
  33. package/dist-esm/lib/primitives/intersect.mjs +0 -20
  34. package/dist-esm/lib/primitives/intersect.mjs.map +2 -2
  35. package/dist-esm/lib/utils/reorderShapes.mjs +8 -2
  36. package/dist-esm/lib/utils/reorderShapes.mjs.map +2 -2
  37. package/dist-esm/version.mjs +3 -3
  38. package/dist-esm/version.mjs.map +1 -1
  39. package/package.json +7 -7
  40. package/src/index.ts +1 -6
  41. package/src/lib/components/GeometryDebuggingView.tsx +3 -3
  42. package/src/lib/editor/Editor.ts +15 -44
  43. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +15 -3
  44. package/src/lib/primitives/geometry/Geometry2d.ts +16 -196
  45. package/src/lib/primitives/geometry/Group2d.ts +13 -76
  46. package/src/lib/primitives/intersect.ts +0 -41
  47. package/src/lib/utils/reorderShapes.ts +9 -2
  48. package/src/version.ts +3 -3
@@ -1,8 +1,6 @@
1
- import { EMPTY_ARRAY } from '@tldraw/state'
2
1
  import { Box } from '../Box'
3
- import { Mat } from '../Mat'
4
- import { Vec, VecLike } from '../Vec'
5
- import { Geometry2d, Geometry2dFilters, Geometry2dOptions } from './Geometry2d'
2
+ import { Vec } from '../Vec'
3
+ import { Geometry2d, Geometry2dOptions } from './Geometry2d'
6
4
 
7
5
  /** @public */
8
6
  export class Group2d extends Geometry2d {
@@ -27,14 +25,11 @@ export class Group2d extends Geometry2d {
27
25
  if (this.children.length === 0) throw Error('Group2d must have at least one child')
28
26
  }
29
27
 
30
- override getVertices(filters: Geometry2dFilters): Vec[] {
31
- if (this.isExcludedByFilter(filters)) return []
32
- return this.children
33
- .filter((c) => !c.isExcludedByFilter(filters))
34
- .flatMap((c) => c.getVertices(filters))
28
+ override getVertices(): Vec[] {
29
+ return this.children.filter((c) => !c.isLabel).flatMap((c) => c.vertices)
35
30
  }
36
31
 
37
- override nearestPoint(point: Vec, filters?: Geometry2dFilters): Vec {
32
+ override nearestPoint(point: Vec): Vec {
38
33
  let dist = Infinity
39
34
  let nearest: Vec | undefined
40
35
 
@@ -47,8 +42,7 @@ export class Group2d extends Geometry2d {
47
42
  let p: Vec
48
43
  let d: number
49
44
  for (const child of children) {
50
- if (child.isExcludedByFilter(filters)) continue
51
- p = child.nearestPoint(point, filters)
45
+ p = child.nearestPoint(point)
52
46
  d = Vec.Dist2(p, point)
53
47
  if (d < dist) {
54
48
  dist = d
@@ -59,75 +53,18 @@ export class Group2d extends Geometry2d {
59
53
  return nearest
60
54
  }
61
55
 
62
- override distanceToPoint(point: Vec, hitInside = false, filters?: Geometry2dFilters) {
63
- let smallestDistance = Infinity
64
- for (const child of this.children) {
65
- if (child.isExcludedByFilter(filters)) continue
66
- const distance = child.distanceToPoint(point, hitInside, filters)
67
- if (distance < smallestDistance) {
68
- smallestDistance = distance
69
- }
70
- }
71
- return smallestDistance
56
+ override distanceToPoint(point: Vec, hitInside = false) {
57
+ return Math.min(...this.children.map((c, i) => c.distanceToPoint(point, hitInside || i > 0)))
72
58
  }
73
59
 
74
- override hitTestPoint(
75
- point: Vec,
76
- margin: number,
77
- hitInside: boolean,
78
- filters = Geometry2dFilters.EXCLUDE_LABELS
79
- ): boolean {
60
+ override hitTestPoint(point: Vec, margin: number, hitInside: boolean): boolean {
80
61
  return !!this.children
81
- .filter((c) => !c.isExcludedByFilter(filters))
62
+ .filter((c) => !c.isLabel)
82
63
  .find((c) => c.hitTestPoint(point, margin, hitInside))
83
64
  }
84
65
 
85
- override hitTestLineSegment(
86
- A: Vec,
87
- B: Vec,
88
- zoom: number,
89
- filters = Geometry2dFilters.EXCLUDE_LABELS
90
- ): boolean {
91
- return !!this.children
92
- .filter((c) => !c.isExcludedByFilter(filters))
93
- .find((c) => c.hitTestLineSegment(A, B, zoom))
94
- }
95
-
96
- override intersectLineSegment(A: VecLike, B: VecLike, filters?: Geometry2dFilters) {
97
- return this.children.flatMap((child) => {
98
- if (child.isExcludedByFilter(filters)) return EMPTY_ARRAY
99
- return child.intersectLineSegment(A, B, filters)
100
- })
101
- }
102
-
103
- override intersectCircle(center: VecLike, radius: number, filters?: Geometry2dFilters) {
104
- return this.children.flatMap((child) => {
105
- if (child.isExcludedByFilter(filters)) return EMPTY_ARRAY
106
- return child.intersectCircle(center, radius, filters)
107
- })
108
- }
109
-
110
- override intersectPolygon(polygon: VecLike[], filters?: Geometry2dFilters) {
111
- return this.children.flatMap((child) => {
112
- if (child.isExcludedByFilter(filters)) return EMPTY_ARRAY
113
- return child.intersectPolygon(polygon, filters)
114
- })
115
- }
116
-
117
- override intersectPolyline(polyline: VecLike[], filters?: Geometry2dFilters) {
118
- return this.children.flatMap((child) => {
119
- if (child.isExcludedByFilter(filters)) return EMPTY_ARRAY
120
- return child.intersectPolyline(polyline, filters)
121
- })
122
- }
123
-
124
- override transform(transform: Mat): Geometry2d {
125
- return new Group2d({
126
- children: this.children.map((c) => c.transform(transform)),
127
- isLabel: this.isLabel,
128
- debugColor: this.debugColor,
129
- ignore: this.ignore,
130
- })
66
+ override hitTestLineSegment(A: Vec, B: Vec, zoom: number): boolean {
67
+ return !!this.children.filter((c) => !c.isLabel).find((c) => c.hitTestLineSegment(A, B, zoom))
131
68
  }
132
69
 
133
70
  getArea() {
@@ -165,6 +102,6 @@ export class Group2d extends Geometry2d {
165
102
  }
166
103
 
167
104
  getSvgPathData(): string {
168
- return this.children.map((c, i) => (c.isLabel ? '' : c.getSvgPathData(i === 0))).join(' ')
105
+ return this.children.map((c) => (c.isLabel ? '' : c.getSvgPathData(true))).join(' ')
169
106
  }
170
107
  }
@@ -293,47 +293,6 @@ export function intersectPolygonPolygon(
293
293
  return orderClockwise([...result.values()])
294
294
  }
295
295
 
296
- /**
297
- * Find all the points where `polyA` and `polyB` intersect and returns them in an undefined order.
298
- * To find the polygon that's the intersection of polyA and polyB, use `intersectPolygonPolygon`
299
- * instead, which orders the points and includes internal points.
300
- *
301
- * @param polyA - The first polygon.
302
- * @param polyB - The second polygon.
303
- * @param isAClosed - Whether `polyA` is a closed polygon or a polyline.
304
- * @param isBClosed - Whether `polyB` is a closed polygon or a polyline.
305
- * @public
306
- */
307
- export function intersectPolys(
308
- polyA: VecLike[],
309
- polyB: VecLike[],
310
- isAClosed: boolean,
311
- isBClosed: boolean
312
- ): VecLike[] {
313
- const result: Map<string, VecLike> = new Map()
314
-
315
- // Add all intersection points to result
316
- for (let i = 0, n = isAClosed ? polyA.length : polyA.length - 1; i < n; i++) {
317
- const currentA = polyA[i]
318
- const nextA = polyA[(i + 1) % polyA.length]
319
-
320
- for (let j = 0, m = isBClosed ? polyB.length : polyB.length - 1; j < m; j++) {
321
- const currentB = polyB[j]
322
- const nextB = polyB[(j + 1) % polyB.length]
323
- const intersection = intersectLineSegmentLineSegment(currentA, nextA, currentB, nextB)
324
-
325
- if (intersection !== null) {
326
- const id = getPointId(intersection)
327
- if (!result.has(id)) {
328
- result.set(id, intersection)
329
- }
330
- }
331
- }
332
- }
333
-
334
- return [...result.values()]
335
- }
336
-
337
296
  function getPointId(point: VecLike) {
338
297
  return `${point.x},${point.y}`
339
298
  }
@@ -154,17 +154,24 @@ function reorderToFront(moving: Set<TLShape>, children: TLShape[], changes: TLSh
154
154
  }
155
155
  }
156
156
 
157
+ function getVerticesInPageSpace(editor: Editor, shape: TLShape) {
158
+ const geo = editor.getShapeGeometry(shape)
159
+ const pageTransform = editor.getShapePageTransform(shape)
160
+ if (!geo || !pageTransform) return null
161
+ return pageTransform.applyToPoints(geo.vertices)
162
+ }
163
+
157
164
  function getOverlapChecker(editor: Editor, moving: Set<TLShape>) {
158
165
  const movingVertices = Array.from(moving)
159
166
  .map((shape) => {
160
- const vertices = editor.getShapePageGeometry(shape).vertices
167
+ const vertices = getVerticesInPageSpace(editor, shape)
161
168
  if (!vertices) return null
162
169
  return { shape, vertices }
163
170
  })
164
171
  .filter(Boolean) as { shape: TLShape; vertices: Vec[] }[]
165
172
 
166
173
  const isOverlapping = (child: TLShape) => {
167
- const vertices = editor.getShapePageGeometry(child).vertices
174
+ const vertices = getVerticesInPageSpace(editor, child)
168
175
  if (!vertices) return false
169
176
  return movingVertices.some((other) => {
170
177
  return polygonsIntersect(other.vertices, vertices)
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.12.0-canary.3e2ed74b5e86'
4
+ export const version = '3.12.0-canary.423f9b4f2a86'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-04-03T13:23:30.522Z',
8
- patch: '2025-04-03T13:23:30.522Z',
7
+ minor: '2025-04-03T13:02:18.145Z',
8
+ patch: '2025-04-03T13:02:18.145Z',
9
9
  }