Rbush for from scratch.

mitja/fresh-rbush
Mitja Bezenšek 2024-04-09 16:43:26 +02:00
rodzic 9ded46ac2b
commit 07b1815885
3 zmienionych plików z 69 dodań i 11 usunięć

Wyświetl plik

@ -59,7 +59,8 @@
"is-plain-object": "^5.0.0",
"lodash.throttle": "^4.1.1",
"lodash.uniq": "^4.5.0",
"nanoid": "4.0.2"
"nanoid": "4.0.2",
"rbush": "^3.0.1"
},
"peerDependencies": {
"react": "^18",
@ -72,6 +73,7 @@
"@types/benchmark": "^2.1.2",
"@types/lodash.throttle": "^4.1.7",
"@types/lodash.uniq": "^4.5.7",
"@types/rbush": "^3.0.3",
"@types/react-test-renderer": "^18.0.0",
"@types/wicg-file-system-access": "^2020.9.5",
"benchmark": "^2.1.4",

Wyświetl plik

@ -1,5 +1,7 @@
import { RESET_VALUE, computed, isUninitialized } from '@tldraw/state'
import { TLPageId, TLShapeId, isShape, isShapeId } from '@tldraw/tlschema'
import { measureCbDuration } from '@tldraw/utils'
import RBush from 'rbush'
import { Box } from '../../primitives/Box'
import { Editor } from '../Editor'
@ -12,6 +14,28 @@ function isShapeNotVisible(editor: Editor, id: TLShapeId, viewportPageBounds: Bo
return !viewportPageBounds.includes(maskedPageBounds)
}
type Element = {
minX: number
minY: number
maxX: number
maxY: number
id: TLShapeId
}
function getElement(editor: Editor, id: TLShapeId): Element | null {
const bounds = editor.getShapeMaskedPageBounds(id)
if (!bounds) return null
return {
minX: bounds.minX,
minY: bounds.minY,
maxX: bounds.maxX,
maxY: bounds.maxY,
id,
}
}
class TldrawRBush extends RBush<Element> {}
/**
* Incremental derivation of not visible shapes.
* Non visible shapes are shapes outside of the viewport page bounds and shapes outside of parent's clipping bounds.
@ -26,17 +50,24 @@ export const notVisibleShapes = (editor: Editor) => {
let prevViewportPageBounds: Box
function fromScratch(editor: Editor): Set<TLShapeId> {
const shapes = editor.getCurrentPageShapeIds()
lastPageId = editor.getCurrentPageId()
const viewportPageBounds = editor.getViewportPageBounds()
prevViewportPageBounds = viewportPageBounds.clone()
const notVisibleShapes = new Set<TLShapeId>()
shapes.forEach((id) => {
if (isShapeNotVisible(editor, id, viewportPageBounds)) {
notVisibleShapes.add(id)
}
return measureCbDuration('fromScratch rbush', () => {
const viewportPageBounds = editor.getViewportPageBounds()
prevViewportPageBounds = viewportPageBounds.clone()
const elementsToAdd: Element[] = []
const shapes = editor.getCurrentPageShapeIds()
lastPageId = editor.getCurrentPageId()
shapes.forEach((id) => {
const e = getElement(editor, id)
if (!e) return
elementsToAdd.push(e)
})
const culled = new Set(shapes)
const rbush = new TldrawRBush().load(elementsToAdd)
rbush.search(viewportPageBounds).forEach((e) => culled.delete(e.id))
console.log('culled', culled.size)
return culled
})
return notVisibleShapes
}
return computed<Set<TLShapeId>>('getCulledShapes', (prevValue, lastComputedEpoch) => {
if (!isCullingOffScreenShapes) return new Set<TLShapeId>()

Wyświetl plik

@ -7488,6 +7488,7 @@ __metadata:
"@types/core-js": "npm:^2.5.5"
"@types/lodash.throttle": "npm:^4.1.7"
"@types/lodash.uniq": "npm:^4.5.7"
"@types/rbush": "npm:^3.0.3"
"@types/react-test-renderer": "npm:^18.0.0"
"@types/wicg-file-system-access": "npm:^2020.9.5"
"@use-gesture/react": "npm:^10.2.27"
@ -7504,6 +7505,7 @@ __metadata:
lodash.throttle: "npm:^4.1.1"
lodash.uniq: "npm:^4.5.0"
nanoid: "npm:4.0.2"
rbush: "npm:^3.0.1"
react-test-renderer: "npm:^18.2.0"
resize-observer-polyfill: "npm:^1.5.1"
peerDependencies:
@ -8330,6 +8332,13 @@ __metadata:
languageName: node
linkType: hard
"@types/rbush@npm:^3.0.3":
version: 3.0.3
resolution: "@types/rbush@npm:3.0.3"
checksum: 59c75d20d3ebf95f8853a98f67d437adc047bf875df6e6bba90884fdfa8fa927402ccec762ecbc8724d98f9ed14c9e97d16eddb709a702021ce1874da5d0d8d7
languageName: node
linkType: hard
"@types/react-dom@npm:^18.0.0, @types/react-dom@npm:^18.2.18":
version: 18.2.18
resolution: "@types/react-dom@npm:18.2.18"
@ -21060,6 +21069,13 @@ __metadata:
languageName: node
linkType: hard
"quickselect@npm:^2.0.0":
version: 2.0.0
resolution: "quickselect@npm:2.0.0"
checksum: ed2e78431050d223fb75da20ee98011aef1a03f7cb04e1a32ee893402e640be3cfb76d72e9dbe01edf3bb457ff6a62e5c2d85748424d1aa531f6ba50daef098c
languageName: node
linkType: hard
"raf@npm:^3.4.1":
version: 3.4.1
resolution: "raf@npm:3.4.1"
@ -21097,6 +21113,15 @@ __metadata:
languageName: node
linkType: hard
"rbush@npm:^3.0.1":
version: 3.0.1
resolution: "rbush@npm:3.0.1"
dependencies:
quickselect: "npm:^2.0.0"
checksum: 489e2e7d9889888ad533518f194e3ab7cc19b1f1365a38ee99fbdda542a47f41cda7dc89870180050f4d04ea402e9ff294e1d767d03c0f1694e0028b7609eec9
languageName: node
linkType: hard
"rc@npm:^1.2.7, rc@npm:^1.2.8, rc@npm:~1.2.7":
version: 1.2.8
resolution: "rc@npm:1.2.8"