refactor: cleanup renderScene (#5573)
* refactor: cleanup renderScene * pass object instead of individual params
This commit is contained in:
parent
c37977af4b
commit
fd946adbae
@ -1165,7 +1165,23 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
this.renderScene();
|
||||||
|
this.history.record(this.state, this.scene.getElementsIncludingDeleted());
|
||||||
|
|
||||||
|
// Do not notify consumers if we're still loading the scene. Among other
|
||||||
|
// potential issues, this fixes a case where the tab isn't focused during
|
||||||
|
// init, which would trigger onChange with empty elements, which would then
|
||||||
|
// override whatever is in localStorage currently.
|
||||||
|
if (!this.state.isLoading) {
|
||||||
|
this.props.onChange?.(
|
||||||
|
this.scene.getElementsIncludingDeleted(),
|
||||||
|
this.state,
|
||||||
|
this.files,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderScene = () => {
|
||||||
const cursorButton: {
|
const cursorButton: {
|
||||||
[id: string]: string | undefined;
|
[id: string]: string | undefined;
|
||||||
} = {};
|
} = {};
|
||||||
@ -1202,6 +1218,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
);
|
);
|
||||||
cursorButton[socketId] = user.button;
|
cursorButton[socketId] = user.button;
|
||||||
});
|
});
|
||||||
|
|
||||||
const renderingElements = this.scene
|
const renderingElements = this.scene
|
||||||
.getNonDeletedElements()
|
.getNonDeletedElements()
|
||||||
.filter((element) => {
|
.filter((element) => {
|
||||||
@ -1223,13 +1240,13 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
renderScene(
|
renderScene(
|
||||||
renderingElements,
|
|
||||||
this.state,
|
|
||||||
this.state.selectionElement,
|
|
||||||
window.devicePixelRatio,
|
|
||||||
this.rc!,
|
|
||||||
this.canvas!,
|
|
||||||
{
|
{
|
||||||
|
elements: renderingElements,
|
||||||
|
appState: this.state,
|
||||||
|
scale: window.devicePixelRatio,
|
||||||
|
rc: this.rc!,
|
||||||
|
canvas: this.canvas!,
|
||||||
|
renderConfig: {
|
||||||
scrollX: this.state.scrollX,
|
scrollX: this.state.scrollX,
|
||||||
scrollY: this.state.scrollY,
|
scrollY: this.state.scrollY,
|
||||||
viewBackgroundColor: this.state.viewBackgroundColor,
|
viewBackgroundColor: this.state.viewBackgroundColor,
|
||||||
@ -1245,7 +1262,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
isExporting: false,
|
isExporting: false,
|
||||||
renderScrollbars: !this.device.isMobile,
|
renderScrollbars: !this.device.isMobile,
|
||||||
},
|
},
|
||||||
({ atLeastOneVisibleElement, scrollBars }) => {
|
callback: ({ atLeastOneVisibleElement, scrollBars }) => {
|
||||||
if (scrollBars) {
|
if (scrollBars) {
|
||||||
currentScrollBars = scrollBars;
|
currentScrollBars = scrollBars;
|
||||||
}
|
}
|
||||||
@ -1260,27 +1277,14 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
|
|
||||||
this.scheduleImageRefresh();
|
this.scheduleImageRefresh();
|
||||||
},
|
},
|
||||||
|
},
|
||||||
THROTTLE_NEXT_RENDER && window.EXCALIDRAW_THROTTLE_RENDER === true,
|
THROTTLE_NEXT_RENDER && window.EXCALIDRAW_THROTTLE_RENDER === true,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!THROTTLE_NEXT_RENDER) {
|
if (!THROTTLE_NEXT_RENDER) {
|
||||||
THROTTLE_NEXT_RENDER = true;
|
THROTTLE_NEXT_RENDER = true;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
this.history.record(this.state, this.scene.getElementsIncludingDeleted());
|
|
||||||
|
|
||||||
// Do not notify consumers if we're still loading the scene. Among other
|
|
||||||
// potential issues, this fixes a case where the tab isn't focused during
|
|
||||||
// init, which would trigger onChange with empty elements, which would then
|
|
||||||
// override whatever is in localStorage currently.
|
|
||||||
if (!this.state.isLoading) {
|
|
||||||
this.props.onChange?.(
|
|
||||||
this.scene.getElementsIncludingDeleted(),
|
|
||||||
this.state,
|
|
||||||
this.files,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private onScroll = debounce(() => {
|
private onScroll = debounce(() => {
|
||||||
const { offsetTop, offsetLeft } = this.getCanvasOffsets();
|
const { offsetTop, offsetLeft } = this.getCanvasOffsets();
|
||||||
|
@ -284,20 +284,26 @@ const renderLinearElementPointHighlight = (
|
|||||||
context.restore();
|
context.restore();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const _renderScene = (
|
export const _renderScene = ({
|
||||||
elements: readonly NonDeletedExcalidrawElement[],
|
elements,
|
||||||
appState: AppState,
|
appState,
|
||||||
selectionElement: NonDeletedExcalidrawElement | null,
|
scale,
|
||||||
scale: number,
|
rc,
|
||||||
rc: RoughCanvas,
|
canvas,
|
||||||
canvas: HTMLCanvasElement,
|
renderConfig,
|
||||||
renderConfig: RenderConfig,
|
}: {
|
||||||
|
elements: readonly NonDeletedExcalidrawElement[];
|
||||||
|
appState: AppState;
|
||||||
|
scale: number;
|
||||||
|
rc: RoughCanvas;
|
||||||
|
canvas: HTMLCanvasElement;
|
||||||
|
renderConfig: RenderConfig;
|
||||||
|
}) =>
|
||||||
// extra options passed to the renderer
|
// extra options passed to the renderer
|
||||||
) => {
|
{
|
||||||
if (canvas === null) {
|
if (canvas === null) {
|
||||||
return { atLeastOneVisibleElement: false };
|
return { atLeastOneVisibleElement: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
renderScrollbars = true,
|
renderScrollbars = true,
|
||||||
renderSelection = true,
|
renderSelection = true,
|
||||||
@ -389,9 +395,9 @@ export const _renderScene = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Paint selection element
|
// Paint selection element
|
||||||
if (selectionElement) {
|
if (appState.selectionElement) {
|
||||||
try {
|
try {
|
||||||
renderElement(selectionElement, rc, context, renderConfig);
|
renderElement(appState.selectionElement, rc, context, renderConfig);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
@ -503,7 +509,9 @@ export const _renderScene = (
|
|||||||
context,
|
context,
|
||||||
renderConfig,
|
renderConfig,
|
||||||
selection,
|
selection,
|
||||||
isSingleLinearElementSelected ? DEFAULT_SPACING * 2 : DEFAULT_SPACING,
|
isSingleLinearElementSelected
|
||||||
|
? DEFAULT_SPACING * 2
|
||||||
|
: DEFAULT_SPACING,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -706,70 +714,45 @@ export const _renderScene = (
|
|||||||
|
|
||||||
context.restore();
|
context.restore();
|
||||||
return { atLeastOneVisibleElement: visibleElements.length > 0, scrollBars };
|
return { atLeastOneVisibleElement: visibleElements.length > 0, scrollBars };
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderSceneThrottled = throttleRAF(
|
const renderSceneThrottled = throttleRAF(
|
||||||
(
|
(config: {
|
||||||
elements: readonly NonDeletedExcalidrawElement[],
|
elements: readonly NonDeletedExcalidrawElement[];
|
||||||
appState: AppState,
|
appState: AppState;
|
||||||
selectionElement: NonDeletedExcalidrawElement | null,
|
scale: number;
|
||||||
scale: number,
|
rc: RoughCanvas;
|
||||||
rc: RoughCanvas,
|
canvas: HTMLCanvasElement;
|
||||||
canvas: HTMLCanvasElement,
|
renderConfig: RenderConfig;
|
||||||
renderConfig: RenderConfig,
|
callback?: (data: ReturnType<typeof _renderScene>) => void;
|
||||||
callback?: (data: ReturnType<typeof _renderScene>) => void,
|
}) => {
|
||||||
) => {
|
const ret = _renderScene(config);
|
||||||
const ret = _renderScene(
|
config.callback?.(ret);
|
||||||
elements,
|
|
||||||
appState,
|
|
||||||
selectionElement,
|
|
||||||
scale,
|
|
||||||
rc,
|
|
||||||
canvas,
|
|
||||||
renderConfig,
|
|
||||||
);
|
|
||||||
callback?.(ret);
|
|
||||||
},
|
},
|
||||||
{ trailing: true },
|
{ trailing: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
/** renderScene throttled to animation framerate */
|
/** renderScene throttled to animation framerate */
|
||||||
export const renderScene = <T extends boolean = false>(
|
export const renderScene = <T extends boolean = false>(
|
||||||
elements: readonly NonDeletedExcalidrawElement[],
|
config: {
|
||||||
appState: AppState,
|
elements: readonly NonDeletedExcalidrawElement[];
|
||||||
selectionElement: NonDeletedExcalidrawElement | null,
|
appState: AppState;
|
||||||
scale: number,
|
scale: number;
|
||||||
rc: RoughCanvas,
|
rc: RoughCanvas;
|
||||||
canvas: HTMLCanvasElement,
|
canvas: HTMLCanvasElement;
|
||||||
renderConfig: RenderConfig,
|
renderConfig: RenderConfig;
|
||||||
callback?: (data: ReturnType<typeof _renderScene>) => void,
|
callback?: (data: ReturnType<typeof _renderScene>) => void;
|
||||||
|
},
|
||||||
/** Whether to throttle rendering. Defaults to false.
|
/** Whether to throttle rendering. Defaults to false.
|
||||||
* When throttling, no value is returned. Use the callback instead. */
|
* When throttling, no value is returned. Use the callback instead. */
|
||||||
throttle?: T,
|
throttle?: T,
|
||||||
): T extends true ? void : ReturnType<typeof _renderScene> => {
|
): T extends true ? void : ReturnType<typeof _renderScene> => {
|
||||||
if (throttle) {
|
if (throttle) {
|
||||||
renderSceneThrottled(
|
renderSceneThrottled(config);
|
||||||
elements,
|
|
||||||
appState,
|
|
||||||
selectionElement,
|
|
||||||
scale,
|
|
||||||
rc,
|
|
||||||
canvas,
|
|
||||||
renderConfig,
|
|
||||||
callback,
|
|
||||||
);
|
|
||||||
return undefined as T extends true ? void : ReturnType<typeof _renderScene>;
|
return undefined as T extends true ? void : ReturnType<typeof _renderScene>;
|
||||||
}
|
}
|
||||||
const ret = _renderScene(
|
const ret = _renderScene(config);
|
||||||
elements,
|
config.callback?.(ret);
|
||||||
appState,
|
|
||||||
selectionElement,
|
|
||||||
scale,
|
|
||||||
rc,
|
|
||||||
canvas,
|
|
||||||
renderConfig,
|
|
||||||
);
|
|
||||||
callback?.(ret);
|
|
||||||
return ret as T extends true ? void : ReturnType<typeof _renderScene>;
|
return ret as T extends true ? void : ReturnType<typeof _renderScene>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,7 +51,13 @@ export const exportToCanvas = async (
|
|||||||
files,
|
files,
|
||||||
});
|
});
|
||||||
|
|
||||||
renderScene(elements, appState, null, scale, rough.canvas(canvas), canvas, {
|
renderScene({
|
||||||
|
elements,
|
||||||
|
appState,
|
||||||
|
scale,
|
||||||
|
rc: rough.canvas(canvas),
|
||||||
|
canvas,
|
||||||
|
renderConfig: {
|
||||||
viewBackgroundColor: exportBackground ? viewBackgroundColor : null,
|
viewBackgroundColor: exportBackground ? viewBackgroundColor : null,
|
||||||
scrollX: -minX + exportPadding,
|
scrollX: -minX + exportPadding,
|
||||||
scrollY: -minY + exportPadding,
|
scrollY: -minY + exportPadding,
|
||||||
@ -67,6 +73,7 @@ export const exportToCanvas = async (
|
|||||||
renderSelection: false,
|
renderSelection: false,
|
||||||
renderGrid: false,
|
renderGrid: false,
|
||||||
isExporting: true,
|
isExporting: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return canvas;
|
return canvas;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user