Fix start arrow binding (#157)

pull/158/head
Steve Ruiz 2021-10-16 19:40:59 +01:00 zatwierdzone przez GitHub
rodzic a4bcf32881
commit d5fcdfbb5a
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
4 zmienionych plików z 83 dodań i 26 usunięć

Wyświetl plik

@ -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)
})
})

Wyświetl plik

@ -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,
},
}
}
}

Wyświetl plik

@ -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(
[
{

Wyświetl plik

@ -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