shift for additive selection

This commit is contained in:
Ryan Di 2025-03-21 00:54:48 +11:00
parent 93cf57b862
commit 7e737f233c
2 changed files with 33 additions and 5 deletions

View file

@ -6562,6 +6562,7 @@ class App extends React.Component<AppProps, AppState> {
this.lassoTrail.startPath(
pointerDownState.origin.x,
pointerDownState.origin.y,
event.shiftKey,
);
} else if (this.state.activeTool.type === "text") {
this.handleTextOnPointerDown(event, pointerDownState);
@ -7020,7 +7021,10 @@ class App extends React.Component<AppProps, AppState> {
}
private clearSelectionIfNotUsingSelection = (): void => {
if (this.state.activeTool.type !== "selection") {
if (
this.state.activeTool.type !== "selection" &&
this.state.activeTool.type !== "lasso"
) {
this.setState({
selectedElementIds: makeNextSelectedElementIds({}, this.state),
selectedGroupIds: {},
@ -8261,7 +8265,8 @@ class App extends React.Component<AppProps, AppState> {
selectedElements.length > 0 &&
!pointerDownState.withCmdOrCtrl &&
!this.state.editingTextElement &&
this.state.activeEmbeddable?.state !== "active"
this.state.activeEmbeddable?.state !== "active" &&
this.state.activeTool.type !== "lasso"
) {
const dragOffset = {
x: pointerCoords.x - pointerDownState.origin.x,
@ -8611,7 +8616,11 @@ class App extends React.Component<AppProps, AppState> {
this.lassoTrail.endPath();
selectionSwitch = false;
} else {
this.lassoTrail.addPointToPath(pointerCoords.x, pointerCoords.y);
this.lassoTrail.addPointToPath(
pointerCoords.x,
pointerCoords.y,
event.shiftKey,
);
}
} else {
// It is very important to read this.state within each move event,

View file

@ -26,6 +26,7 @@ export class LassoTrail extends AnimatedTrail {
private worker: Worker | null = null;
private elementsSegments: Map<string, LineSegment<GlobalPoint>[]> | null =
null;
private keepPreviousSelection: boolean = false;
constructor(animationFrameHandler: AnimationFrameHandler, app: App) {
super(animationFrameHandler, app, {
@ -49,7 +50,7 @@ export class LassoTrail extends AnimatedTrail {
});
}
startPath(x: number, y: number) {
startPath(x: number, y: number, keepPreviousSelection = false) {
// clear any existing trails just in case
this.endPath();
@ -57,6 +58,16 @@ export class LassoTrail extends AnimatedTrail {
this.intersectedElements.clear();
this.enclosedElements.clear();
this.keepPreviousSelection = keepPreviousSelection;
if (!this.keepPreviousSelection) {
this.app.setState({
selectedElementIds: {},
selectedGroupIds: {},
selectedLinearElement: null,
});
}
try {
this.worker = new LassoWorker();
@ -80,6 +91,12 @@ export class LassoTrail extends AnimatedTrail {
return acc;
}, {} as Record<ExcalidrawElement["id"], true>);
if (this.keepPreviousSelection) {
for (const id of Object.keys(prevState.selectedElementIds)) {
nextSelectedElementIds[id] = true;
}
}
for (const [id] of Object.entries(nextSelectedElementIds)) {
const element = this.app.scene.getNonDeletedElement(id);
if (element && isFrameLikeElement(element)) {
@ -123,9 +140,11 @@ export class LassoTrail extends AnimatedTrail {
});
};
addPointToPath = (x: number, y: number) => {
addPointToPath = (x: number, y: number, keepPreviousSelection = false) => {
super.addPointToPath(x, y);
this.keepPreviousSelection = keepPreviousSelection;
this.app.setState({
lassoSelection: {
points: