From dce6010b2988e3f58db05aae79b44d2cf8d960ce Mon Sep 17 00:00:00 2001 From: Ryan Di Date: Fri, 23 Jun 2023 21:31:28 +0800 Subject: [PATCH] fix new element scene null leading to bugs after aligning --- src/actions/actionAlign.tsx | 6 ++---- src/actions/actionDistribute.tsx | 6 ++---- src/actions/actionFlip.ts | 5 +---- src/components/App.tsx | 16 ++++++++++++++-- src/scene/selection.ts | 7 +++++-- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/actions/actionAlign.tsx b/src/actions/actionAlign.tsx index d917f8037..138f331c9 100644 --- a/src/actions/actionAlign.tsx +++ b/src/actions/actionAlign.tsx @@ -10,7 +10,6 @@ import { import { ToolButton } from "../components/ToolButton"; import { getNonDeletedElements } from "../element"; import { ExcalidrawElement } from "../element/types"; -import { updateFrameMembershipOfSelectedElements } from "../frame"; import { t } from "../i18n"; import { KEYS } from "../keys"; import { getSelectedElements, isSomeElementSelected } from "../scene"; @@ -47,9 +46,8 @@ const alignSelectedElements = ( const updatedElementsMap = arrayToMap(updatedElements); - return updateFrameMembershipOfSelectedElements( - elements.map((element) => updatedElementsMap.get(element.id) || element), - appState, + return elements.map( + (element) => updatedElementsMap.get(element.id) || element, ); }; diff --git a/src/actions/actionDistribute.tsx b/src/actions/actionDistribute.tsx index f6ab3f09d..929ae31f1 100644 --- a/src/actions/actionDistribute.tsx +++ b/src/actions/actionDistribute.tsx @@ -6,7 +6,6 @@ import { ToolButton } from "../components/ToolButton"; import { distributeElements, Distribution } from "../distribute"; import { getNonDeletedElements } from "../element"; import { ExcalidrawElement } from "../element/types"; -import { updateFrameMembershipOfSelectedElements } from "../frame"; import { t } from "../i18n"; import { CODES, KEYS } from "../keys"; import { getSelectedElements, isSomeElementSelected } from "../scene"; @@ -43,9 +42,8 @@ const distributeSelectedElements = ( const updatedElementsMap = arrayToMap(updatedElements); - return updateFrameMembershipOfSelectedElements( - elements.map((element) => updatedElementsMap.get(element.id) || element), - appState, + return elements.map( + (element) => updatedElementsMap.get(element.id) || element, ); }; diff --git a/src/actions/actionFlip.ts b/src/actions/actionFlip.ts index 8199d2f50..ad62cf43f 100644 --- a/src/actions/actionFlip.ts +++ b/src/actions/actionFlip.ts @@ -19,10 +19,7 @@ export const actionFlipHorizontal = register({ trackEvent: { category: "element" }, perform: (elements, appState) => { return { - elements: updateFrameMembershipOfSelectedElements( - flipSelectedElements(elements, appState, "horizontal"), - appState, - ), + elements: flipSelectedElements(elements, appState, "horizontal"), appState, commitToHistory: true, }; diff --git a/src/components/App.tsx b/src/components/App.tsx index 99be4b0db..271462e04 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -245,6 +245,7 @@ import { isTransparent, easeToValuesRAF, muteFSAbortError, + arrayToMap, } from "../utils"; import { ContextMenu, @@ -1094,6 +1095,12 @@ class App extends React.Component { }, ); } + + // update frame membership if needed + updateFrameMembershipOfSelectedElements( + this.scene.getElementsIncludingDeleted(), + this.state, + ); }, ); @@ -3018,11 +3025,13 @@ class App extends React.Component { !(isTextElement(element) && element.containerId)), ); + const elementsMap = arrayToMap(elements); + return getElementsAtPosition(elements, (element) => hitTest(element, this.state, this.frameNameBoundsCache, x, y), ).filter((element) => { // hitting a frame's element from outside the frame is not considered a hit - const containingFrame = getContainingFrame(element); + const containingFrame = getContainingFrame(element, elementsMap); return containingFrame && this.state.shouldRenderFrames ? isCursorInFrame({ x, y }, containingFrame) : true; @@ -5845,7 +5854,10 @@ class App extends React.Component { ); if (linearElement?.frameId) { - const frame = getContainingFrame(linearElement); + const frame = getContainingFrame( + linearElement, + arrayToMap(this.scene.getElementsIncludingDeleted()), + ); if (frame && linearElement) { if (!elementOverlapsWithFrame(linearElement, frame)) { diff --git a/src/scene/selection.ts b/src/scene/selection.ts index 5b8cb35b4..e1afdcb5f 100644 --- a/src/scene/selection.ts +++ b/src/scene/selection.ts @@ -10,6 +10,7 @@ import { getContainingFrame, getFrameElements, } from "../frame"; +import { arrayToMap } from "../utils"; /** * Frames and their containing elements are not to be selected at the same time. @@ -46,11 +47,13 @@ export const getElementsWithinSelection = ( const [selectionX1, selectionY1, selectionX2, selectionY2] = getElementAbsoluteCoords(selection); + const elementsMap = arrayToMap(elements); + let elementsInSelection = elements.filter((element) => { let [elementX1, elementY1, elementX2, elementY2] = getElementBounds(element); - const containingFrame = getContainingFrame(element); + const containingFrame = getContainingFrame(element, elementsMap); if (containingFrame) { const [fx1, fy1, fx2, fy2] = getElementBounds(containingFrame); @@ -76,7 +79,7 @@ export const getElementsWithinSelection = ( : elementsInSelection; elementsInSelection = elementsInSelection.filter((element) => { - const containingFrame = getContainingFrame(element); + const containingFrame = getContainingFrame(element, elementsMap); if (containingFrame) { return elementOverlapsWithFrame(element, containingFrame);