summaryrefslogtreecommitdiff
path: root/apps/web/src/lib/selection/hit-testing.ts
blob: ba086425ccd2f9a7dbe390e65d9085bed26fd27c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
function isIntersecting({
	selectionRect,
	itemRect,
}: {
	selectionRect: DOMRect;
	itemRect: DOMRect;
}) {
	return !(
		itemRect.right < selectionRect.left ||
		itemRect.left > selectionRect.right ||
		itemRect.bottom < selectionRect.top ||
		itemRect.top > selectionRect.bottom
	);
}

function createSelectionRect({
	startPos,
	currentPos,
}: {
	startPos: { x: number; y: number };
	currentPos: { x: number; y: number };
}) {
	return new DOMRect(
		Math.min(startPos.x, currentPos.x),
		Math.min(startPos.y, currentPos.y),
		Math.abs(currentPos.x - startPos.x),
		Math.abs(currentPos.y - startPos.y),
	);
}

export function resolveElementIntersections({
	startPos,
	currentPos,
	elements,
}: {
	startPos: { x: number; y: number };
	currentPos: { x: number; y: number };
	elements: Map<string, HTMLElement>;
}) {
	const selectionRect = createSelectionRect({ startPos, currentPos });

	return [...elements.entries()]
		.filter(([, element]) =>
			isIntersecting({
				selectionRect,
				itemRect: element.getBoundingClientRect(),
			}),
		)
		.map(([id]) => id);
}