[example] culling (#3174)

An example hook for listening to when shapes were culled or unculled.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [x] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know
This commit is contained in:
Steve Ruiz 2024-03-16 11:03:07 +00:00 committed by GitHub
parent dc05890407
commit 29b82ed123
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 78 additions and 0 deletions

View file

@ -0,0 +1,9 @@
---
title: Rendering shapes change
component: ./RenderingShapesChangeExample.tsx
category: basic
---
---
Do something when the rendering shapes change.

View file

@ -0,0 +1,27 @@
import { useCallback } from 'react'
import { TLShape, Tldraw } from 'tldraw'
import 'tldraw/tldraw.css'
import { useChangedShapesReactor } from './useRenderingShapesChange'
const components = {
InFrontOfTheCanvas: () => {
const onShapesChanged = useCallback((info: { culled: TLShape[]; restored: TLShape[] }) => {
// eslint-disable-next-line no-console
for (const shape of info.culled) console.log('culled: ' + shape.id)
// eslint-disable-next-line no-console
for (const shape of info.restored) console.log('restored: ' + shape.id)
}, [])
useChangedShapesReactor(onShapesChanged)
return null
},
}
export default function RenderingShapesChangeExample() {
return (
<div className="tldraw__editor">
<Tldraw persistenceKey="example" components={components} />
</div>
)
}

View file

@ -0,0 +1,42 @@
import { useEffect, useRef } from 'react'
import { TLShape, react, useEditor } from 'tldraw'
export function useChangedShapesReactor(
cb: (info: { culled: TLShape[]; restored: TLShape[] }) => void
) {
const editor = useEditor()
const rPrevShapes = useRef(editor.getRenderingShapes())
useEffect(() => {
return react('when rendering shapes change', () => {
const after = editor.getRenderingShapes()
const before = rPrevShapes.current
const culled: TLShape[] = []
const restored: TLShape[] = []
const beforeToVisit = new Set(before)
for (const afterInfo of after) {
const beforeInfo = before.find((s) => s.id === afterInfo.id)
if (!beforeInfo) {
continue
} else {
if (afterInfo.isCulled && !beforeInfo.isCulled) {
culled.push(afterInfo.shape)
} else if (!afterInfo.isCulled && beforeInfo.isCulled) {
restored.push(afterInfo.shape)
}
beforeToVisit.delete(beforeInfo)
}
}
rPrevShapes.current = after
cb({
culled,
restored,
})
})
}, [cb, editor])
}