mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Update set selection to select items if select box is within the element
This commit is contained in:
parent
1ea72e9134
commit
6955a920a2
2 changed files with 107 additions and 6 deletions
42
src/math.ts
42
src/math.ts
|
@ -52,3 +52,45 @@ export function rotate(
|
||||||
(x1 - x2) * Math.sin(angle) + (y1 - y2) * Math.cos(angle) + y2
|
(x1 - x2) * Math.sin(angle) + (y1 - y2) * Math.cos(angle) + y2
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Line {
|
||||||
|
x1: number;
|
||||||
|
x2: number;
|
||||||
|
y1: number;
|
||||||
|
y2: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Point {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const vcp = (a: Point, b: Point) => {
|
||||||
|
return a.x * b.y - a.y * b.x;
|
||||||
|
};
|
||||||
|
|
||||||
|
//https://stackoverflow.com/a/565282/816116
|
||||||
|
export const testLineSegmentIntersect = (l1: Line, l2: Line) => {
|
||||||
|
const r: Point = { x: l1.x2 - l1.x1, y: l1.y2 - l1.y1 };
|
||||||
|
const s: Point = { x: l2.x2 - l2.x1, y: l2.y2 - l2.y1 };
|
||||||
|
|
||||||
|
// r x s
|
||||||
|
const div = vcp(r, s);
|
||||||
|
|
||||||
|
// q - p
|
||||||
|
const sub = { x: l2.x1 - l1.x1, y: l2.y1 - l1.y1 };
|
||||||
|
|
||||||
|
// t = (q - p) x s / (r x s)
|
||||||
|
const t = vcp(sub, s) / div;
|
||||||
|
|
||||||
|
// u = (q - p) x r / (r x s)
|
||||||
|
const u = vcp(sub, r) / div;
|
||||||
|
|
||||||
|
if (div === 0 && vcp(sub, s) === 0) {
|
||||||
|
return true;
|
||||||
|
} else if (div !== 0 && t >= 0 && t <= 1 && u >= 0 && u <= 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { ExcalidrawElement } from "../element/types";
|
import { ExcalidrawElement } from "../element/types";
|
||||||
import { getElementAbsoluteCoords } from "../element";
|
import { getElementAbsoluteCoords } from "../element";
|
||||||
|
import { testLineSegmentIntersect } from "../math";
|
||||||
|
|
||||||
export function setSelection(
|
export function setSelection(
|
||||||
elements: ExcalidrawElement[],
|
elements: ExcalidrawElement[],
|
||||||
|
@ -18,12 +19,70 @@ export function setSelection(
|
||||||
elementX2,
|
elementX2,
|
||||||
elementY2
|
elementY2
|
||||||
] = getElementAbsoluteCoords(element);
|
] = getElementAbsoluteCoords(element);
|
||||||
|
if (element.type === "selection") {
|
||||||
|
element.isSelected = false;
|
||||||
|
} else if (element.type === "arrow") {
|
||||||
|
if (
|
||||||
|
selectionX1 < elementX1 &&
|
||||||
|
selectionX2 > elementX2 &&
|
||||||
|
selectionY1 < elementY1 &&
|
||||||
|
selectionY2 > elementY2
|
||||||
|
) {
|
||||||
|
element.isSelected = true;
|
||||||
|
} else {
|
||||||
|
// lt -> lb
|
||||||
|
const line1 = {
|
||||||
|
x1: selectionX1,
|
||||||
|
y1: selectionY1,
|
||||||
|
x2: selectionX1,
|
||||||
|
y2: selectionY2
|
||||||
|
};
|
||||||
|
|
||||||
|
// rt -> rb
|
||||||
|
const line2 = {
|
||||||
|
x1: selectionX2,
|
||||||
|
y1: selectionY1,
|
||||||
|
x2: selectionX2,
|
||||||
|
y2: selectionY2
|
||||||
|
};
|
||||||
|
|
||||||
|
// lt -> rt
|
||||||
|
const line3 = {
|
||||||
|
x1: selectionX1,
|
||||||
|
y1: selectionY1,
|
||||||
|
x2: selectionX2,
|
||||||
|
y2: selectionY1
|
||||||
|
};
|
||||||
|
|
||||||
|
// lb -> rb
|
||||||
|
const line4 = {
|
||||||
|
x1: selectionX1,
|
||||||
|
y1: selectionY2,
|
||||||
|
x2: selectionX2,
|
||||||
|
y2: selectionY2
|
||||||
|
};
|
||||||
|
|
||||||
|
const target = {
|
||||||
|
x1: elementX1,
|
||||||
|
y1: elementY1,
|
||||||
|
x2: elementX2,
|
||||||
|
y2: elementY2
|
||||||
|
};
|
||||||
|
|
||||||
element.isSelected =
|
element.isSelected =
|
||||||
element.type !== "selection" &&
|
testLineSegmentIntersect(line1, target) ||
|
||||||
selectionX1 <= elementX1 &&
|
testLineSegmentIntersect(line2, target) ||
|
||||||
selectionY1 <= elementY1 &&
|
testLineSegmentIntersect(line3, target) ||
|
||||||
selectionX2 >= elementX2 &&
|
testLineSegmentIntersect(line4, target);
|
||||||
selectionY2 >= elementY2;
|
}
|
||||||
|
} else {
|
||||||
|
element.isSelected = !(
|
||||||
|
(selectionX1 < elementX1 && selectionX2 < elementX1) ||
|
||||||
|
(selectionX1 > elementX2 && selectionX2 > elementX2) ||
|
||||||
|
(selectionY1 < elementY1 && selectionY2 < elementY1) ||
|
||||||
|
(selectionY1 > elementY2 && selectionY2 > elementY2)
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue