throttle take 2

This commit is contained in:
zsviczian 2023-02-26 21:47:35 +01:00
parent 84e01cde87
commit 6ecd843df2
2 changed files with 108 additions and 38 deletions

View File

@ -175,7 +175,10 @@ import {
} from "../keys";
import { distance2d, getGridPoint, isPathALoop } from "../math";
import { renderScene } from "../renderer/renderScene";
import { invalidateShapeForElement } from "../renderer/renderElement";
import {
generateElementWithCanvas,
invalidateShapeForElement,
} from "../renderer/renderElement";
import {
calculateScrollCenter,
getElementsAtPosition,
@ -1283,10 +1286,7 @@ class App extends React.Component<AppProps, AppState> {
}
}
private renderScene = (
renderingElements: NonDeletedExcalidrawElement[] = [],
shouldCacheIgnoreZoom: boolean | null = null,
) => {
private renderScene = () => {
const cursorButton: {
[id: string]: string | undefined;
} = {};
@ -1324,26 +1324,25 @@ class App extends React.Component<AppProps, AppState> {
cursorButton[socketId] = user.button;
});
renderingElements =
renderingElements.length > 0
? renderingElements
: this.scene.getNonDeletedElements().filter((element) => {
if (isImageElement(element)) {
if (
// not placed on canvas yet (but in elements array)
this.state.pendingImageElementId === element.id
) {
return false;
}
}
// don't render text element that's being currently edited (it's
// rendered on remote only)
return (
!this.state.editingElement ||
this.state.editingElement.type !== "text" ||
element.id !== this.state.editingElement.id
);
});
const renderingElements = this.scene
.getNonDeletedElements()
.filter((element) => {
if (isImageElement(element)) {
if (
// not placed on canvas yet (but in elements array)
this.state.pendingImageElementId === element.id
) {
return false;
}
}
// don't render text element that's being currently edited (it's
// rendered on remote only)
return (
!this.state.editingElement ||
this.state.editingElement.type !== "text" ||
element.id !== this.state.editingElement.id
);
});
const selectionColor = getComputedStyle(
document.querySelector(".excalidraw")!,
@ -1367,10 +1366,7 @@ class App extends React.Component<AppProps, AppState> {
remoteSelectedElementIds,
remotePointerUsernames: pointerUsernames,
remotePointerUserStates: pointerUserStates,
shouldCacheIgnoreZoom:
shouldCacheIgnoreZoom === null
? this.state.shouldCacheIgnoreZoom
: shouldCacheIgnoreZoom,
shouldCacheIgnoreZoom: this.state.shouldCacheIgnoreZoom,
theme: this.state.theme,
imageCache: this.imageCache,
isExporting: false,
@ -6374,14 +6370,88 @@ class App extends React.Component<AppProps, AppState> {
private resetShouldCacheIgnoreZoomDebounced = debounce(() => {
if (!this.unmounted) {
//generateElementWithCanvas
const elements = this.scene.getNonDeletedElements();
let i = 0;
for (; i < elements.length; i += 200) {
const chunk = elements.slice(i, i + 200);
setTimeout(() => this.renderScene(chunk, false),i*100);
}
setTimeout(() => this.setState({ shouldCacheIgnoreZoom: false }),i*100);
const cursorButton: {
[id: string]: string | undefined;
} = {};
const pointerViewportCoords: RenderConfig["remotePointerViewportCoords"] =
{};
const remoteSelectedElementIds: RenderConfig["remoteSelectedElementIds"] =
{};
const pointerUsernames: { [id: string]: string } = {};
const pointerUserStates: { [id: string]: string } = {};
this.state.collaborators.forEach((user, socketId) => {
if (user.selectedElementIds) {
for (const id of Object.keys(user.selectedElementIds)) {
if (!(id in remoteSelectedElementIds)) {
remoteSelectedElementIds[id] = [];
}
remoteSelectedElementIds[id].push(socketId);
}
}
if (!user.pointer) {
return;
}
if (user.username) {
pointerUsernames[socketId] = user.username;
}
if (user.userState) {
pointerUserStates[socketId] = user.userState;
}
pointerViewportCoords[socketId] = sceneCoordsToViewportCoords(
{
sceneX: user.pointer.x,
sceneY: user.pointer.y,
},
this.state,
);
cursorButton[socketId] = user.button;
});
const renderingElements = this.scene
.getNonDeletedElements()
.filter((element) => {
if (isImageElement(element)) {
if (
// not placed on canvas yet (but in elements array)
this.state.pendingImageElementId === element.id
) {
return false;
}
}
// don't render text element that's being currently edited (it's
// rendered on remote only)
return (
!this.state.editingElement ||
this.state.editingElement.type !== "text" ||
element.id !== this.state.editingElement.id
);
});
const selectionColor = getComputedStyle(
document.querySelector(".excalidraw")!,
).getPropertyValue("--color-selection");
const renderConfig: RenderConfig = {
selectionColor,
scrollX: this.state.scrollX,
scrollY: this.state.scrollY,
viewBackgroundColor: this.state.viewBackgroundColor,
zoom: this.state.zoom,
remotePointerViewportCoords: pointerViewportCoords,
remotePointerButton: cursorButton,
remoteSelectedElementIds,
remotePointerUsernames: pointerUsernames,
remotePointerUserStates: pointerUserStates,
shouldCacheIgnoreZoom: false,
theme: this.state.theme,
imageCache: this.imageCache,
isExporting: false,
renderScrollbars: !this.device.isMobile,
};
renderingElements.forEach((el) =>
setTimeout(() => generateElementWithCanvas(el, renderConfig)),
);
setTimeout(() => this.setState({ shouldCacheIgnoreZoom: false }));
}
}, 300);

View File

@ -655,7 +655,7 @@ const generateElementShape = (
}
};
const generateElementWithCanvas = (
export const generateElementWithCanvas = (
element: NonDeletedExcalidrawElement,
renderConfig: RenderConfig,
) => {