Adds patchShapes, pageId to patch / update shapes

This commit is contained in:
Steve Ruiz 2021-09-08 14:40:04 +01:00
parent d97cfd494e
commit 73ed0781ea
5 changed files with 93 additions and 34 deletions

View file

@ -1,6 +1,8 @@
import * as React from 'react'
import Basic from './basic'
import Controlled from './controlled'
import Imperative from './imperative'
export default function App(): JSX.Element {
return <Imperative />
return <Basic />
}

View file

@ -9,7 +9,7 @@ import {
} from '@tldraw/tldraw'
export default function Controlled() {
const [doc, setDoc] = React.useState<TLDrawDocument>({
const rDocument = React.useRef<TLDrawDocument>({
id: 'doc',
pages: {
page1: {
@ -31,12 +31,12 @@ export default function Controlled() {
},
rect2: {
id: 'rect2',
type: TLDrawShapeType.Rectangle,
parentId: 'page1',
name: 'Rectangle',
childIndex: 2,
type: TLDrawShapeType.Rectangle,
point: [150, 250],
size: [150, 150],
childIndex: 1,
point: [200, 200],
size: [100, 100],
style: {
dash: DashStyle.Draw,
size: SizeStyle.Medium,
@ -59,35 +59,48 @@ export default function Controlled() {
},
})
const [doc, setDoc] = React.useState<TLDrawDocument>(rDocument.current)
React.useEffect(() => {
const timeout = setTimeout(
() =>
setDoc({
...doc,
let i = 0
const interval = setInterval(() => {
const currentDoc = rDocument.current
const rect1 = currentDoc.pages.page1.shapes.rect1
if (rect1) {
i++
const next = {
...currentDoc,
pages: {
...doc.pages,
...currentDoc.pages,
page1: {
...doc.pages.page1,
...currentDoc.pages.page1,
shapes: {
...doc.pages.page1.shapes,
rect2: {
...doc.pages.page1.shapes.rect2,
...currentDoc.pages.page1.shapes,
rect1: {
...rect1,
style: {
...doc.pages.page1.shapes.rect2.style,
color: ColorStyle.Orange,
...rect1.style,
color: i % 2 ? ColorStyle.Red : ColorStyle.Blue,
},
},
},
},
},
}),
1000
)
}
rDocument.current = next
setDoc(next)
}
}, 1000)
return () => {
clearTimeout(timeout)
clearInterval(interval)
}
}, [])
return <TLDraw document={doc} />
const handleChange = React.useCallback((tlstate) => {
rDocument.current = tlstate.document
}, [])
return <TLDraw document={doc} onChange={handleChange} />
}

View file

@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import * as React from 'react'
import { TLDraw, TLDrawShapeType, TLDrawState } from '@tldraw/tldraw'
import { ColorStyle, TLDraw, TLDrawShapeType, TLDrawState } from '@tldraw/tldraw'
export default function Imperative(): JSX.Element {
const rTLDrawState = React.useRef<TLDrawState>()
@ -25,5 +26,31 @@ export default function Imperative(): JSX.Element {
)
}, [])
React.useEffect(() => {
let i = 0
const interval = setInterval(() => {
const tlstate = rTLDrawState.current!
const rect1 = tlstate.getShape('rect1')
if (!rect1) {
// clearInterval(interval)
return
}
const color = i % 2 ? ColorStyle.Red : ColorStyle.Blue
tlstate.patchShapes({
id: 'rect1',
style: {
...rect1.style,
color,
},
})
i++
}, 1000)
return () => clearInterval(interval)
}, [])
return <TLDraw onMount={handleMount} />
}

View file

@ -3,7 +3,8 @@ import { TLDR } from '~state/tldr'
export function update(
data: Data,
updates: ({ id: string } & Partial<TLDrawShape>)[]
updates: ({ id: string } & Partial<TLDrawShape>)[],
pageId: string
): TLDrawCommand {
const ids = updates.map((update) => update.id)
@ -17,12 +18,7 @@ export function update(
bindings: {},
}
const change = TLDR.mutateShapes(
data,
ids,
(_shape, i) => updates[i],
data.appState.currentPageId
)
const change = TLDR.mutateShapes(data, ids, (_shape, i) => updates[i], pageId)
before.shapes = change.before
after.shapes = change.after
@ -32,14 +28,14 @@ export function update(
before: {
document: {
pages: {
[data.appState.currentPageId]: before,
[pageId]: before,
},
},
},
after: {
document: {
pages: {
[data.appState.currentPageId]: after,
[pageId]: after,
},
},
},

View file

@ -16,6 +16,7 @@ import {
TLPointerInfo,
inputs,
TLBounds,
Patch,
} from '@tldraw/core'
import {
FlipType,
@ -1655,8 +1656,28 @@ export class TLDrawState extends StateManager<Data> {
* @command
*/
updateShapes = (...shapes: ({ id: string } & Partial<TLDrawShape>)[]): this => {
if (shapes.length === 0) return this
return this.setState(Commands.update(this.state, shapes), 'updated_shape')
const pageShapes = this.document.pages[this.currentPageId].shapes
const shapesToUpdate = shapes.filter((shape) => pageShapes[shape.id])
if (shapesToUpdate.length === 0) return this
return this.setState(
Commands.update(this.state, shapesToUpdate, this.currentPageId),
'updated_shapes'
)
}
/**
* Manually patch a set of shapes.
* @param shapes An array of shape partials, containing the changes to be made to each shape.
* @command
*/
patchShapes = (...shapes: ({ id: string } & Partial<TLDrawShape>)[]): this => {
const pageShapes = this.document.pages[this.currentPageId].shapes
const shapesToUpdate = shapes.filter((shape) => pageShapes[shape.id])
if (shapesToUpdate.length === 0) return this
return this.patchState(
Commands.update(this.state, shapesToUpdate, this.currentPageId).after,
'updated_shapes'
)
}
/**