aboutsummaryrefslogtreecommitdiff
path: root/apps/web/lib/drophelpers.ts
blob: 9094da6e3660dff87bd5fee4c03ec67f385e0a10 (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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import {
	Editor,
	TLBookmarkShape,
	TLShapePartial,
	Vec,
	VecLike,
	createShapeId,
} from "tldraw";

export function createEmptyBookmarkShape(
	editor: Editor,
	url: string,
	position: VecLike,
): TLBookmarkShape {
	const partial: TLShapePartial = {
		id: createShapeId(),
		type: "bookmark",
		x: position.x - 150,
		y: position.y - 160,
		opacity: 1,
		props: {
			assetId: null,
			url,
		},
	};

	editor.batch(() => {
		editor.createShapes([partial]).select(partial.id);
		centerSelectionAroundPoint(editor, position);
	});

	return editor.getShape(partial.id) as TLBookmarkShape;
}

function centerSelectionAroundPoint(editor: Editor, position: VecLike) {
	// Re-position shapes so that the center of the group is at the provided point
	const viewportPageBounds = editor.getViewportPageBounds();
	let selectionPageBounds = editor.getSelectionPageBounds();

	if (selectionPageBounds) {
		const offset = selectionPageBounds!.center.sub(position);

		editor.updateShapes(
			editor.getSelectedShapes().map((shape) => {
				const localRotation = editor
					.getShapeParentTransform(shape)
					.decompose().rotation;
				const localDelta = Vec.Rot(offset, -localRotation);
				return {
					id: shape.id,
					type: shape.type,
					x: shape.x! - localDelta.x,
					y: shape.y! - localDelta.y,
				};
			}),
		);
	}

	// Zoom out to fit the shapes, if necessary
	selectionPageBounds = editor.getSelectionPageBounds();
	if (
		selectionPageBounds &&
		!viewportPageBounds.contains(selectionPageBounds)
	) {
		editor.zoomToSelection();
	}
}