diff --git a/.watchmanconfig b/.watchmanconfig new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/.watchmanconfig @@ -0,0 +1 @@ +{} diff --git a/src/appState.ts b/src/appState.ts index d41b3ba7a..de55b6c5d 100644 --- a/src/appState.ts +++ b/src/appState.ts @@ -35,6 +35,7 @@ export function getDefaultAppState(): AppState { lastPointerDownWith: "mouse", selectedElementIds: {}, collaborators: new Map(), + shouldCacheIgnoreZoom: false, }; } diff --git a/src/components/App.tsx b/src/components/App.tsx index 430af6c82..c37643101 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -481,6 +481,7 @@ export class App extends React.Component { viewBackgroundColor: this.state.viewBackgroundColor, zoom: this.state.zoom, remotePointerViewportCoords: pointerViewportCoords, + shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom, }, { renderOptimizations: true, @@ -1247,7 +1248,9 @@ export class App extends React.Component { scrollX: normalizeScroll(this.state.scrollX + deltaX / this.state.zoom), scrollY: normalizeScroll(this.state.scrollY + deltaY / this.state.zoom), zoom: getNormalizedZoom(gesture.initialScale! * scaleFactor), + shouldCacheIgnoreZoom: true, }); + this.resetShouldCacheIgnoreZoomDebounced(); } else { gesture.lastCenter = gesture.initialDistance = gesture.initialScale = null; } @@ -2553,6 +2556,10 @@ export class App extends React.Component { this.socket && this.broadcastMouseLocation({ pointerCoords }); }; + private resetShouldCacheIgnoreZoomDebounced = debounce(() => { + this.setState({ shouldCacheIgnoreZoom: false }); + }, 1000); + private saveDebounced = debounce(() => { saveToLocalStorage(globalSceneState.getAllElements(), this.state); }, 300); diff --git a/src/renderer/renderElement.ts b/src/renderer/renderElement.ts index 52d14c042..e72e57dbe 100644 --- a/src/renderer/renderElement.ts +++ b/src/renderer/renderElement.ts @@ -245,7 +245,11 @@ function generateElement( } const zoom = sceneState ? sceneState.zoom : 1; const prevElementWithCanvas = elementWithCanvasCache.get(element); - if (!prevElementWithCanvas || prevElementWithCanvas.canvasZoom !== zoom) { + const shouldRegenerateBecauseZoom = + prevElementWithCanvas && + prevElementWithCanvas.canvasZoom !== zoom && + !sceneState?.shouldCacheIgnoreZoom; + if (!prevElementWithCanvas || shouldRegenerateBecauseZoom) { const elementWithCanvas = generateElementCanvas(element, zoom); elementWithCanvasCache.set(element, elementWithCanvas); return elementWithCanvas; @@ -261,8 +265,8 @@ function drawElementFromCanvas( ) { context.scale(1 / window.devicePixelRatio, 1 / window.devicePixelRatio); context.translate( - -CANVAS_PADDING / sceneState.zoom, - -CANVAS_PADDING / sceneState.zoom, + -CANVAS_PADDING / elementWithCanvas.canvasZoom, + -CANVAS_PADDING / elementWithCanvas.canvasZoom, ); context.drawImage( elementWithCanvas.canvas!, @@ -276,12 +280,12 @@ function drawElementFromCanvas( (Math.floor(elementWithCanvas.element.y) + sceneState.scrollY) * window.devicePixelRatio, ), - elementWithCanvas.canvas!.width / sceneState.zoom, - elementWithCanvas.canvas!.height / sceneState.zoom, + elementWithCanvas.canvas!.width / elementWithCanvas.canvasZoom, + elementWithCanvas.canvas!.height / elementWithCanvas.canvasZoom, ); context.translate( - CANVAS_PADDING / sceneState.zoom, - CANVAS_PADDING / sceneState.zoom, + CANVAS_PADDING / elementWithCanvas.canvasZoom, + CANVAS_PADDING / elementWithCanvas.canvasZoom, ); context.scale(window.devicePixelRatio, window.devicePixelRatio); } diff --git a/src/scene/export.ts b/src/scene/export.ts index a5f89988d..26e27c29a 100644 --- a/src/scene/export.ts +++ b/src/scene/export.ts @@ -50,6 +50,7 @@ export function exportToCanvas( scrollY: normalizeScroll(-minY + exportPadding), zoom: 1, remotePointerViewportCoords: {}, + shouldCacheIgnoreZoom: false, }, { renderScrollbars: false, diff --git a/src/scene/types.ts b/src/scene/types.ts index cd48c4abe..96c93fb19 100644 --- a/src/scene/types.ts +++ b/src/scene/types.ts @@ -7,6 +7,7 @@ export type SceneState = { // null indicates transparent bg viewBackgroundColor: string | null; zoom: number; + shouldCacheIgnoreZoom: boolean; remotePointerViewportCoords: { [id: string]: { x: number; y: number } }; }; diff --git a/src/tests/__snapshots__/regressionTests.test.tsx.snap b/src/tests/__snapshots__/regressionTests.test.tsx.snap index ba92e0cd0..63eb39d42 100644 --- a/src/tests/__snapshots__/regressionTests.test.tsx.snap +++ b/src/tests/__snapshots__/regressionTests.test.tsx.snap @@ -33,6 +33,7 @@ Object { "id2": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -211,6 +212,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -316,6 +318,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -558,6 +561,7 @@ Object { "id1": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -699,6 +703,7 @@ Object { "id2": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -873,6 +878,7 @@ Object { "id2": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -1053,6 +1059,7 @@ Object { "id3": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -1320,6 +1327,7 @@ Object { "scrolledOutside": false, "selectedElementIds": Object {}, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -1895,6 +1903,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -2000,6 +2009,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -2105,6 +2115,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -2210,6 +2221,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -2337,6 +2349,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -2464,6 +2477,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -2591,6 +2605,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -2696,6 +2711,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -2801,6 +2817,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -2928,6 +2945,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -3033,6 +3051,7 @@ Object { "id0": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": true, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -3098,6 +3117,7 @@ Object { "id9": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -3754,6 +3774,7 @@ Object { "id7": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -4102,6 +4123,7 @@ Object { "id5": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -4380,6 +4402,7 @@ Object { "id3": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -4588,6 +4611,7 @@ Object { "id1": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -4742,6 +4766,7 @@ Object { "id9": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -5370,6 +5395,7 @@ Object { "id9": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -5928,6 +5954,7 @@ Object { "id9": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -6416,6 +6443,7 @@ Object { "id9": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -6835,6 +6863,7 @@ Object { "id8": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -7218,6 +7247,7 @@ Object { "id6": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -7531,6 +7561,7 @@ Object { "id4": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -7774,6 +7805,7 @@ Object { "id2": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -7963,6 +7995,7 @@ Object { "id9": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -8626,6 +8659,7 @@ Object { "id9": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -9219,6 +9253,7 @@ Object { "id9": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -9742,6 +9777,7 @@ Object { "id9": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -10191,6 +10227,7 @@ Object { "id4": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -10419,6 +10456,7 @@ Object { "scrolledOutside": false, "selectedElementIds": Object {}, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -10468,6 +10506,7 @@ Object { "id1": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": true, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -10517,6 +10556,7 @@ Object { "id2": true, }, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } @@ -10785,6 +10825,7 @@ Object { "scrolledOutside": false, "selectedElementIds": Object {}, "selectionElement": null, + "shouldCacheIgnoreZoom": false, "viewBackgroundColor": "#ffffff", "zoom": 1, } diff --git a/src/types.ts b/src/types.ts index 640d4f183..ca7123d80 100644 --- a/src/types.ts +++ b/src/types.ts @@ -42,6 +42,7 @@ export type AppState = { lastPointerDownWith: PointerType; selectedElementIds: { [id: string]: boolean }; collaborators: Map; + shouldCacheIgnoreZoom: boolean; }; export type PointerCoords = Readonly<{