@tldraw/editor 3.16.0-canary.c7d3f7d5729d → 3.16.0-canary.ca33603d9bda
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.
- package/dist-cjs/index.d.ts +3 -101
- package/dist-cjs/index.js +1 -5
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +0 -4
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +3 -99
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
- package/dist-cjs/lib/primitives/Vec.js +0 -4
- package/dist-cjs/lib/primitives/Vec.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +26 -18
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Group2d.js +3 -0
- package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js +2 -35
- package/dist-cjs/lib/utils/reparenting.js.map +3 -3
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +3 -101
- package/dist-esm/index.mjs +1 -5
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +0 -4
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +3 -99
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/primitives/Vec.mjs +0 -4
- package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +29 -19
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Group2d.mjs +3 -0
- package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs +3 -40
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +0 -9
- package/src/lib/TldrawEditor.tsx +0 -11
- package/src/lib/editor/Editor.ts +1 -125
- package/src/lib/editor/types/misc-types.ts +0 -6
- package/src/lib/primitives/Vec.ts +0 -5
- package/src/lib/primitives/geometry/Geometry2d.ts +49 -19
- package/src/lib/primitives/geometry/Group2d.ts +4 -0
- package/src/lib/utils/reparenting.ts +3 -69
- package/src/version.ts +3 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/editor",
|
|
3
3
|
"description": "tldraw infinite canvas SDK (editor).",
|
|
4
|
-
"version": "3.16.0-canary.
|
|
4
|
+
"version": "3.16.0-canary.ca33603d9bda",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"@tiptap/core": "^2.9.1",
|
|
51
51
|
"@tiptap/pm": "^2.9.1",
|
|
52
52
|
"@tiptap/react": "^2.9.1",
|
|
53
|
-
"@tldraw/state": "3.16.0-canary.
|
|
54
|
-
"@tldraw/state-react": "3.16.0-canary.
|
|
55
|
-
"@tldraw/store": "3.16.0-canary.
|
|
56
|
-
"@tldraw/tlschema": "3.16.0-canary.
|
|
57
|
-
"@tldraw/utils": "3.16.0-canary.
|
|
58
|
-
"@tldraw/validate": "3.16.0-canary.
|
|
53
|
+
"@tldraw/state": "3.16.0-canary.ca33603d9bda",
|
|
54
|
+
"@tldraw/state-react": "3.16.0-canary.ca33603d9bda",
|
|
55
|
+
"@tldraw/store": "3.16.0-canary.ca33603d9bda",
|
|
56
|
+
"@tldraw/tlschema": "3.16.0-canary.ca33603d9bda",
|
|
57
|
+
"@tldraw/utils": "3.16.0-canary.ca33603d9bda",
|
|
58
|
+
"@tldraw/validate": "3.16.0-canary.ca33603d9bda",
|
|
59
59
|
"@types/core-js": "^2.5.8",
|
|
60
60
|
"@use-gesture/react": "^10.3.1",
|
|
61
61
|
"classnames": "^2.5.1",
|
package/src/index.ts
CHANGED
|
@@ -268,7 +268,6 @@ export {
|
|
|
268
268
|
type TLGetShapeAtPointOptions,
|
|
269
269
|
type TLImageExportOptions,
|
|
270
270
|
type TLSvgExportOptions,
|
|
271
|
-
type TLSvgOptions,
|
|
272
271
|
type TLUpdatePointerOptions,
|
|
273
272
|
} from './lib/editor/types/misc-types'
|
|
274
273
|
export {
|
|
@@ -486,14 +485,6 @@ export { type TLStoreWithStatus } from './lib/utils/sync/StoreWithStatus'
|
|
|
486
485
|
export { uniq } from './lib/utils/uniq'
|
|
487
486
|
export { openWindow } from './lib/utils/window-open'
|
|
488
487
|
|
|
489
|
-
/**
|
|
490
|
-
* @deprecated Licensing is now enabled in the tldraw SDK.
|
|
491
|
-
* @public */
|
|
492
|
-
export function debugEnableLicensing() {
|
|
493
|
-
// noop
|
|
494
|
-
return
|
|
495
|
-
}
|
|
496
|
-
|
|
497
488
|
registerTldrawLibraryVersion(
|
|
498
489
|
(globalThis as any).TLDRAW_LIBRARY_NAME,
|
|
499
490
|
(globalThis as any).TLDRAW_LIBRARY_VERSION,
|
package/src/lib/TldrawEditor.tsx
CHANGED
|
@@ -189,13 +189,6 @@ export interface TldrawEditorBaseProps {
|
|
|
189
189
|
*/
|
|
190
190
|
deepLinks?: true | TLDeepLinkOptions
|
|
191
191
|
|
|
192
|
-
/**
|
|
193
|
-
* Predicate for whether or not a shape should be hidden.
|
|
194
|
-
*
|
|
195
|
-
* @deprecated Use {@link TldrawEditorBaseProps#getShapeVisibility} instead.
|
|
196
|
-
*/
|
|
197
|
-
isShapeHidden?(shape: TLShape, editor: Editor): boolean
|
|
198
|
-
|
|
199
192
|
/**
|
|
200
193
|
* Provides a way to hide shapes.
|
|
201
194
|
*
|
|
@@ -412,8 +405,6 @@ function TldrawEditorWithReadyStore({
|
|
|
412
405
|
options,
|
|
413
406
|
licenseKey,
|
|
414
407
|
deepLinks: _deepLinks,
|
|
415
|
-
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
416
|
-
isShapeHidden,
|
|
417
408
|
getShapeVisibility,
|
|
418
409
|
assetUrls,
|
|
419
410
|
}: Required<
|
|
@@ -473,7 +464,6 @@ function TldrawEditorWithReadyStore({
|
|
|
473
464
|
textOptions,
|
|
474
465
|
options,
|
|
475
466
|
licenseKey,
|
|
476
|
-
isShapeHidden,
|
|
477
467
|
getShapeVisibility,
|
|
478
468
|
fontAssetUrls: assetUrls?.fonts,
|
|
479
469
|
})
|
|
@@ -509,7 +499,6 @@ function TldrawEditorWithReadyStore({
|
|
|
509
499
|
user,
|
|
510
500
|
setEditor,
|
|
511
501
|
licenseKey,
|
|
512
|
-
isShapeHidden,
|
|
513
502
|
getShapeVisibility,
|
|
514
503
|
textOptions,
|
|
515
504
|
assetUrls,
|
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -116,7 +116,6 @@ import {
|
|
|
116
116
|
} from '../constants'
|
|
117
117
|
import { exportToSvg } from '../exports/exportToSvg'
|
|
118
118
|
import { getSvgAsImage } from '../exports/getSvgAsImage'
|
|
119
|
-
import { tlenv } from '../globals/environment'
|
|
120
119
|
import { tlmenus } from '../globals/menus'
|
|
121
120
|
import { tltime } from '../globals/time'
|
|
122
121
|
import { TldrawOptions, defaultTldrawOptions } from '../options'
|
|
@@ -244,16 +243,6 @@ export interface TLEditorOptions {
|
|
|
244
243
|
options?: Partial<TldrawOptions>
|
|
245
244
|
licenseKey?: string
|
|
246
245
|
fontAssetUrls?: { [key: string]: string | undefined }
|
|
247
|
-
/**
|
|
248
|
-
* A predicate that should return true if the given shape should be hidden.
|
|
249
|
-
*
|
|
250
|
-
* @deprecated Use {@link Editor#getShapeVisibility} instead.
|
|
251
|
-
*
|
|
252
|
-
* @param shape - The shape to check.
|
|
253
|
-
* @param editor - The editor instance.
|
|
254
|
-
*/
|
|
255
|
-
isShapeHidden?(shape: TLShape, editor: Editor): boolean
|
|
256
|
-
|
|
257
246
|
/**
|
|
258
247
|
* Provides a way to hide shapes.
|
|
259
248
|
*
|
|
@@ -309,21 +298,12 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
309
298
|
autoFocus,
|
|
310
299
|
inferDarkMode,
|
|
311
300
|
options,
|
|
312
|
-
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
313
|
-
isShapeHidden,
|
|
314
301
|
getShapeVisibility,
|
|
315
302
|
fontAssetUrls,
|
|
316
303
|
}: TLEditorOptions) {
|
|
317
304
|
super()
|
|
318
|
-
assert(
|
|
319
|
-
!(isShapeHidden && getShapeVisibility),
|
|
320
|
-
'Cannot use both isShapeHidden and getShapeVisibility'
|
|
321
|
-
)
|
|
322
305
|
|
|
323
|
-
this._getShapeVisibility =
|
|
324
|
-
? // eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
325
|
-
(shape: TLShape, editor: Editor) => (isShapeHidden(shape, editor) ? 'hidden' : 'inherit')
|
|
326
|
-
: getShapeVisibility
|
|
306
|
+
this._getShapeVisibility = getShapeVisibility
|
|
327
307
|
|
|
328
308
|
this.options = { ...defaultTldrawOptions, ...options }
|
|
329
309
|
|
|
@@ -907,14 +887,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
907
887
|
*/
|
|
908
888
|
readonly fonts: FontManager
|
|
909
889
|
|
|
910
|
-
/**
|
|
911
|
-
* A manager for the editor's environment.
|
|
912
|
-
*
|
|
913
|
-
* @deprecated This is deprecated and will be removed in a future version. Use the `tlenv` global export instead.
|
|
914
|
-
* @public
|
|
915
|
-
*/
|
|
916
|
-
readonly environment = tlenv
|
|
917
|
-
|
|
918
890
|
/**
|
|
919
891
|
* A manager for the editor's scribbles.
|
|
920
892
|
*
|
|
@@ -1119,35 +1091,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1119
1091
|
return this.history.getNumRedos() > 0
|
|
1120
1092
|
}
|
|
1121
1093
|
|
|
1122
|
-
/**
|
|
1123
|
-
* Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear
|
|
1124
|
-
* any redos.
|
|
1125
|
-
*
|
|
1126
|
-
* @example
|
|
1127
|
-
* ```ts
|
|
1128
|
-
* editor.mark()
|
|
1129
|
-
* editor.mark('flip shapes')
|
|
1130
|
-
* ```
|
|
1131
|
-
*
|
|
1132
|
-
* @param markId - The mark's id, usually the reason for adding the mark.
|
|
1133
|
-
*
|
|
1134
|
-
* @public
|
|
1135
|
-
* @deprecated use {@link Editor.markHistoryStoppingPoint} instead
|
|
1136
|
-
*/
|
|
1137
|
-
mark(markId?: string): this {
|
|
1138
|
-
if (typeof markId === 'string') {
|
|
1139
|
-
console.warn(
|
|
1140
|
-
`[tldraw] \`editor.history.mark("${markId}")\` is deprecated. Please use \`const myMarkId = editor.markHistoryStoppingPoint()\` instead.`
|
|
1141
|
-
)
|
|
1142
|
-
} else {
|
|
1143
|
-
console.warn(
|
|
1144
|
-
'[tldraw] `editor.mark()` is deprecated. Use `editor.markHistoryStoppingPoint()` instead.'
|
|
1145
|
-
)
|
|
1146
|
-
}
|
|
1147
|
-
this.history._mark(markId ?? uniqueId())
|
|
1148
|
-
return this
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
1094
|
/**
|
|
1152
1095
|
* Create a new "mark", or stopping point, in the undo redo history. Creating a mark will clear
|
|
1153
1096
|
* any redos. You typically want to do this just before a user interaction begins or is handled.
|
|
@@ -1272,13 +1215,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1272
1215
|
return this
|
|
1273
1216
|
}
|
|
1274
1217
|
|
|
1275
|
-
/**
|
|
1276
|
-
* @deprecated Use `Editor.run` instead.
|
|
1277
|
-
*/
|
|
1278
|
-
batch(fn: () => void, opts?: TLEditorRunOptions): this {
|
|
1279
|
-
return this.run(fn, opts)
|
|
1280
|
-
}
|
|
1281
|
-
|
|
1282
1218
|
/* --------------------- Errors --------------------- */
|
|
1283
1219
|
|
|
1284
1220
|
/** @internal */
|
|
@@ -1580,54 +1516,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1580
1516
|
|
|
1581
1517
|
menus = tlmenus.forContext(this.contextId)
|
|
1582
1518
|
|
|
1583
|
-
/**
|
|
1584
|
-
* @deprecated Use `editor.menus.getOpenMenus` instead.
|
|
1585
|
-
*
|
|
1586
|
-
* @public
|
|
1587
|
-
*/
|
|
1588
|
-
@computed getOpenMenus(): string[] {
|
|
1589
|
-
return this.menus.getOpenMenus()
|
|
1590
|
-
}
|
|
1591
|
-
|
|
1592
|
-
/**
|
|
1593
|
-
* @deprecated Use `editor.menus.addOpenMenu` instead.
|
|
1594
|
-
*
|
|
1595
|
-
* @public
|
|
1596
|
-
*/
|
|
1597
|
-
addOpenMenu(id: string): this {
|
|
1598
|
-
this.menus.addOpenMenu(id)
|
|
1599
|
-
return this
|
|
1600
|
-
}
|
|
1601
|
-
|
|
1602
|
-
/**
|
|
1603
|
-
* @deprecated Use `editor.menus.deleteOpenMenu` instead.
|
|
1604
|
-
*
|
|
1605
|
-
* @public
|
|
1606
|
-
*/
|
|
1607
|
-
deleteOpenMenu(id: string): this {
|
|
1608
|
-
this.menus.deleteOpenMenu(id)
|
|
1609
|
-
return this
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
|
-
/**
|
|
1613
|
-
* @deprecated Use `editor.menus.clearOpenMenus` instead.
|
|
1614
|
-
*
|
|
1615
|
-
* @public
|
|
1616
|
-
*/
|
|
1617
|
-
clearOpenMenus(): this {
|
|
1618
|
-
this.menus.clearOpenMenus()
|
|
1619
|
-
return this
|
|
1620
|
-
}
|
|
1621
|
-
|
|
1622
|
-
/**
|
|
1623
|
-
* @deprecated Use `editor.menus.hasAnyOpenMenus` instead.
|
|
1624
|
-
*
|
|
1625
|
-
* @public
|
|
1626
|
-
*/
|
|
1627
|
-
@computed getIsMenuOpen(): boolean {
|
|
1628
|
-
return this.menus.hasAnyOpenMenus()
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
1519
|
/* --------------------- Cursor --------------------- */
|
|
1632
1520
|
|
|
1633
1521
|
/**
|
|
@@ -5839,11 +5727,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5839
5727
|
return shapeIds
|
|
5840
5728
|
}
|
|
5841
5729
|
|
|
5842
|
-
/** @deprecated Use {@link Editor.getDraggingOverShape} instead */
|
|
5843
|
-
getDroppingOverShape(point: Vec, droppingShapes: TLShape[]): TLShape | undefined {
|
|
5844
|
-
return this.getDraggingOverShape(point, droppingShapes)
|
|
5845
|
-
}
|
|
5846
|
-
|
|
5847
5730
|
/**
|
|
5848
5731
|
* Get the shape that some shapes should be dropped on at a given point.
|
|
5849
5732
|
*
|
|
@@ -9459,13 +9342,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9459
9342
|
}
|
|
9460
9343
|
}
|
|
9461
9344
|
|
|
9462
|
-
/** @deprecated Use {@link Editor.getSvgString} or {@link Editor.getSvgElement} instead. */
|
|
9463
|
-
async getSvg(shapes: TLShapeId[] | TLShape[], opts: TLSvgExportOptions = {}) {
|
|
9464
|
-
const result = await this.getSvgElement(shapes, opts)
|
|
9465
|
-
if (!result) return undefined
|
|
9466
|
-
return result.svg
|
|
9467
|
-
}
|
|
9468
|
-
|
|
9469
9345
|
/**
|
|
9470
9346
|
* Get an exported image of the given shapes.
|
|
9471
9347
|
*
|
|
@@ -72,12 +72,6 @@ export interface TLImageExportOptions extends TLSvgExportOptions {
|
|
|
72
72
|
format?: TLExportType
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
/**
|
|
76
|
-
* @public
|
|
77
|
-
* @deprecated use {@link TLImageExportOptions} instead
|
|
78
|
-
*/
|
|
79
|
-
export type TLSvgOptions = TLImageExportOptions
|
|
80
|
-
|
|
81
75
|
/** @public */
|
|
82
76
|
export interface TLCameraMoveOptions {
|
|
83
77
|
/** Whether to move the camera immediately, rather than on the next tick. */
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
intersectLineSegmentPolyline,
|
|
10
10
|
intersectPolys,
|
|
11
11
|
linesIntersect,
|
|
12
|
+
polygonIntersectsPolyline,
|
|
13
|
+
polygonsIntersect,
|
|
12
14
|
} from '../intersect'
|
|
13
15
|
import { approximately, pointInPolygon } from '../utils'
|
|
14
16
|
|
|
@@ -227,25 +229,6 @@ export abstract class Geometry2d {
|
|
|
227
229
|
return distanceAlongRoute / length
|
|
228
230
|
}
|
|
229
231
|
|
|
230
|
-
/** @deprecated Iterate the vertices instead. */
|
|
231
|
-
nearestPointOnLineSegment(A: VecLike, B: VecLike): Vec {
|
|
232
|
-
const { vertices } = this
|
|
233
|
-
let nearest: Vec | undefined
|
|
234
|
-
let dist = Infinity
|
|
235
|
-
let d: number, p: Vec, q: Vec
|
|
236
|
-
for (let i = 0; i < vertices.length; i++) {
|
|
237
|
-
p = vertices[i]
|
|
238
|
-
q = Vec.NearestPointOnLineSegment(A, B, p, true)
|
|
239
|
-
d = Vec.Dist2(p, q)
|
|
240
|
-
if (d < dist) {
|
|
241
|
-
dist = d
|
|
242
|
-
nearest = q
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
if (!nearest) throw Error('nearest point not found')
|
|
246
|
-
return nearest
|
|
247
|
-
}
|
|
248
|
-
|
|
249
232
|
isPointInBounds(point: VecLike, margin = 0) {
|
|
250
233
|
const { bounds } = this
|
|
251
234
|
return !(
|
|
@@ -256,6 +239,53 @@ export abstract class Geometry2d {
|
|
|
256
239
|
)
|
|
257
240
|
}
|
|
258
241
|
|
|
242
|
+
overlapsPolygon(_polygon: VecLike[]): boolean {
|
|
243
|
+
const polygon = _polygon.map((v) => Vec.From(v))
|
|
244
|
+
|
|
245
|
+
// Otherwise, check if the geometry itself overlaps the polygon
|
|
246
|
+
const { vertices, center, isFilled, isEmptyLabel, isClosed } = this
|
|
247
|
+
|
|
248
|
+
// We'll do things in order of cheapest to most expensive checks
|
|
249
|
+
|
|
250
|
+
// Skip empty labels
|
|
251
|
+
if (isEmptyLabel) return false
|
|
252
|
+
|
|
253
|
+
// If any of the geometry's vertices are inside the polygon, it's inside
|
|
254
|
+
if (vertices.some((v) => pointInPolygon(v, polygon))) {
|
|
255
|
+
return true
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// If the geometry is filled and closed and its center is inside the polygon, it's inside
|
|
259
|
+
if (isClosed) {
|
|
260
|
+
if (isFilled) {
|
|
261
|
+
// If closed and filled, check if the center is inside the polygon
|
|
262
|
+
if (pointInPolygon(center, polygon)) {
|
|
263
|
+
return true
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ..then, slightly more expensive check, see the geometry covers the entire polygon but not its center
|
|
267
|
+
if (polygon.every((v) => pointInPolygon(v, vertices))) {
|
|
268
|
+
return true
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// If any the geometry's vertices intersect the edge of the polygon, it's inside.
|
|
273
|
+
// for example when a rotated rectangle is moved over the corner of a parent rectangle
|
|
274
|
+
// If the geometry is closed, intersect as a polygon
|
|
275
|
+
if (polygonsIntersect(polygon, vertices)) {
|
|
276
|
+
return true
|
|
277
|
+
}
|
|
278
|
+
} else {
|
|
279
|
+
// If the geometry is not closed, intersect as a polyline
|
|
280
|
+
if (polygonIntersectsPolyline(polygon, vertices)) {
|
|
281
|
+
return true
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// If none of the above checks passed, the geometry is outside the polygon
|
|
286
|
+
return false
|
|
287
|
+
}
|
|
288
|
+
|
|
259
289
|
transform(transform: MatModel, opts?: TransformedGeometry2dOptions): Geometry2d {
|
|
260
290
|
return new TransformedGeometry2d(this, transform, opts)
|
|
261
291
|
}
|
|
@@ -236,4 +236,8 @@ export class Group2d extends Geometry2d {
|
|
|
236
236
|
getSvgPathData(): string {
|
|
237
237
|
return this.children.map((c, i) => (c.isLabel ? '' : c.getSvgPathData(i === 0))).join(' ')
|
|
238
238
|
}
|
|
239
|
+
|
|
240
|
+
overlapsPolygon(polygon: VecLike[]): boolean {
|
|
241
|
+
return this.children.some((child) => child.overlapsPolygon(polygon))
|
|
242
|
+
}
|
|
239
243
|
}
|
|
@@ -2,15 +2,7 @@ import { EMPTY_ARRAY } from '@tldraw/state'
|
|
|
2
2
|
import { TLGroupShape, TLParentId, TLShape, TLShapeId } from '@tldraw/tlschema'
|
|
3
3
|
import { IndexKey, compact, getIndexAbove, getIndexBetween } from '@tldraw/utils'
|
|
4
4
|
import { Editor } from '../editor/Editor'
|
|
5
|
-
import {
|
|
6
|
-
import { Geometry2d } from '../primitives/geometry/Geometry2d'
|
|
7
|
-
import { Group2d } from '../primitives/geometry/Group2d'
|
|
8
|
-
import {
|
|
9
|
-
intersectPolygonPolygon,
|
|
10
|
-
polygonIntersectsPolyline,
|
|
11
|
-
polygonsIntersect,
|
|
12
|
-
} from '../primitives/intersect'
|
|
13
|
-
import { pointInPolygon } from '../primitives/utils'
|
|
5
|
+
import { intersectPolygonPolygon } from '../primitives/intersect'
|
|
14
6
|
|
|
15
7
|
/**
|
|
16
8
|
* Reparents shapes that are no longer contained within their parent shapes.
|
|
@@ -189,68 +181,10 @@ function getOverlappingShapes<T extends TLShape[] | TLShapeId[]>(
|
|
|
189
181
|
|
|
190
182
|
const geometry = editor.getShapeGeometry(childId)
|
|
191
183
|
|
|
192
|
-
return
|
|
184
|
+
return geometry.overlapsPolygon(parentPolygonInShapeShape)
|
|
193
185
|
})
|
|
194
186
|
}
|
|
195
187
|
|
|
196
|
-
/**
|
|
197
|
-
* @public
|
|
198
|
-
*/
|
|
199
|
-
export function doesGeometryOverlapPolygon(
|
|
200
|
-
geometry: Geometry2d,
|
|
201
|
-
parentCornersInShapeSpace: Vec[]
|
|
202
|
-
): boolean {
|
|
203
|
-
// If the child is a group, check if any of its children overlap the box
|
|
204
|
-
if (geometry instanceof Group2d) {
|
|
205
|
-
return geometry.children.some((childGeometry) =>
|
|
206
|
-
doesGeometryOverlapPolygon(childGeometry, parentCornersInShapeSpace)
|
|
207
|
-
)
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Otherwise, check if the geometry overlaps the box
|
|
211
|
-
const { vertices, center, isFilled, isEmptyLabel, isClosed } = geometry
|
|
212
|
-
|
|
213
|
-
// We'll do things in order of cheapest to most expensive checks
|
|
214
|
-
|
|
215
|
-
// Skip empty labels
|
|
216
|
-
if (isEmptyLabel) return false
|
|
217
|
-
|
|
218
|
-
// If any of the shape's vertices are inside the occluder, it's inside
|
|
219
|
-
if (vertices.some((v) => pointInPolygon(v, parentCornersInShapeSpace))) {
|
|
220
|
-
return true
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// If the shape is filled and closed and its center is inside the parent, it's inside
|
|
224
|
-
if (isClosed) {
|
|
225
|
-
if (isFilled) {
|
|
226
|
-
// If closed and filled, check if the center is inside the parent
|
|
227
|
-
if (pointInPolygon(center, parentCornersInShapeSpace)) {
|
|
228
|
-
return true
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// ..then, slightly more expensive check, see the shape covers the entire parent but not its center
|
|
232
|
-
if (parentCornersInShapeSpace.every((v) => pointInPolygon(v, vertices))) {
|
|
233
|
-
return true
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// If any the shape's vertices intersect the edge of the occluder, it's inside.
|
|
238
|
-
// for example when a rotated rectangle is moved over the corner of a parent rectangle
|
|
239
|
-
// If the child shape is closed, intersect as a polygon
|
|
240
|
-
if (polygonsIntersect(parentCornersInShapeSpace, vertices)) {
|
|
241
|
-
return true
|
|
242
|
-
}
|
|
243
|
-
} else {
|
|
244
|
-
// if the child shape is not closed, intersect as a polyline
|
|
245
|
-
if (polygonIntersectsPolyline(parentCornersInShapeSpace, vertices)) {
|
|
246
|
-
return true
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// If none of the above checks passed, the shape is outside the parent
|
|
251
|
-
return false
|
|
252
|
-
}
|
|
253
|
-
|
|
254
188
|
/**
|
|
255
189
|
* Get the shapes that will be reparented to new parents when the shapes are dropped.
|
|
256
190
|
*
|
|
@@ -354,7 +288,7 @@ export function getDroppedShapesToNewParents(
|
|
|
354
288
|
.applyToPoints(parentPagePolygon)
|
|
355
289
|
|
|
356
290
|
// If the shape overlaps the parent polygon, reparent it to that parent
|
|
357
|
-
if (
|
|
291
|
+
if (editor.getShapeGeometry(shape).overlapsPolygon(parentPolygonInShapeSpace)) {
|
|
358
292
|
// Use the util to check if the shape can be reparented to the parent
|
|
359
293
|
if (
|
|
360
294
|
!editor.getShapeUtil(parentShape).canReceiveNewChildrenOfType?.(parentShape, shape.type)
|
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.16.0-canary.
|
|
4
|
+
export const version = '3.16.0-canary.ca33603d9bda'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2024-09-13T14:36:29.063Z',
|
|
7
|
-
minor: '2025-
|
|
8
|
-
patch: '2025-
|
|
7
|
+
minor: '2025-09-03T08:49:47.670Z',
|
|
8
|
+
patch: '2025-09-03T08:49:47.670Z',
|
|
9
9
|
}
|