fix: deselected hit element being duplicated + incorrect re-seeding

This commit is contained in:
dwelle 2025-04-02 22:56:35 +02:00
parent c79e892e55
commit 9ce6e438e6

View file

@ -99,6 +99,7 @@ import {
isShallowEqual, isShallowEqual,
arrayToMap, arrayToMap,
type EXPORT_IMAGE_TYPES, type EXPORT_IMAGE_TYPES,
randomInteger,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { import {
@ -8485,20 +8486,26 @@ class App extends React.Component<AppProps, AppState> {
}); });
if ( if (
hitElement && hitElement &&
// hit element may not end up being selected
// if we're alt-dragging a common bounding box
// over the hit element
pointerDownState.hit.wasAddedToSelection &&
!selectedElements.find((el) => el.id === hitElement.id) !selectedElements.find((el) => el.id === hitElement.id)
) { ) {
selectedElements.push(hitElement); selectedElements.push(hitElement);
} }
const idsOfElementsToDuplicate = new Map(
selectedElements.map((el) => [el.id, el]),
);
const { newElements: clonedElements, elementsWithClones } = const { newElements: clonedElements, elementsWithClones } =
duplicateElements({ duplicateElements({
type: "in-place", type: "in-place",
elements, elements,
appState: this.state, appState: this.state,
randomizeSeed: true, randomizeSeed: true,
idsOfElementsToDuplicate: new Map( idsOfElementsToDuplicate,
selectedElements.map((el) => [el.id, el]),
),
overrides: (el) => { overrides: (el) => {
const origEl = pointerDownState.originalElements.get(el.id); const origEl = pointerDownState.originalElements.get(el.id);
@ -8506,6 +8513,7 @@ class App extends React.Component<AppProps, AppState> {
return { return {
x: origEl.x, x: origEl.x,
y: origEl.y, y: origEl.y,
seed: origEl.seed,
}; };
} }
@ -8525,7 +8533,14 @@ class App extends React.Component<AppProps, AppState> {
const nextSceneElements = syncMovedIndices( const nextSceneElements = syncMovedIndices(
mappedNewSceneElements || elementsWithClones, mappedNewSceneElements || elementsWithClones,
arrayToMap(clonedElements), arrayToMap(clonedElements),
); ).map((el) => {
if (idsOfElementsToDuplicate.has(el.id)) {
return newElementWith(el, {
seed: randomInteger(),
});
}
return el;
});
this.scene.replaceAllElements(nextSceneElements); this.scene.replaceAllElements(nextSceneElements);
this.maybeCacheVisibleGaps(event, selectedElements, true); this.maybeCacheVisibleGaps(event, selectedElements, true);