From 48eecf36bb4da4213ab02375e0320816d255ed69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mitja=20Bezen=C5=A1ek?= Date: Tue, 26 Mar 2024 14:55:25 +0100 Subject: [PATCH] WIP --- packages/editor/src/lib/components/Shape.tsx | 20 ++-- packages/editor/src/lib/editor/Editor.ts | 99 ------------------- packages/tldraw/src/lib/utils/tldr/file.ts | 1 - packages/tldraw/src/test/TestEditor.ts | 1 - packages/tldraw/src/test/paste.test.ts | 1 - .../tldraw/src/test/renderingShapes.test.tsx | 12 --- 6 files changed, 6 insertions(+), 128 deletions(-) diff --git a/packages/editor/src/lib/components/Shape.tsx b/packages/editor/src/lib/components/Shape.tsx index 3762290b3..3e1519d36 100644 --- a/packages/editor/src/lib/components/Shape.tsx +++ b/packages/editor/src/lib/components/Shape.tsx @@ -28,7 +28,6 @@ export const Shape = memo(function Shape({ index, backgroundIndex, opacity, - isCulled, dprMultiple, }: { id: TLShapeId @@ -37,7 +36,6 @@ export const Shape = memo(function Shape({ index: number backgroundIndex: number opacity: number - isCulled: boolean dprMultiple: number }) { const editor = useEditor() @@ -133,21 +131,15 @@ export const Shape = memo(function Shape({ data-shape-type={shape.type} draggable={false} > - {isCulled ? null : ( - - - - )} + + + )}
- {isCulled ? ( - - ) : ( - - - - )} + + +
) diff --git a/packages/editor/src/lib/editor/Editor.ts b/packages/editor/src/lib/editor/Editor.ts index 76aa6c1a6..460e9748f 100644 --- a/packages/editor/src/lib/editor/Editor.ts +++ b/packages/editor/src/lib/editor/Editor.ts @@ -66,7 +66,6 @@ import { TLUser, createTLUser } from '../config/createTLUser' import { checkShapesAndAddCore } from '../config/defaultShapes' import { ANIMATION_MEDIUM_MS, - CAMERA_MAX_RENDERING_INTERVAL, CAMERA_MOVING_TIMEOUT, CAMERA_SLIDE_FRICTION, COARSE_DRAG_DISTANCE, @@ -636,8 +635,6 @@ export class Editor extends EventEmitter { this.stopFollowingUser() } - this.updateRenderingBounds() - this.on('tick', this.tick) requestAnimationFrame(() => { @@ -2790,7 +2787,6 @@ export class Editor extends EventEmitter { } this._tickCameraState() - this.updateRenderingBounds() return this } @@ -3063,7 +3059,6 @@ export class Editor extends EventEmitter { // box just for rendering, and we only update after the camera stops moving. private _cameraStateTimeoutRemaining = 0 - private _lastUpdateRenderingBoundsTimestamp = Date.now() private _decayCameraStateTimeout = (elapsed: number) => { this._cameraStateTimeoutRemaining -= elapsed @@ -3072,7 +3067,6 @@ export class Editor extends EventEmitter { if (this._cameraStateTimeoutRemaining <= 0) { this.off('tick', this._decayCameraStateTimeout) this._cameraState.set('idle') - this.updateRenderingBounds() } } @@ -3081,18 +3075,11 @@ export class Editor extends EventEmitter { // always reset the timeout this._cameraStateTimeoutRemaining = CAMERA_MOVING_TIMEOUT - const now = Date.now() - // If the state is idle, then start the tick if (this._cameraState.__unsafe__getWithoutCapture() === 'idle') { - this._lastUpdateRenderingBoundsTimestamp = now // don't render right away this._cameraState.set('moving') this.off('tick', this._decayCameraStateTimeout) this.on('tick', this._decayCameraStateTimeout) - } else { - if (now - this._lastUpdateRenderingBoundsTimestamp > CAMERA_MAX_RENDERING_INTERVAL) { - this.updateRenderingBounds() - } } } @@ -3121,7 +3108,6 @@ export class Editor extends EventEmitter { index: number backgroundIndex: number opacity: number - isCulled: boolean maskedPageBounds: Box | undefined }[] = [] @@ -3129,21 +3115,13 @@ export class Editor extends EventEmitter { let nextBackgroundIndex = MAX_SHAPES_PER_PAGE // We only really need these if we're using editor state, but that's ok - const editingShapeId = this.getEditingShapeId() - const selectedShapeIds = this.getSelectedShapeIds() const erasingShapeIds = this.getErasingShapeIds() - const renderingBoundsExpanded = this.getRenderingBoundsExpanded() - - // If renderingBoundsMargin is set to Infinity, then we won't cull offscreen shapes - const isCullingOffScreenShapes = Number.isFinite(this.renderingBoundsMargin) - let culled = 0 const addShapeById = (id: TLShapeId, opacity: number, isAncestorErasing: boolean) => { const shape = this.getShape(id) if (!shape) return opacity *= shape.opacity - const isCulled = false let isShapeErasing = false const util = this.getShapeUtil(shape) const maskedPageBounds = this.getShapeMaskedPageBounds(id) @@ -3153,23 +3131,8 @@ export class Editor extends EventEmitter { if (isShapeErasing) { opacity *= 0.32 } - - // isCulled = - // isCullingOffScreenShapes && - // // only cull shapes that allow unmounting, i.e. not stateful components - // util.canUnmount(shape) && - // // never cull editingg shapes - // editingShapeId !== id && - // // if the shape is fully outside of its parent's clipping bounds... - // (maskedPageBounds === undefined || - // // ...or if the shape is outside of the expanded viewport bounds... - // (!renderingBoundsExpanded.includes(maskedPageBounds) && - // // ...and if it's not selected... then cull it - // !selectedShapeIds.includes(id))) } - if (isCulled) culled++ - renderingShapes.push({ id, shape, @@ -3177,7 +3140,6 @@ export class Editor extends EventEmitter { index: nextIndex, backgroundIndex: nextBackgroundIndex, opacity, - isCulled, maskedPageBounds, }) @@ -3211,7 +3173,6 @@ export class Editor extends EventEmitter { addShapeById(childId, 1, false) } } - console.log('culled', culled) return renderingShapes } @@ -3249,59 +3210,6 @@ export class Editor extends EventEmitter { /** @internal */ private readonly _renderingBounds = atom('rendering viewport', new Box()) - /** - * The current rendering bounds in the current page space, expanded slightly. Used for determining which shapes - * to render and which to "cull". - * - * @public - */ - getRenderingBoundsExpanded() { - return this._renderingBoundsExpanded.get() - } - - /** @internal */ - private readonly _renderingBoundsExpanded = atom('rendering viewport expanded', new Box()) - - last = Date.now() - - /** - * Update the rendering bounds. This should be called when the viewport has stopped changing, such - * as at the end of a pan, zoom, or animation. - * - * @example - * ```ts - * editor.updateRenderingBounds() - * ``` - * - * - * @internal - */ - updateRenderingBounds(): this { - const viewportPageBounds = this.getViewportPageBounds() - if (viewportPageBounds.equals(this._renderingBounds.__unsafe__getWithoutCapture())) return this - const now = Date.now() - console.log('update rendering bounds', now - this.last) - this.last = now - this._renderingBounds.set(viewportPageBounds.clone()) - - if (Number.isFinite(this.renderingBoundsMargin)) { - this._renderingBoundsExpanded.set( - viewportPageBounds.clone().expandBy(this.renderingBoundsMargin / this.getZoomLevel()) - ) - } else { - this._renderingBoundsExpanded.set(viewportPageBounds) - } - return this - } - - /** - * The distance to expand the viewport when measuring culling. A larger distance will - * mean that shapes near to the viewport (but still outside of it) will not be culled. - * - * @public - */ - renderingBoundsMargin = 100 - /* --------------------- Pages ---------------------- */ @computed private _getAllPagesQuery() { @@ -3440,8 +3348,6 @@ export class Editor extends EventEmitter { } this.store.put([{ ...this.getInstanceState(), currentPageId: toId }]) - - this.updateRenderingBounds() }, undo: ({ fromId }) => { if (!this.store.has(fromId)) { @@ -3449,8 +3355,6 @@ export class Editor extends EventEmitter { return } this.store.put([{ ...this.getInstanceState(), currentPageId: fromId }]) - - this.updateRenderingBounds() }, squash: ({ fromId }, { toId }) => { return { toId, fromId } @@ -3626,12 +3530,10 @@ export class Editor extends EventEmitter { this.store.remove(deletedPageStates.map((s) => s.id)) // remove the page state this.store.remove([deletedPage.id]) // remove the page - this.updateRenderingBounds() }, undo: ({ deletedPage, deletedPageStates }) => { this.store.put([deletedPage]) this.store.put(deletedPageStates) - this.updateRenderingBounds() }, } ) @@ -4644,7 +4546,6 @@ export class Editor extends EventEmitter { */ @computed getCurrentPageRenderingShapesSorted(): TLShape[] { return this.getRenderingShapes() - .filter(({ isCulled }) => !isCulled) .sort((a, b) => a.index - b.index) .map(({ shape }) => shape) } diff --git a/packages/tldraw/src/lib/utils/tldr/file.ts b/packages/tldraw/src/lib/utils/tldr/file.ts index e7c933316..eaa95d16f 100644 --- a/packages/tldraw/src/lib/utils/tldr/file.ts +++ b/packages/tldraw/src/lib/utils/tldr/file.ts @@ -292,7 +292,6 @@ export async function parseAndLoadDocument( editor.history.clear() // Put the old bounds back in place editor.updateViewportScreenBounds(initialBounds) - editor.updateRenderingBounds() const bounds = editor.getCurrentPageBounds() if (bounds) { diff --git a/packages/tldraw/src/test/TestEditor.ts b/packages/tldraw/src/test/TestEditor.ts index b1d204c6d..7f94a4f0a 100644 --- a/packages/tldraw/src/test/TestEditor.ts +++ b/packages/tldraw/src/test/TestEditor.ts @@ -130,7 +130,6 @@ export class TestEditor extends Editor { this.bounds.bottom = bounds.y + bounds.h this.updateViewportScreenBounds(Box.From(bounds), center) - this.updateRenderingBounds() return this } diff --git a/packages/tldraw/src/test/paste.test.ts b/packages/tldraw/src/test/paste.test.ts index cc1c26d3b..0035fe8cf 100644 --- a/packages/tldraw/src/test/paste.test.ts +++ b/packages/tldraw/src/test/paste.test.ts @@ -419,7 +419,6 @@ describe('When pasting into frames...', () => { .bringToFront(editor.getSelectedShapeIds()) editor.setCamera({ x: -2000, y: -2000, z: 1 }) - editor.updateRenderingBounds() // Copy box 1 (should be out of viewport) editor.select(ids.box1).copy() diff --git a/packages/tldraw/src/test/renderingShapes.test.tsx b/packages/tldraw/src/test/renderingShapes.test.tsx index 322dfc34f..9bd2c7f17 100644 --- a/packages/tldraw/src/test/renderingShapes.test.tsx +++ b/packages/tldraw/src/test/renderingShapes.test.tsx @@ -48,18 +48,6 @@ function createShapes() { ]) } -it('updates the rendering viewport when the camera stops moving', () => { - const ids = createShapes() - - editor.updateRenderingBounds = jest.fn(editor.updateRenderingBounds) - editor.pan({ x: -201, y: -201 }) - jest.advanceTimersByTime(500) - - expect(editor.updateRenderingBounds).toHaveBeenCalledTimes(1) - expect(editor.getRenderingBounds()).toMatchObject({ x: 201, y: 201, w: 1800, h: 900 }) - expect(editor.getShapePageBounds(ids.A)).toMatchObject({ x: 100, y: 100, w: 100, h: 100 }) -}) - it('lists shapes in viewport', () => { const ids = createShapes() editor.selectNone()