fix new element scene null leading to bugs after aligning

fix-frame
Ryan Di 2 years ago
parent b7350f9707
commit dce6010b29

@ -10,7 +10,6 @@ import {
import { ToolButton } from "../components/ToolButton"; import { ToolButton } from "../components/ToolButton";
import { getNonDeletedElements } from "../element"; import { getNonDeletedElements } from "../element";
import { ExcalidrawElement } from "../element/types"; import { ExcalidrawElement } from "../element/types";
import { updateFrameMembershipOfSelectedElements } from "../frame";
import { t } from "../i18n"; import { t } from "../i18n";
import { KEYS } from "../keys"; import { KEYS } from "../keys";
import { getSelectedElements, isSomeElementSelected } from "../scene"; import { getSelectedElements, isSomeElementSelected } from "../scene";
@ -47,9 +46,8 @@ const alignSelectedElements = (
const updatedElementsMap = arrayToMap(updatedElements); const updatedElementsMap = arrayToMap(updatedElements);
return updateFrameMembershipOfSelectedElements( return elements.map(
elements.map((element) => updatedElementsMap.get(element.id) || element), (element) => updatedElementsMap.get(element.id) || element,
appState,
); );
}; };

@ -6,7 +6,6 @@ import { ToolButton } from "../components/ToolButton";
import { distributeElements, Distribution } from "../distribute"; import { distributeElements, Distribution } from "../distribute";
import { getNonDeletedElements } from "../element"; import { getNonDeletedElements } from "../element";
import { ExcalidrawElement } from "../element/types"; import { ExcalidrawElement } from "../element/types";
import { updateFrameMembershipOfSelectedElements } from "../frame";
import { t } from "../i18n"; import { t } from "../i18n";
import { CODES, KEYS } from "../keys"; import { CODES, KEYS } from "../keys";
import { getSelectedElements, isSomeElementSelected } from "../scene"; import { getSelectedElements, isSomeElementSelected } from "../scene";
@ -43,9 +42,8 @@ const distributeSelectedElements = (
const updatedElementsMap = arrayToMap(updatedElements); const updatedElementsMap = arrayToMap(updatedElements);
return updateFrameMembershipOfSelectedElements( return elements.map(
elements.map((element) => updatedElementsMap.get(element.id) || element), (element) => updatedElementsMap.get(element.id) || element,
appState,
); );
}; };

@ -19,10 +19,7 @@ export const actionFlipHorizontal = register({
trackEvent: { category: "element" }, trackEvent: { category: "element" },
perform: (elements, appState) => { perform: (elements, appState) => {
return { return {
elements: updateFrameMembershipOfSelectedElements( elements: flipSelectedElements(elements, appState, "horizontal"),
flipSelectedElements(elements, appState, "horizontal"),
appState,
),
appState, appState,
commitToHistory: true, commitToHistory: true,
}; };

@ -245,6 +245,7 @@ import {
isTransparent, isTransparent,
easeToValuesRAF, easeToValuesRAF,
muteFSAbortError, muteFSAbortError,
arrayToMap,
} from "../utils"; } from "../utils";
import { import {
ContextMenu, ContextMenu,
@ -1094,6 +1095,12 @@ class App extends React.Component<AppProps, AppState> {
}, },
); );
} }
// update frame membership if needed
updateFrameMembershipOfSelectedElements(
this.scene.getElementsIncludingDeleted(),
this.state,
);
}, },
); );
@ -3018,11 +3025,13 @@ class App extends React.Component<AppProps, AppState> {
!(isTextElement(element) && element.containerId)), !(isTextElement(element) && element.containerId)),
); );
const elementsMap = arrayToMap(elements);
return getElementsAtPosition(elements, (element) => return getElementsAtPosition(elements, (element) =>
hitTest(element, this.state, this.frameNameBoundsCache, x, y), hitTest(element, this.state, this.frameNameBoundsCache, x, y),
).filter((element) => { ).filter((element) => {
// hitting a frame's element from outside the frame is not considered a hit // 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 return containingFrame && this.state.shouldRenderFrames
? isCursorInFrame({ x, y }, containingFrame) ? isCursorInFrame({ x, y }, containingFrame)
: true; : true;
@ -5845,7 +5854,10 @@ class App extends React.Component<AppProps, AppState> {
); );
if (linearElement?.frameId) { if (linearElement?.frameId) {
const frame = getContainingFrame(linearElement); const frame = getContainingFrame(
linearElement,
arrayToMap(this.scene.getElementsIncludingDeleted()),
);
if (frame && linearElement) { if (frame && linearElement) {
if (!elementOverlapsWithFrame(linearElement, frame)) { if (!elementOverlapsWithFrame(linearElement, frame)) {

@ -10,6 +10,7 @@ import {
getContainingFrame, getContainingFrame,
getFrameElements, getFrameElements,
} from "../frame"; } from "../frame";
import { arrayToMap } from "../utils";
/** /**
* Frames and their containing elements are not to be selected at the same time. * 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] = const [selectionX1, selectionY1, selectionX2, selectionY2] =
getElementAbsoluteCoords(selection); getElementAbsoluteCoords(selection);
const elementsMap = arrayToMap(elements);
let elementsInSelection = elements.filter((element) => { let elementsInSelection = elements.filter((element) => {
let [elementX1, elementY1, elementX2, elementY2] = let [elementX1, elementY1, elementX2, elementY2] =
getElementBounds(element); getElementBounds(element);
const containingFrame = getContainingFrame(element); const containingFrame = getContainingFrame(element, elementsMap);
if (containingFrame) { if (containingFrame) {
const [fx1, fy1, fx2, fy2] = getElementBounds(containingFrame); const [fx1, fy1, fx2, fy2] = getElementBounds(containingFrame);
@ -76,7 +79,7 @@ export const getElementsWithinSelection = (
: elementsInSelection; : elementsInSelection;
elementsInSelection = elementsInSelection.filter((element) => { elementsInSelection = elementsInSelection.filter((element) => {
const containingFrame = getContainingFrame(element); const containingFrame = getContainingFrame(element, elementsMap);
if (containingFrame) { if (containingFrame) {
return elementOverlapsWithFrame(element, containingFrame); return elementOverlapsWithFrame(element, containingFrame);

Loading…
Cancel
Save