Fix an issue with arrow creation. (#2004)
Fixes an issue with creating arrows. Currently we create an arrow that has both `start` and `end` handles set to the same point. This causes `NaN` issues in some of our functions / svg rendering. After this change we only create the arrow after we start dragging, which ensures the start and the end handle won't have the same coordinates. This probably feels the best way to approach it: arrow of length 0 doesn't really make sense. Resolves [#2005](https://github.com/tldraw/tldraw/issues/2005) Before https://github.com/tldraw/tldraw/assets/2523721/6e83c17e-21bd-4e0a-826b-02fad9c21ec6 After https://github.com/tldraw/tldraw/assets/2523721/29359936-b673-4583-89c8-6d1728ab338c ### Change Type - [x] `patch` — Bug fix - [ ] `minor` — New feature - [ ] `major` — Breaking change - [ ] `dependencies` — Changes to package dependencies[^1] - [ ] `documentation` — Changes to the documentation only[^2] - [ ] `tests` — Changes to any test code only[^2] - [ ] `internal` — Any other changes that don't affect the published package[^2] - [ ] I don't know [^1]: publishes a `patch` release, for devDependencies use `internal` [^2]: will not publish a new version ### Test Plan 1. Create an arrow. 2. You should not see any errors in the console. --------- Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This commit is contained in:
parent
4260f499c6
commit
f7b325c48c
5 changed files with 25 additions and 6 deletions
|
@ -227,7 +227,8 @@ export function getCurvedArrowInfo(
|
|||
)
|
||||
}
|
||||
|
||||
if (Vec2d.Dist(tA, tB) < MIN_ARROW_LENGTH) {
|
||||
const distAB = Vec2d.Dist(tA, tB)
|
||||
if (distAB < MIN_ARROW_LENGTH) {
|
||||
if (offsetA !== 0 && offsetB !== 0) {
|
||||
offsetA *= -1.5
|
||||
offsetB *= -1.5
|
||||
|
@ -235,6 +236,11 @@ export function getCurvedArrowInfo(
|
|||
offsetA *= -2
|
||||
} else if (offsetB !== 0) {
|
||||
offsetB *= -2
|
||||
} else {
|
||||
if (distAB < 10) {
|
||||
if (startShapeInfo) offsetA = -(10 - distAB)
|
||||
else if (endShapeInfo) offsetB = -(10 - distAB)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,8 @@ export function getStraightArrowInfo(editor: Editor, shape: TLArrowShape): TLArr
|
|||
|
||||
const tA = a.clone().add(u.clone().mul(offsetA * (didFlip ? -1 : 1)))
|
||||
const tB = b.clone().sub(u.clone().mul(offsetB * (didFlip ? -1 : 1)))
|
||||
if (Vec2d.Dist(tA, tB) < MIN_ARROW_LENGTH) {
|
||||
const distAB = Vec2d.Dist(tA, tB)
|
||||
if (distAB < MIN_ARROW_LENGTH) {
|
||||
if (offsetA !== 0 && offsetB !== 0) {
|
||||
offsetA *= -1.5
|
||||
offsetB *= -1.5
|
||||
|
@ -114,6 +115,11 @@ export function getStraightArrowInfo(editor: Editor, shape: TLArrowShape): TLArr
|
|||
offsetA *= -2
|
||||
} else if (offsetB !== 0) {
|
||||
offsetB *= -2
|
||||
} else {
|
||||
if (distAB < 10) {
|
||||
if (startShapeInfo) offsetA = -(10 - distAB)
|
||||
else if (endShapeInfo) offsetB = -(10 - distAB)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -349,7 +349,7 @@ describe('When pointing an end shape', () => {
|
|||
y: 0,
|
||||
props: {
|
||||
start: { type: 'point', x: 0, y: 0 },
|
||||
end: { type: 'point', x: 0, y: 0 },
|
||||
end: { type: 'point', x: 2, y: 0 },
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ import { ArrowTextLabel } from './components/ArrowTextLabel'
|
|||
|
||||
let globalRenderIndex = 0
|
||||
|
||||
export const ARROW_END_OFFSET = 0.1
|
||||
|
||||
/** @public */
|
||||
export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
|
||||
static override type = 'arrow' as const
|
||||
|
@ -78,7 +80,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
|
|||
labelColor: 'black',
|
||||
bend: 0,
|
||||
start: { type: 'point', x: 0, y: 0 },
|
||||
end: { type: 'point', x: 0, y: 0 },
|
||||
end: { type: 'point', x: 2, y: 0 },
|
||||
arrowheadStart: 'none',
|
||||
arrowheadEnd: 'arrow',
|
||||
text: '',
|
||||
|
|
|
@ -127,12 +127,17 @@ export class Pointing extends StateNode {
|
|||
const handles = this.editor.getShapeHandles(shape)
|
||||
if (!handles) throw Error(`expected handles for arrow`)
|
||||
|
||||
const shapeWithOutEndOffset = {
|
||||
...shape,
|
||||
props: { ...shape.props, end: { ...shape.props.end, x: 0, y: 0 } },
|
||||
}
|
||||
|
||||
// end update
|
||||
{
|
||||
const util = this.editor.getShapeUtil<TLArrowShape>('arrow')
|
||||
const point = this.editor.getPointInShapeSpace(shape, this.editor.inputs.currentPagePoint)
|
||||
const endHandle = handles.find((h) => h.id === 'end')!
|
||||
const change = util.onHandleChange?.(shape, {
|
||||
const change = util.onHandleChange?.(shapeWithOutEndOffset, {
|
||||
handle: { ...endHandle, x: point.x, y: point.y },
|
||||
isPrecise: false, // sure about that?
|
||||
})
|
||||
|
@ -150,7 +155,7 @@ export class Pointing extends StateNode {
|
|||
{
|
||||
const util = this.editor.getShapeUtil<TLArrowShape>('arrow')
|
||||
const startHandle = handles.find((h) => h.id === 'start')!
|
||||
const change = util.onHandleChange?.(shape, {
|
||||
const change = util.onHandleChange?.(shapeWithOutEndOffset, {
|
||||
handle: { ...startHandle, x: 0, y: 0 },
|
||||
isPrecise: this.didTimeout, // sure about that?
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue