Added cloning bindings

This commit is contained in:
Steve Ruiz 2021-08-11 17:03:08 +01:00
parent ed4cab6fd4
commit cec7048acd
2 changed files with 79 additions and 24 deletions

View file

@ -235,7 +235,10 @@ export class Ellipse extends TLDrawShapeUtil<EllipseShape> {
]) ])
} }
if (Utils.pointInBounds(point, bounds)) { if (
Utils.pointInEllipse(point, center, shape.radius[0], shape.radius[1], shape.rotation || 0)
) {
// Pad the arrow out by 16 points
distance = 16 distance = 16
} else { } else {
// Find the distance between the point and the ellipse // Find the distance between the point and the ellipse

View file

@ -1,4 +1,5 @@
import { Utils, Vec } from '@tldraw/core' import { Utils, Vec } from '@tldraw/core'
import type { TLBinding } from 'packages/core/src/types'
import type { TLDrawShape } from '../../../../shape' import type { TLDrawShape } from '../../../../shape'
import type { Session } from '../../../state-types' import type { Session } from '../../../state-types'
import type { Data } from '../../../state-types' import type { Data } from '../../../state-types'
@ -75,6 +76,12 @@ export class TranslateSession implements Session {
} }
next.pageState.selectedIds = clones.map((c) => c.id) next.pageState.selectedIds = clones.map((c) => c.id)
for (const binding of this.snapshot.clonedBindings) {
next.page.bindings[binding.id] = binding
}
next.page.bindings = { ...next.page.bindings }
} }
// Either way, move the clones // Either way, move the clones
@ -101,21 +108,24 @@ export class TranslateSession implements Session {
if (this.isCloning) { if (this.isCloning) {
this.isCloning = false this.isCloning = false
next.page.shapes = { ...next.page.shapes }
// Delete the clones // Delete the clones
clones.forEach((clone) => delete next.page.shapes[clone.id]) clones.forEach((clone) => delete next.page.shapes[clone.id])
// Move the original shapes back to the cursor position // Move the original shapes back to the cursor position
next.page.shapes = { initialShapes.forEach((shape) => {
...next.page.shapes, next.page.shapes[shape.id] = {
...Object.fromEntries( ...next.page.shapes[shape.id],
initialShapes.map((shape) => [ point: Vec.round(Vec.add(shape.point, delta)),
shape.id, }
{ })
...next.page.shapes[shape.id],
point: Vec.round(Vec.add(shape.point, delta)), // Delete the cloned bindings
}, next.page.bindings = { ...next.page.bindings }
])
), for (const binding of this.snapshot.clonedBindings) {
delete next.page.bindings[binding.id]
} }
// Set selected ids // Set selected ids
@ -172,9 +182,15 @@ export class TranslateSession implements Session {
this.snapshot.initialShapes.map((shape) => [shape.id, { point: shape.point }]) this.snapshot.initialShapes.map((shape) => [shape.id, { point: shape.point }])
), ),
}, },
bindings: {
...Object.fromEntries(
this.snapshot.clonedBindings.map((binding) => [binding.id, undefined])
),
},
}, },
pageState: { pageState: {
selectedIds: this.snapshot.selectedIds, selectedIds: this.snapshot.selectedIds,
hoveredId: undefined,
}, },
}, },
after: { after: {
@ -190,9 +206,18 @@ export class TranslateSession implements Session {
]) ])
), ),
}, },
bindings: {
...Object.fromEntries(
this.snapshot.clonedBindings.map((binding) => [
binding.id,
data.page.bindings[binding.id],
])
),
},
}, },
pageState: { pageState: {
selectedIds: [...data.pageState.selectedIds], selectedIds: [...data.pageState.selectedIds],
hoveredId: undefined,
}, },
}, },
} }
@ -205,6 +230,8 @@ export function getTranslateSnapshot(data: Data) {
const hasUnlockedShapes = selectedShapes.length > 0 const hasUnlockedShapes = selectedShapes.length > 0
const cloneMap: Record<string, string> = {}
const initialParents = Array.from(new Set(selectedShapes.map((s) => s.parentId)).values()) const initialParents = Array.from(new Set(selectedShapes.map((s) => s.parentId)).values())
.filter((id) => id !== data.page.id) .filter((id) => id !== data.page.id)
.map((id) => { .map((id) => {
@ -215,6 +242,41 @@ export function getTranslateSnapshot(data: Data) {
} }
}) })
const clones = selectedShapes
.filter((shape) => shape.children === undefined)
.flatMap((shape) => {
const clone: TLDrawShape = {
...shape,
id: Utils.uniqueId(),
parentId: shape.parentId,
childIndex: TLDR.getChildIndexAbove(data, shape.id),
}
cloneMap[shape.id] = clone.id
return clone
})
const clonedBindings: TLBinding[] = []
selectedShapes.forEach((shape) => {
if (!shape.handles) return
for (const handle of Object.values(shape.handles)) {
if (handle.bindingId) {
const binding = data.page.bindings[handle.bindingId]
const cloneBinding = {
...binding,
id: Utils.uniqueId(),
fromId: cloneMap[binding.fromId] || binding.fromId,
toId: cloneMap[binding.toId] || binding.toId,
}
clonedBindings.push(cloneBinding)
}
}
})
return { return {
selectedIds: TLDR.getSelectedIds(data), selectedIds: TLDR.getSelectedIds(data),
hasUnlockedShapes, hasUnlockedShapes,
@ -224,18 +286,8 @@ export function getTranslateSnapshot(data: Data) {
point, point,
parentId, parentId,
})), })),
clones: selectedShapes clones,
.filter((shape) => shape.children === undefined) clonedBindings,
.flatMap((shape) => {
const clone: TLDrawShape = {
...shape,
id: Utils.uniqueId(),
parentId: shape.parentId,
childIndex: TLDR.getChildIndexAbove(data, shape.id),
}
return clone
}),
} }
} }