Update set selection to select items if select box is within the element

This commit is contained in:
Gasim Gasimzada 2020-01-09 18:40:19 +04:00
parent 1ea72e9134
commit 6955a920a2
2 changed files with 107 additions and 6 deletions

View file

@ -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;
};

View file

@ -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);
element.isSelected = if (element.type === "selection") {
element.type !== "selection" && element.isSelected = false;
selectionX1 <= elementX1 && } else if (element.type === "arrow") {
selectionY1 <= elementY1 && if (
selectionX2 >= elementX2 && selectionX1 < elementX1 &&
selectionY2 >= elementY2; 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 =
testLineSegmentIntersect(line1, target) ||
testLineSegmentIntersect(line2, target) ||
testLineSegmentIntersect(line3, target) ||
testLineSegmentIntersect(line4, target);
}
} else {
element.isSelected = !(
(selectionX1 < elementX1 && selectionX2 < elementX1) ||
(selectionX1 > elementX2 && selectionX2 > elementX2) ||
(selectionY1 < elementY1 && selectionY2 < elementY1) ||
(selectionY1 > elementY2 && selectionY2 > elementY2)
);
}
}); });
} }