[fix] Hit testing against zero width / height lines (#2060)
This PR fixes a bug where certain hit tests would always miss straight lines. ### Change Type - [x] `patch` — Bug fix ### Test Plan 1. Create a straight line. 2. Try to bind an arrow to it. - [x] Unit Tests ### Release Notes - [fix] Bug where arrows would not bind to straight lines
This commit is contained in:
parent
8015a7e3d8
commit
e77005e507
2 changed files with 40 additions and 4 deletions
|
@ -4319,9 +4319,21 @@ export class Editor extends EventEmitter<TLEventMap> {
|
||||||
|
|
||||||
distance = minDistance
|
distance = minDistance
|
||||||
} else {
|
} else {
|
||||||
distance = geometry.bounds.containsPoint(pointInShapeSpace, margin)
|
// If the margin is zero and the geometry has a very small width or height,
|
||||||
? geometry.distanceToPoint(pointInShapeSpace, hitInside)
|
// then check the actual distance. This is to prevent a bug where straight
|
||||||
: Infinity
|
// lines would never pass the broad phase (point-in-bounds) check.
|
||||||
|
if (margin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {
|
||||||
|
distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)
|
||||||
|
} else {
|
||||||
|
// Broad phase
|
||||||
|
if (geometry.bounds.containsPoint(pointInShapeSpace, margin)) {
|
||||||
|
// Narrow phase (actual distance)
|
||||||
|
distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)
|
||||||
|
} else {
|
||||||
|
// Failed the broad phase, geddafugaotta'ere!
|
||||||
|
distance = Infinity
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geometry.isClosed) {
|
if (geometry.isClosed) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Vec2d, createShapeId } from '@tldraw/editor'
|
import { TLArrowShape, Vec2d, createShapeId } from '@tldraw/editor'
|
||||||
import { TestEditor } from '../../../test/TestEditor'
|
import { TestEditor } from '../../../test/TestEditor'
|
||||||
|
|
||||||
let editor: TestEditor
|
let editor: TestEditor
|
||||||
|
@ -523,5 +523,29 @@ describe('line bug', () => {
|
||||||
.keyUp('Shift')
|
.keyUp('Shift')
|
||||||
|
|
||||||
expect(editor.currentPageShapes.length).toBe(2)
|
expect(editor.currentPageShapes.length).toBe(2)
|
||||||
|
const arrow = editor.currentPageShapes[1] as TLArrowShape
|
||||||
|
expect(arrow.props.end.type).toBe('binding')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('works as expected when binding to a straight horizontal line', () => {
|
||||||
|
editor.selectAll().deleteShapes(editor.selectedShapeIds)
|
||||||
|
|
||||||
|
expect(editor.currentPageShapes.length).toBe(0)
|
||||||
|
|
||||||
|
editor
|
||||||
|
.setCurrentTool('line')
|
||||||
|
.pointerMove(0, 0)
|
||||||
|
.pointerDown()
|
||||||
|
.pointerMove(0, 100)
|
||||||
|
.pointerUp()
|
||||||
|
.setCurrentTool('arrow')
|
||||||
|
.pointerMove(50, 50)
|
||||||
|
.pointerDown()
|
||||||
|
.pointerMove(0, 50)
|
||||||
|
.pointerUp()
|
||||||
|
|
||||||
|
expect(editor.currentPageShapes.length).toBe(2)
|
||||||
|
const arrow = editor.currentPageShapes[1] as TLArrowShape
|
||||||
|
expect(arrow.props.end.type).toBe('binding')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue