fix: No more debounced refresh()
for subtypes.
This commit is contained in:
parent
91fe07d9c5
commit
ab3467973f
@ -361,7 +361,6 @@ export const useExcalidrawSetAppState = () =>
|
|||||||
export const useExcalidrawActionManager = () =>
|
export const useExcalidrawActionManager = () =>
|
||||||
useContext(ExcalidrawActionManagerContext);
|
useContext(ExcalidrawActionManagerContext);
|
||||||
|
|
||||||
let refreshTimer = 0;
|
|
||||||
let didTapTwice: boolean = false;
|
let didTapTwice: boolean = false;
|
||||||
let tappedTwiceTimer = 0;
|
let tappedTwiceTimer = 0;
|
||||||
let cursorX = 0;
|
let cursorX = 0;
|
||||||
@ -1388,20 +1387,6 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
cursorButton[socketId] = user.button;
|
cursorButton[socketId] = user.button;
|
||||||
});
|
});
|
||||||
|
|
||||||
const refresh = () => {
|
|
||||||
// If a scene refresh is cued, restart the countdown.
|
|
||||||
// This way we are not calling this.setState({}) once per
|
|
||||||
// ExcalidrawElement. The countdown improves performance
|
|
||||||
// when there are large numbers of ExcalidrawElements
|
|
||||||
// executing this refresh() callback.
|
|
||||||
if (refreshTimer !== 0) {
|
|
||||||
window.clearTimeout(refreshTimer);
|
|
||||||
}
|
|
||||||
refreshTimer = window.setTimeout(() => {
|
|
||||||
this.refresh();
|
|
||||||
window.clearTimeout(refreshTimer);
|
|
||||||
}, 50);
|
|
||||||
};
|
|
||||||
const renderingElements = this.scene
|
const renderingElements = this.scene
|
||||||
.getNonDeletedElements()
|
.getNonDeletedElements()
|
||||||
.filter((element) => {
|
.filter((element) => {
|
||||||
@ -1449,7 +1434,6 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
imageCache: this.imageCache,
|
imageCache: this.imageCache,
|
||||||
isExporting: false,
|
isExporting: false,
|
||||||
renderScrollbars: !this.device.isMobile,
|
renderScrollbars: !this.device.isMobile,
|
||||||
renderCb: refresh,
|
|
||||||
},
|
},
|
||||||
callback: ({ atLeastOneVisibleElement, scrollBars }) => {
|
callback: ({ atLeastOneVisibleElement, scrollBars }) => {
|
||||||
if (scrollBars) {
|
if (scrollBars) {
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
} from "../../../../element/types";
|
} from "../../../../element/types";
|
||||||
import { newElementWith } from "../../../../element/mutateElement";
|
import { newElementWith } from "../../../../element/mutateElement";
|
||||||
import { getElementAbsoluteCoords } from "../../../../element/bounds";
|
import { getElementAbsoluteCoords } from "../../../../element/bounds";
|
||||||
|
import Scene from "../../../../scene/Scene";
|
||||||
|
|
||||||
// Imports for actions
|
// Imports for actions
|
||||||
import { t, registerAuxLangData } from "../../../../i18n";
|
import { t, registerAuxLangData } from "../../../../i18n";
|
||||||
@ -908,7 +909,7 @@ const measureMathElement = function (element, next) {
|
|||||||
return metrics;
|
return metrics;
|
||||||
} as SubtypeMethods["measureText"];
|
} as SubtypeMethods["measureText"];
|
||||||
|
|
||||||
const renderMathElement = function (element, context, renderCb) {
|
const renderMathElement = function (element, context) {
|
||||||
ensureMathElement(element);
|
ensureMathElement(element);
|
||||||
const isMathJaxLoaded = mathJaxLoaded;
|
const isMathJaxLoaded = mathJaxLoaded;
|
||||||
const _element = element as NonDeleted<ExcalidrawMathElement>;
|
const _element = element as NonDeleted<ExcalidrawMathElement>;
|
||||||
@ -996,9 +997,7 @@ const renderMathElement = function (element, context, renderCb) {
|
|||||||
if (isMathJaxLoaded) {
|
if (isMathJaxLoaded) {
|
||||||
imageCache[imgKey] = img;
|
imageCache[imgKey] = img;
|
||||||
}
|
}
|
||||||
if (renderCb) {
|
Scene.getScene(element)?.informMutation();
|
||||||
renderCb();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
img.src = reader.result as string;
|
img.src = reader.result as string;
|
||||||
},
|
},
|
||||||
|
@ -257,7 +257,7 @@ const drawElementOnCanvas = (
|
|||||||
context.globalAlpha = element.opacity / 100;
|
context.globalAlpha = element.opacity / 100;
|
||||||
const map = getSubtypeMethods(element.subtype);
|
const map = getSubtypeMethods(element.subtype);
|
||||||
if (map?.render) {
|
if (map?.render) {
|
||||||
map.render(element, context, renderConfig.renderCb);
|
map.render(element, context);
|
||||||
context.globalAlpha = 1;
|
context.globalAlpha = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import {
|
|||||||
getInitializedImageElements,
|
getInitializedImageElements,
|
||||||
updateImageCache,
|
updateImageCache,
|
||||||
} from "../element/image";
|
} from "../element/image";
|
||||||
import { ensureSubtypesLoadedForElements } from "../subtypes";
|
|
||||||
|
|
||||||
export const SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;
|
export const SVG_EXPORT_TAG = `<!-- svg-source:excalidraw -->`;
|
||||||
|
|
||||||
@ -52,9 +51,13 @@ export const exportToCanvas = async (
|
|||||||
files,
|
files,
|
||||||
});
|
});
|
||||||
|
|
||||||
let refreshTimer = 0;
|
renderScene({
|
||||||
|
elements,
|
||||||
const renderConfig = {
|
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,
|
||||||
@ -70,30 +73,8 @@ export const exportToCanvas = async (
|
|||||||
renderSelection: false,
|
renderSelection: false,
|
||||||
renderGrid: false,
|
renderGrid: false,
|
||||||
isExporting: true,
|
isExporting: true,
|
||||||
renderCb: () => {
|
|
||||||
if (refreshTimer !== 0) {
|
|
||||||
window.clearTimeout(refreshTimer);
|
|
||||||
}
|
|
||||||
refreshTimer = window.setTimeout(() => {
|
|
||||||
renderConfig.renderCb = () => {};
|
|
||||||
window.clearTimeout(refreshTimer);
|
|
||||||
// Here instead of setState({}), call renderScene() again
|
|
||||||
render();
|
|
||||||
}, 50);
|
|
||||||
},
|
},
|
||||||
};
|
|
||||||
|
|
||||||
const render = () => {
|
|
||||||
renderScene({
|
|
||||||
elements,
|
|
||||||
appState,
|
|
||||||
scale,
|
|
||||||
rc: rough.canvas(canvas),
|
|
||||||
canvas,
|
|
||||||
renderConfig,
|
|
||||||
});
|
});
|
||||||
};
|
|
||||||
render();
|
|
||||||
|
|
||||||
return canvas;
|
return canvas;
|
||||||
};
|
};
|
||||||
@ -187,13 +168,11 @@ export const exportToSvg = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const rsvg = rough.svg(svgRoot);
|
const rsvg = rough.svg(svgRoot);
|
||||||
await ensureSubtypesLoadedForElements(elements, () => {
|
|
||||||
renderSceneToSvg(elements, rsvg, svgRoot, files || {}, {
|
renderSceneToSvg(elements, rsvg, svgRoot, files || {}, {
|
||||||
offsetX: -minX + exportPadding,
|
offsetX: -minX + exportPadding,
|
||||||
offsetY: -minY + exportPadding,
|
offsetY: -minY + exportPadding,
|
||||||
exportWithDarkMode: appState.exportWithDarkMode,
|
exportWithDarkMode: appState.exportWithDarkMode,
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
return svgRoot;
|
return svgRoot;
|
||||||
};
|
};
|
||||||
|
@ -24,7 +24,6 @@ export type RenderConfig = {
|
|||||||
renderScrollbars?: boolean;
|
renderScrollbars?: boolean;
|
||||||
renderSelection?: boolean;
|
renderSelection?: boolean;
|
||||||
renderGrid?: boolean;
|
renderGrid?: boolean;
|
||||||
renderCb?: () => void;
|
|
||||||
/** when exporting the behavior is slightly different (e.g. we can't use
|
/** when exporting the behavior is slightly different (e.g. we can't use
|
||||||
CSS filters), and we disable render optimizations for best output */
|
CSS filters), and we disable render optimizations for best output */
|
||||||
isExporting: boolean;
|
isExporting: boolean;
|
||||||
|
@ -241,7 +241,6 @@ export type SubtypeMethods = {
|
|||||||
render: (
|
render: (
|
||||||
element: NonDeleted<ExcalidrawElement>,
|
element: NonDeleted<ExcalidrawElement>,
|
||||||
context: CanvasRenderingContext2D,
|
context: CanvasRenderingContext2D,
|
||||||
renderCb?: () => void,
|
|
||||||
) => void;
|
) => void;
|
||||||
renderSvg: (
|
renderSvg: (
|
||||||
svgRoot: SVGElement,
|
svgRoot: SVGElement,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user