File size: 2,483 Bytes
be26971
7d4e291
f7d189a
be26971
 
 
 
 
 
 
b4efffa
d11af81
b4efffa
 
be26971
b4efffa
7d4e291
be26971
 
7d4e291
 
be26971
 
 
dc37474
7d4e291
8239db2
b4efffa
f7d189a
 
be26971
f7d189a
 
 
 
 
 
 
 
 
dc37474
be26971
 
6a839c1
f7d189a
 
be26971
 
 
 
2fe0733
 
4df0c49
 
2fe0733
 
be26971
 
6a839c1
dc37474
 
f7d189a
 
b4efffa
 
 
 
 
 
 
be26971
2fe0733
 
 
4df0c49
 
2fe0733
 
 
 
 
 
 
 
6a839c1
93b70aa
 
 
 
be26971
 
 
7d4e291
2fe0733
 
 
 
 
 
8239db2
2fe0733
 
 
be26971
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<script lang="ts">
	import Frame from '$lib/Frame.svelte';
	import Move from '$lib/Icons/Move.svelte';
	import { drag } from 'd3-drag';
	import { select } from 'd3-selection';
	import { round } from '$lib/utils';

	import type { ZoomTransform } from 'd3-zoom';
	import { onMount } from 'svelte';

	import { useMyPresence } from '$lib/liveblocks';
	import { loadingState } from '$lib/store';
	const myPresence = useMyPresence();

	export let transform: ZoomTransform;
	export let color = 'black';
	export let interactive = false;

	let position = {
		x: 768,
		y: 768
	};

	let frameElement: HTMLDivElement;
	let isDragging = false;
	$: prompt = $myPresence?.currentPrompt;
	$: isLoading = $myPresence?.isLoading || false;

	let offsetX = 0;
	let offsetY = 0;
	onMount(() => {
		function dragstarted(event: Event) {
			const rect = (event.sourceEvent.target as HTMLElement).getBoundingClientRect();
			if (event.sourceEvent instanceof TouchEvent) {
				offsetX = event.sourceEvent.targetTouches[0].pageX - rect.left;
				offsetY = event.sourceEvent.targetTouches[0].pageY - rect.top;
			} else {
				offsetX = event.sourceEvent.pageX - rect.left;
				offsetY = event.sourceEvent.pageY - rect.top;
			}
			isDragging = true;
		}

		function dragged(event: Event) {
			const x = round(transform.invertX(event.x - offsetX));
			const y = round(transform.invertY(event.y - offsetY));
			position = {
				x,
				y
			};
			myPresence.update({
				cursor: {
					x: transform.invertX(event.x),
					y: transform.invertY(event.y)
				}
			});
		}

		function dragended(event: Event) {
			isDragging = false;

			const x = round(transform.invertX(event.x - offsetX));
			const y = round(transform.invertY(event.y - offsetY));

			myPresence.update({
				frame: {
					x,
					y
				}
			});
		}
		function handlePointerMove(event: PointerEvent) {
			myPresence.update({
				cursor: {
					x: transform.invertX(event.clientX),
					y: transform.invertY(event.clientY)
				}
			});
		}
		function handlePointerLeave() {
			myPresence.update({
				cursor: null
			});
		}
		const dragHandler = drag().on('start', dragstarted).on('drag', dragged).on('end', dragended);
		select(frameElement)
			.call(dragHandler as any)
			.on('pointermove', handlePointerMove)
			.on('pointerleave', handlePointerLeave);
	});
</script>

<div bind:this={frameElement}>
	<Frame
		{color}
		{position}
		loadingState={$loadingState}
		{prompt}
		{transform}
		{isLoading}
		{isDragging}
		{interactive}
	/>
</div>