kopia lustrzana https://github.com/Tldraw/Tldraw
Fix start arrow binding (#157)
rodzic
a4bcf32881
commit
d5fcdfbb5a
|
@ -190,4 +190,31 @@ describe('When creating with an arrow session', () => {
|
|||
expect(arrow.handles.start.bindingId).not.toBe(undefined)
|
||||
expect(arrow.handles.end.bindingId).not.toBe(undefined)
|
||||
})
|
||||
|
||||
it('Removes a binding when dragged away', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
.createShapes(
|
||||
{ type: TLDrawShapeType.Rectangle, id: 'rect1', point: [200, 200], size: [200, 200] },
|
||||
{ type: TLDrawShapeType.Rectangle, id: 'rect2', point: [400, 200], size: [200, 200] },
|
||||
{ type: TLDrawShapeType.Arrow, id: 'arrow1', point: [250, 250] }
|
||||
)
|
||||
.select('arrow1')
|
||||
.startSession(SessionType.Arrow, [250, 250], 'end', true)
|
||||
.updateSession([450, 250])
|
||||
.completeSession()
|
||||
.select('arrow1')
|
||||
.startSession(SessionType.Arrow, [250, 250], 'start', false)
|
||||
.updateSession([0, 0])
|
||||
.completeSession()
|
||||
|
||||
const arrow = tlstate.shapes.find((shape) => shape.type === TLDrawShapeType.Arrow) as ArrowShape
|
||||
|
||||
expect(arrow).toBeTruthy()
|
||||
|
||||
expect(tlstate.bindings.length).toBe(1)
|
||||
|
||||
expect(arrow.handles.start.point).toStrictEqual([0, 0])
|
||||
expect(arrow.handles.start.bindingId).toBe(undefined)
|
||||
expect(arrow.handles.end.bindingId).not.toBe(undefined)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
SessionType,
|
||||
} from '~types'
|
||||
import { Vec } from '@tldraw/vec'
|
||||
import { Utils, Patch } from '@tldraw/core'
|
||||
import { Utils } from '@tldraw/core'
|
||||
import { TLDR } from '~state/tldr'
|
||||
|
||||
export class ArrowSession implements Session {
|
||||
|
@ -96,6 +96,7 @@ export class ArrowSession implements Session {
|
|||
const handle = {
|
||||
...handles[handleId],
|
||||
point: Vec.sub(Vec.add(handles[handleId].point, delta), shape.point),
|
||||
bindingId: undefined,
|
||||
}
|
||||
|
||||
const utils = TLDR.getShapeUtils<ArrowShape>(shape.type)
|
||||
|
@ -116,10 +117,14 @@ export class ArrowSession implements Session {
|
|||
// made it this far, the shape should be a new object reference that
|
||||
// incorporates the changes we've made due to the handle movement.
|
||||
const next: { shape: ArrowShape; bindings: Record<string, TLDrawBinding | undefined> } = {
|
||||
shape: { ...shape, ...change },
|
||||
shape: Utils.deepMerge(shape, change),
|
||||
bindings: {},
|
||||
}
|
||||
|
||||
if (this.initialBinding) {
|
||||
next.bindings[this.initialBinding.id] = undefined
|
||||
}
|
||||
|
||||
// START BINDING
|
||||
|
||||
// If we have a start binding shape id, the recompute the binding
|
||||
|
@ -151,6 +156,8 @@ export class ArrowSession implements Session {
|
|||
}
|
||||
|
||||
if (startBinding) {
|
||||
this.didBind = true
|
||||
|
||||
next.bindings[this.newStartBindingId] = startBinding
|
||||
|
||||
next.shape.handles = {
|
||||
|
@ -177,14 +184,20 @@ export class ArrowSession implements Session {
|
|||
Object.assign(next.shape, arrowChange)
|
||||
}
|
||||
} else {
|
||||
next.bindings[this.newStartBindingId] = undefined
|
||||
this.didBind = this.didBind || false
|
||||
|
||||
next.shape.handles = {
|
||||
...next.shape.handles,
|
||||
start: {
|
||||
...next.shape.handles.start,
|
||||
bindingId: undefined,
|
||||
},
|
||||
if (page.bindings[this.newStartBindingId]) {
|
||||
next.bindings[this.newStartBindingId] = undefined
|
||||
}
|
||||
|
||||
if (shape.handles.start.bindingId === this.newStartBindingId) {
|
||||
next.shape.handles = {
|
||||
...next.shape.handles,
|
||||
start: {
|
||||
...next.shape.handles.start,
|
||||
bindingId: undefined,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,13 +227,13 @@ export class ArrowSession implements Session {
|
|||
metaKey
|
||||
)
|
||||
|
||||
if (draggedBinding) {
|
||||
break
|
||||
}
|
||||
if (draggedBinding) break
|
||||
}
|
||||
}
|
||||
|
||||
if (draggedBinding) {
|
||||
this.didBind = true
|
||||
|
||||
next.bindings[this.draggedBindingId] = draggedBinding
|
||||
|
||||
next.shape.handles = {
|
||||
|
@ -247,14 +260,23 @@ export class ArrowSession implements Session {
|
|||
Object.assign(next.shape, arrowChange)
|
||||
}
|
||||
} else {
|
||||
next.bindings[this.draggedBindingId] = undefined
|
||||
this.didBind = this.didBind || false
|
||||
|
||||
next.shape.handles = {
|
||||
...next.shape.handles,
|
||||
[this.handleId]: {
|
||||
...next.shape.handles[this.handleId],
|
||||
bindingId: undefined,
|
||||
},
|
||||
const currentBindingId = shape.handles[this.handleId].bindingId
|
||||
|
||||
if (currentBindingId) {
|
||||
next.bindings = {
|
||||
...next.bindings,
|
||||
[currentBindingId]: undefined,
|
||||
}
|
||||
|
||||
next.shape.handles = {
|
||||
...next.shape.handles,
|
||||
[this.handleId]: {
|
||||
...next.shape.handles[this.handleId],
|
||||
bindingId: undefined,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -227,7 +227,9 @@ export class TLDrawState extends StateManager<Data> {
|
|||
|
||||
// If binding is undefined, delete the binding
|
||||
Object.keys(page.bindings).forEach((id) => {
|
||||
if (!page.bindings[id]) delete page.bindings[id]
|
||||
if (!page.bindings[id]) {
|
||||
delete page.bindings[id]
|
||||
}
|
||||
})
|
||||
|
||||
// Find which shapes have changed
|
||||
|
@ -242,6 +244,10 @@ export class TLDrawState extends StateManager<Data> {
|
|||
|
||||
// Update all of the bindings we've just collected
|
||||
bindingsToUpdate.forEach((binding) => {
|
||||
if (!page.bindings[binding.id]) {
|
||||
return
|
||||
}
|
||||
|
||||
const toShape = page.shapes[binding.toId]
|
||||
const fromShape = page.shapes[binding.fromId]
|
||||
|
||||
|
@ -1648,7 +1654,7 @@ export class TLDrawState extends StateManager<Data> {
|
|||
if (!session) return this
|
||||
const patch = session.update(this.state, point, shiftKey, altKey, metaKey)
|
||||
if (!patch) return this
|
||||
return this.patchState(patch, `session:updateSession.id}`)
|
||||
return this.patchState(patch, `session:${session?.constructor.name}`)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2200,6 +2206,8 @@ export class TLDrawState extends StateManager<Data> {
|
|||
if (this.state.room) {
|
||||
const { users, userId } = this.state.room
|
||||
|
||||
if (Object.values(users).length === 1) return
|
||||
|
||||
this.updateUsers(
|
||||
[
|
||||
{
|
||||
|
|
|
@ -41,7 +41,7 @@ export class SelectTool extends BaseTool<Status> {
|
|||
|
||||
selectedGroupId?: string
|
||||
|
||||
pointedHandleId?: 'start' | 'end'
|
||||
pointedHandleId?: 'start' | 'end' | 'bend'
|
||||
|
||||
pointedBoundsHandle?: TLBoundsCorner | TLBoundsEdge | 'rotate'
|
||||
|
||||
|
@ -303,12 +303,12 @@ export class SelectTool extends BaseTool<Status> {
|
|||
|
||||
if (!selectedShape) return
|
||||
|
||||
const point = this.state.getPagePoint(info.origin)
|
||||
const point = this.state.getPagePoint(info.point)
|
||||
|
||||
if (selectedShape.type === TLDrawShapeType.Arrow) {
|
||||
this.state.startSession(SessionType.Arrow, point, this.pointedHandleId)
|
||||
} else {
|
||||
if (this.pointedHandleId === 'bend') {
|
||||
this.state.startSession(SessionType.Handle, point, this.pointedHandleId)
|
||||
} else {
|
||||
this.state.startSession(SessionType.Arrow, point, this.pointedHandleId, false)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
Ładowanie…
Reference in New Issue