Don't reset cache while zooming using a gesture (#1103)

* Don't reset cache while zooming using a gesture

This reuses the cached canvas while the gesture is happening. Once it has stop updating, then recompute the cache with the proper zoom.

This should massively improve performance when panning on big scenes on mobile

Fixes #1056

* update snapshot tests
This commit is contained in:
Christopher Chedeau 2020-03-28 16:59:36 -07:00 committed by GitHub
parent 95eaadeb85
commit 24fa657093
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 64 additions and 7 deletions

1
.watchmanconfig Normal file
View File

@ -0,0 +1 @@
{}

View File

@ -35,6 +35,7 @@ export function getDefaultAppState(): AppState {
lastPointerDownWith: "mouse",
selectedElementIds: {},
collaborators: new Map(),
shouldCacheIgnoreZoom: false,
};
}

View File

@ -481,6 +481,7 @@ export class App extends React.Component<any, AppState> {
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<any, AppState> {
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<any, AppState> {
this.socket && this.broadcastMouseLocation({ pointerCoords });
};
private resetShouldCacheIgnoreZoomDebounced = debounce(() => {
this.setState({ shouldCacheIgnoreZoom: false });
}, 1000);
private saveDebounced = debounce(() => {
saveToLocalStorage(globalSceneState.getAllElements(), this.state);
}, 300);

View File

@ -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);
}

View File

@ -50,6 +50,7 @@ export function exportToCanvas(
scrollY: normalizeScroll(-minY + exportPadding),
zoom: 1,
remotePointerViewportCoords: {},
shouldCacheIgnoreZoom: false,
},
{
renderScrollbars: false,

View File

@ -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 } };
};

View File

@ -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,
}

View File

@ -42,6 +42,7 @@ export type AppState = {
lastPointerDownWith: PointerType;
selectedElementIds: { [id: string]: boolean };
collaborators: Map<string, { pointer?: { x: number; y: number } }>;
shouldCacheIgnoreZoom: boolean;
};
export type PointerCoords = Readonly<{