Removed unnessary context.restore() calls a using cached selectedElements in the interactive canvas
This commit is contained in:
parent
58dcafe8f6
commit
e58e9ec6d5
@ -1100,7 +1100,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
};
|
||||
|
||||
public render() {
|
||||
const selectedElement = this.scene.getSelectedElements(this.state);
|
||||
const selectedElements = this.scene.getSelectedElements(this.state);
|
||||
const { renderTopRightUI, renderCustomStats } = this.props;
|
||||
|
||||
const versionNonce = this.scene.getVersionNonce();
|
||||
@ -1180,12 +1180,12 @@ class App extends React.Component<AppProps, AppState> {
|
||||
<div className="excalidraw-textEditorContainer" />
|
||||
<div className="excalidraw-contextMenuContainer" />
|
||||
<div className="excalidraw-eye-dropper-container" />
|
||||
{selectedElement.length === 1 &&
|
||||
{selectedElements.length === 1 &&
|
||||
!this.state.contextMenu &&
|
||||
this.state.showHyperlinkPopup && (
|
||||
<Hyperlink
|
||||
key={selectedElement[0].id}
|
||||
element={selectedElement[0]}
|
||||
key={selectedElements[0].id}
|
||||
element={selectedElements[0]}
|
||||
setAppState={this.setAppState}
|
||||
onLinkOpen={this.props.onLinkOpen}
|
||||
setToast={this.setToast}
|
||||
@ -1229,6 +1229,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
canvas={this.interactiveCanvas}
|
||||
elements={canvasElements}
|
||||
visibleElements={visibleElements}
|
||||
selectedElements={selectedElements}
|
||||
versionNonce={versionNonce}
|
||||
selectionNonce={
|
||||
this.state.selectionElement?.versionNonce
|
||||
|
@ -19,6 +19,7 @@ type InteractiveCanvasProps = {
|
||||
canvas: HTMLCanvasElement | null;
|
||||
elements: readonly NonDeletedExcalidrawElement[];
|
||||
visibleElements: readonly NonDeletedExcalidrawElement[];
|
||||
selectedElements: readonly NonDeletedExcalidrawElement[];
|
||||
versionNonce: number | undefined;
|
||||
selectionNonce: number | undefined;
|
||||
scale: number;
|
||||
@ -92,6 +93,7 @@ const InteractiveCanvas = (props: InteractiveCanvasProps) => {
|
||||
canvas: props.canvas,
|
||||
elements: props.elements,
|
||||
visibleElements: props.visibleElements,
|
||||
selectedElements: props.selectedElements,
|
||||
scale: window.devicePixelRatio,
|
||||
appState: props.appState,
|
||||
renderConfig: {
|
||||
@ -179,7 +181,8 @@ const areEqual = (
|
||||
// even if versionNonce didn't change (e.g. we filter elements out based
|
||||
// on appState)
|
||||
prevProps.elements !== nextProps.elements ||
|
||||
prevProps.visibleElements !== nextProps.visibleElements
|
||||
prevProps.visibleElements !== nextProps.visibleElements ||
|
||||
prevProps.selectedElements !== nextProps.selectedElements
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ export const getTransformHandles = (
|
||||
};
|
||||
|
||||
export const shouldShowBoundingBox = (
|
||||
elements: NonDeletedExcalidrawElement[],
|
||||
elements: readonly NonDeletedExcalidrawElement[],
|
||||
appState: InteractiveCanvasAppState,
|
||||
) => {
|
||||
if (appState.editingLinearElement) {
|
||||
|
@ -38,7 +38,6 @@ import {
|
||||
SCROLLBAR_COLOR,
|
||||
SCROLLBAR_WIDTH,
|
||||
} from "../scene/scrollbars";
|
||||
import { getSelectedElements } from "../scene/selection";
|
||||
|
||||
import {
|
||||
renderElement,
|
||||
@ -398,7 +397,6 @@ const getNormalizedCanvasDimensions = (
|
||||
const bootstrapCanvas = ({
|
||||
canvas,
|
||||
scale,
|
||||
zoom,
|
||||
normalizedWidth,
|
||||
normalizedHeight,
|
||||
theme,
|
||||
@ -407,7 +405,6 @@ const bootstrapCanvas = ({
|
||||
}: {
|
||||
canvas: HTMLCanvasElement;
|
||||
scale: number;
|
||||
zoom: CommonCanvasAppState["zoom"];
|
||||
normalizedWidth: number;
|
||||
normalizedHeight: number;
|
||||
theme?: CommonCanvasAppState["theme"];
|
||||
@ -417,7 +414,6 @@ const bootstrapCanvas = ({
|
||||
const context = canvas.getContext("2d")!;
|
||||
|
||||
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||
context.save();
|
||||
context.scale(scale, scale);
|
||||
|
||||
if (isExporting && theme === "dark") {
|
||||
@ -442,10 +438,6 @@ const bootstrapCanvas = ({
|
||||
context.clearRect(0, 0, normalizedWidth, normalizedHeight);
|
||||
}
|
||||
|
||||
// Apply zoom
|
||||
context.save();
|
||||
context.scale(zoom.value, zoom.value);
|
||||
|
||||
return context;
|
||||
};
|
||||
|
||||
@ -453,6 +445,7 @@ const _renderInteractiveScene = ({
|
||||
canvas,
|
||||
elements,
|
||||
visibleElements,
|
||||
selectedElements,
|
||||
scale,
|
||||
appState,
|
||||
renderConfig,
|
||||
@ -471,9 +464,12 @@ const _renderInteractiveScene = ({
|
||||
scale,
|
||||
normalizedWidth,
|
||||
normalizedHeight,
|
||||
zoom: appState.zoom,
|
||||
});
|
||||
|
||||
// Apply zoom
|
||||
context.save();
|
||||
context.scale(appState.zoom.value, appState.zoom.value);
|
||||
|
||||
let editingLinearElement: NonDeleted<ExcalidrawLinearElement> | undefined =
|
||||
undefined;
|
||||
|
||||
@ -517,8 +513,7 @@ const _renderInteractiveScene = ({
|
||||
renderElementsBoxHighlight(context, appState, appState.elementsToHighlight);
|
||||
}
|
||||
|
||||
const locallySelectedElements = getSelectedElements(elements, appState);
|
||||
const isFrameSelected = locallySelectedElements.some((element) =>
|
||||
const isFrameSelected = selectedElements.some((element) =>
|
||||
isFrameElement(element),
|
||||
);
|
||||
|
||||
@ -526,13 +521,13 @@ const _renderInteractiveScene = ({
|
||||
// ShapeCache returns empty hence making sure that we get the
|
||||
// correct element from visible elements
|
||||
if (
|
||||
locallySelectedElements.length === 1 &&
|
||||
appState.editingLinearElement?.elementId === locallySelectedElements[0].id
|
||||
selectedElements.length === 1 &&
|
||||
appState.editingLinearElement?.elementId === selectedElements[0].id
|
||||
) {
|
||||
renderLinearPointHandles(
|
||||
context,
|
||||
appState,
|
||||
locallySelectedElements[0] as NonDeleted<ExcalidrawLinearElement>,
|
||||
selectedElements[0] as NonDeleted<ExcalidrawLinearElement>,
|
||||
);
|
||||
}
|
||||
|
||||
@ -544,32 +539,27 @@ const _renderInteractiveScene = ({
|
||||
}
|
||||
// Paint selected elements
|
||||
if (!appState.multiElement && !appState.editingLinearElement) {
|
||||
const showBoundingBox = shouldShowBoundingBox(
|
||||
locallySelectedElements,
|
||||
appState,
|
||||
);
|
||||
const showBoundingBox = shouldShowBoundingBox(selectedElements, appState);
|
||||
|
||||
const isSingleLinearElementSelected =
|
||||
locallySelectedElements.length === 1 &&
|
||||
isLinearElement(locallySelectedElements[0]);
|
||||
selectedElements.length === 1 && isLinearElement(selectedElements[0]);
|
||||
// render selected linear element points
|
||||
if (
|
||||
isSingleLinearElementSelected &&
|
||||
appState.selectedLinearElement?.elementId ===
|
||||
locallySelectedElements[0].id &&
|
||||
!locallySelectedElements[0].locked
|
||||
appState.selectedLinearElement?.elementId === selectedElements[0].id &&
|
||||
!selectedElements[0].locked
|
||||
) {
|
||||
renderLinearPointHandles(
|
||||
context,
|
||||
appState,
|
||||
locallySelectedElements[0] as ExcalidrawLinearElement,
|
||||
selectedElements[0] as ExcalidrawLinearElement,
|
||||
);
|
||||
}
|
||||
const selectionColor = renderConfig.selectionColor || oc.black;
|
||||
|
||||
if (showBoundingBox) {
|
||||
// Optimisation for finding quickly relevant element ids
|
||||
const locallySelectedIds = locallySelectedElements.reduce(
|
||||
const locallySelectedIds = selectedElements.reduce(
|
||||
(acc: Record<string, boolean>, element) => {
|
||||
acc[element.id] = true;
|
||||
return acc;
|
||||
@ -671,10 +661,10 @@ const _renderInteractiveScene = ({
|
||||
context.save();
|
||||
context.translate(appState.scrollX, appState.scrollY);
|
||||
|
||||
if (locallySelectedElements.length === 1) {
|
||||
if (selectedElements.length === 1) {
|
||||
context.fillStyle = oc.white;
|
||||
const transformHandles = getTransformHandles(
|
||||
locallySelectedElements[0],
|
||||
selectedElements[0],
|
||||
appState.zoom,
|
||||
"mouse", // when we render we don't know which pointer type so use mouse
|
||||
);
|
||||
@ -684,13 +674,13 @@ const _renderInteractiveScene = ({
|
||||
renderConfig,
|
||||
appState,
|
||||
transformHandles,
|
||||
locallySelectedElements[0].angle,
|
||||
selectedElements[0].angle,
|
||||
);
|
||||
}
|
||||
} else if (locallySelectedElements.length > 1 && !appState.isRotating) {
|
||||
} else if (selectedElements.length > 1 && !appState.isRotating) {
|
||||
const dashedLinePadding = (DEFAULT_SPACING * 2) / appState.zoom.value;
|
||||
context.fillStyle = oc.white;
|
||||
const [x1, y1, x2, y2] = getCommonBounds(locallySelectedElements);
|
||||
const [x1, y1, x2, y2] = getCommonBounds(selectedElements);
|
||||
const initialLineDash = context.getLineDash();
|
||||
context.setLineDash([2 / appState.zoom.value]);
|
||||
const lineWidth = context.lineWidth;
|
||||
@ -717,7 +707,7 @@ const _renderInteractiveScene = ({
|
||||
? OMIT_SIDES_FOR_FRAME
|
||||
: OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,
|
||||
);
|
||||
if (locallySelectedElements.some((element) => !element.locked)) {
|
||||
if (selectedElements.some((element) => !element.locked)) {
|
||||
renderTransformHandles(
|
||||
context,
|
||||
renderConfig,
|
||||
@ -899,9 +889,6 @@ const _renderInteractiveScene = ({
|
||||
context.restore();
|
||||
}
|
||||
|
||||
context.restore();
|
||||
context.restore();
|
||||
|
||||
return {
|
||||
scrollBars,
|
||||
atLeastOneVisibleElement: visibleElements.length > 0,
|
||||
@ -934,12 +921,14 @@ const _renderStaticScene = ({
|
||||
scale,
|
||||
normalizedWidth,
|
||||
normalizedHeight,
|
||||
zoom: appState.zoom,
|
||||
theme: appState.theme,
|
||||
isExporting,
|
||||
viewBackgroundColor: appState.viewBackgroundColor,
|
||||
});
|
||||
|
||||
// Apply zoom
|
||||
context.scale(appState.zoom.value, appState.zoom.value);
|
||||
|
||||
// Grid
|
||||
if (renderGrid && appState.gridSize) {
|
||||
strokeGrid(
|
||||
@ -1057,8 +1046,6 @@ const _renderStaticScene = ({
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
|
||||
context.restore();
|
||||
};
|
||||
|
||||
export const renderInteractiveScene = <
|
||||
|
@ -53,6 +53,7 @@ export type InteractiveSceneRenderConfig = {
|
||||
canvas: HTMLCanvasElement | null;
|
||||
elements: readonly NonDeletedExcalidrawElement[];
|
||||
visibleElements: readonly NonDeletedExcalidrawElement[];
|
||||
selectedElements: readonly NonDeletedExcalidrawElement[];
|
||||
scale: number;
|
||||
appState: InteractiveCanvasAppState;
|
||||
renderConfig: InteractiveCanvasRenderConfig;
|
||||
|
Loading…
x
Reference in New Issue
Block a user