[fix] Hides handles that are too close to a previous handle (#193)
* Hides handles that are too close to a previous handle * Hide handles if only one handle is visible
This commit is contained in:
parent
918ebef54d
commit
3ba4d435bc
4 changed files with 22 additions and 6 deletions
|
@ -4,6 +4,6 @@ import { Handles } from './handles'
|
||||||
|
|
||||||
describe('handles', () => {
|
describe('handles', () => {
|
||||||
test('mounts component without crashing', () => {
|
test('mounts component without crashing', () => {
|
||||||
renderWithContext(<Handles shape={mockUtils.box.create({ id: 'box' })} />)
|
renderWithContext(<Handles shape={mockUtils.box.create({ id: 'box' })} zoom={1} />)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,20 +1,36 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Vec } from '@tldraw/vec'
|
import { Vec } from '@tldraw/vec'
|
||||||
import type { TLShape } from '+types'
|
import type { TLHandle, TLShape } from '+types'
|
||||||
import { Handle } from './handle'
|
import { Handle } from './handle'
|
||||||
|
|
||||||
interface HandlesProps {
|
interface HandlesProps {
|
||||||
shape: TLShape
|
shape: TLShape
|
||||||
|
zoom: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Handles = React.memo(({ shape }: HandlesProps): JSX.Element | null => {
|
export const Handles = React.memo(({ shape, zoom }: HandlesProps): JSX.Element | null => {
|
||||||
if (shape.handles === undefined) {
|
if (shape.handles === undefined) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let prev: number[] | null = null
|
||||||
|
|
||||||
|
const handlesToShow = Object.values(shape.handles).reduce((acc, cur) => {
|
||||||
|
const point = Vec.add(cur.point, shape.point)
|
||||||
|
|
||||||
|
if (!prev || Vec.dist(point, prev) * zoom >= 32) {
|
||||||
|
acc.push(cur)
|
||||||
|
prev = point
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc
|
||||||
|
}, [] as TLHandle[])
|
||||||
|
|
||||||
|
if (handlesToShow.length === 1) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{Object.values(shape.handles).map((handle) => (
|
{handlesToShow.map((handle) => (
|
||||||
<Handle
|
<Handle
|
||||||
key={shape.id + '_' + handle.id}
|
key={shape.id + '_' + handle.id}
|
||||||
id={handle.id}
|
id={handle.id}
|
||||||
|
|
|
@ -105,7 +105,7 @@ export const Page = React.memo(function Page<T extends TLShape, M extends Record
|
||||||
hideCloneHandles={_hideCloneHandles}
|
hideCloneHandles={_hideCloneHandles}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!hideHandles && shapeWithHandles && <Handles shape={shapeWithHandles} />}
|
{!hideHandles && shapeWithHandles && <Handles shape={shapeWithHandles} zoom={zoom} />}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -104,7 +104,7 @@ export class ArrowSession extends Session {
|
||||||
|
|
||||||
const handle = {
|
const handle = {
|
||||||
...handles[handleId],
|
...handles[handleId],
|
||||||
point: Vec.sub(Vec.add(handles[handleId].point, delta), shape.point),
|
point: Vec.round(Vec.sub(Vec.add(handles[handleId].point, delta), shape.point)),
|
||||||
bindingId: undefined,
|
bindingId: undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue