Allow snapping of shapes to the frame when dragging inside the frame. (#2520)
Allows you to snap to frames when dragging inside them. https://github.com/tldraw/tldraw/assets/2523721/41816b9b-5969-416d-af15-77b8f102ad21 Resolves #2471 ### Change Type - [ ] `patch` — Bug fix - [x] `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 a frame. 2. Add some shape inside. 3. Drag the shapes while holding `cmd` or turning on always snap. You should be able to snap to the edges and the centre of the frame. - [ ] Unit Tests - [ ] End to end tests ### Release Notes - Adds snapping to frames when dragging shapes inside a frame.
This commit is contained in:
parent
12fe9d9c4e
commit
be927df935
2 changed files with 28 additions and 3 deletions
|
@ -1,5 +1,13 @@
|
|||
import { atom, computed, EMPTY_ARRAY } from '@tldraw/state'
|
||||
import { TLGroupShape, TLParentId, TLShape, TLShapeId, VecModel } from '@tldraw/tlschema'
|
||||
import {
|
||||
isShapeId,
|
||||
TLFrameShape,
|
||||
TLGroupShape,
|
||||
TLParentId,
|
||||
TLShape,
|
||||
TLShapeId,
|
||||
VecModel,
|
||||
} from '@tldraw/tlschema'
|
||||
import { dedupe, deepCopy } from '@tldraw/utils'
|
||||
import {
|
||||
Box,
|
||||
|
@ -244,6 +252,16 @@ export class SnapManager {
|
|||
const snappableShapes: GapNode[] = []
|
||||
|
||||
const collectSnappableShapesFromParent = (parentId: TLParentId) => {
|
||||
if (isShapeId(parentId)) {
|
||||
const parent = editor.getShape(parentId)
|
||||
if (parent && editor.isShapeOfType<TLFrameShape>(parent, 'frame')) {
|
||||
snappableShapes.push({
|
||||
id: parentId,
|
||||
pageBounds: editor.getShapePageBounds(parentId)!,
|
||||
isClosed: editor.getShapeGeometry(parent).isClosed,
|
||||
})
|
||||
}
|
||||
}
|
||||
const sortedChildIds = editor.getSortedChildIdsForParent(parentId)
|
||||
for (const childId of sortedChildIds) {
|
||||
// Skip any selected ids
|
||||
|
|
|
@ -492,12 +492,19 @@ describe('frame shapes', () => {
|
|||
editor.setCurrentTool('select')
|
||||
editor.pointerDown(150, 150, innerBoxId).pointerMove(150, 50).pointerMove(150, 148)
|
||||
editor.keyDown('Control')
|
||||
expect(editor.snaps.getLines()).toHaveLength(0)
|
||||
let shapes = editor.snaps.getSnappableShapes()
|
||||
// We can snap to the parent frame
|
||||
expect(shapes).toHaveLength(1)
|
||||
expect(shapes[0].id).toBe(frameId)
|
||||
|
||||
// move shape inside the frame to make sure it snaps in there
|
||||
editor.reparentShapes([outerBoxId], frameId).pointerMove(150, 149, { ctrlKey: true })
|
||||
|
||||
expect(editor.snaps.getLines()).toHaveLength(1)
|
||||
shapes = editor.snaps.getSnappableShapes()
|
||||
expect(shapes).toHaveLength(2)
|
||||
const ids = new Set(shapes.map((s) => s.id))
|
||||
expect(ids).toContain(frameId)
|
||||
expect(ids).toContain(outerBoxId)
|
||||
})
|
||||
|
||||
it('masks its children', () => {
|
||||
|
|
Loading…
Reference in a new issue