Skip to content

Commit 9c50f98

Browse files
author
Max Carlson
committed
Add navigator html page to broadcast zoom/position events into supabase
1 parent b6545c8 commit 9c50f98

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

WebSites/spacetime/navigator.html

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<!DOCTYPE html>
2+
<html lang="en-us">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6+
<title>Spacecraft Navigator</title>
7+
<link rel="icon" type="image/png" href="thumbnail.png">
8+
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js"></script>
9+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
10+
</head>
11+
<body style="padding:0;margin:0;touch-action:none">
12+
<div id="target" style="height: 100vh"></div>
13+
<script>
14+
// Create a single supabase client for interacting with your database
15+
const client = supabase.createClient('https://gwodhwyvuftyrvbymmvc.supabase.co', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imd3b2Rod3l2dWZ0eXJ2YnltbXZjIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDIzNDkyMDMsImV4cCI6MjA1NzkyNTIwM30.APVpyOupY84gQ7c0vBZkY-GqoJRPhb4oD4Lcj9CEzlc')
16+
17+
const channel = client.channel("navigators")
18+
19+
let subscribed = false;
20+
channel.subscribe((status) => {
21+
console.log('subscribe', status)
22+
if (status === 'SUBSCRIBED') {
23+
subscribed = true;
24+
}
25+
})
26+
27+
// dummy log method
28+
const log = () => {};
29+
30+
// Global vars to cache event state
31+
const evCache = [];
32+
let prevDiff = -1;
33+
let prevX = 0;
34+
let prevY = 0;
35+
36+
function removeEvent(ev) {
37+
// Remove this event from the target's cache
38+
const index = evCache.findIndex(
39+
(cachedEv) => cachedEv.pointerId === ev.pointerId,
40+
);
41+
evCache.splice(index, 1);
42+
}
43+
44+
function pointerdownHandler(ev) {
45+
// The pointerdown event signals the start of a touch interaction.
46+
// This event is cached to support 2-finger gestures
47+
evCache.push(ev);
48+
log("pointerDown", ev);
49+
}
50+
51+
function pointermoveHandler(ev) {
52+
// This function implements a 2-pointer horizontal pinch/zoom gesture.
53+
//
54+
// If the distance between the two pointers has increased (zoom in),
55+
// the target element's background is changed to "pink" and if the
56+
// distance is decreasing (zoom out), the color is changed to "lightblue".
57+
//
58+
// This function sets the target element's border to "dashed" to visually
59+
// indicate the pointer's target received a move event.
60+
log("pointerMove", ev);
61+
// ev.target.style.border = "dashed";
62+
63+
// Find this event in the cache and update its record with this event
64+
const index = evCache.findIndex(
65+
(cachedEv) => cachedEv.pointerId === ev.pointerId,
66+
);
67+
evCache[index] = ev;
68+
69+
// If two pointers are down, check for pinch gestures
70+
if (evCache.length === 2) {
71+
// Calculate the distance between the two pointers
72+
const curDiff = Math.abs(evCache[0].clientX - evCache[1].clientX);
73+
74+
if (prevDiff > 0) {
75+
if (curDiff > prevDiff) {
76+
// The distance between the two pointers has increased
77+
log("Pinch moving OUT -> Zoom in", ev);
78+
ev.target.style.background = "pink";
79+
}
80+
if (curDiff < prevDiff) {
81+
// The distance between the two pointers has decreased
82+
log("Pinch moving IN -> Zoom out", ev);
83+
ev.target.style.background = "lightblue";
84+
}
85+
}
86+
87+
// Cache the distance for the next move event
88+
prevDiff = curDiff;
89+
} else if (evCache.length === 1) {
90+
// single pointer
91+
let relX = evCache[0].clientX - prevX;
92+
if (prevX === 0) relX = 0;
93+
let relY = evCache[0].clientY - prevY;
94+
if (prevY === 0) relY = 0;
95+
96+
prevX = evCache[0].clientX
97+
prevY = evCache[0].clientY
98+
99+
if (subscribed) {
100+
const payload = { x: relX, y: relY }
101+
console.log('sending ', payload)
102+
channel.send({
103+
type: 'broadcast',
104+
event: 'pos',
105+
payload,
106+
})
107+
}
108+
}
109+
}
110+
111+
function pointerupHandler(ev) {
112+
log(ev.type, ev);
113+
// Remove this pointer from the cache and reset the target's
114+
// background and border
115+
removeEvent(ev);
116+
ev.target.style.background = "white";
117+
// ev.target.style.border = "1px solid black";
118+
119+
// If the number of pointers down is less than two then reset diff tracker
120+
if (evCache.length < 2) {
121+
prevDiff = -1;
122+
}
123+
}
124+
125+
function wheelHandler(ev) {
126+
// prevent wheel from zooming
127+
if( ev.ctrlKey ) ev.preventDefault()
128+
const payload = { zoom: ev.deltaY}
129+
console.log('wheel', payload)
130+
channel.send({
131+
type: 'broadcast',
132+
event: 'zoom',
133+
payload,
134+
})
135+
return false
136+
}
137+
138+
window.addEventListener( 'wheel', wheelHandler, { passive: false })
139+
140+
// Install event handlers for the pointer target
141+
const el = document.getElementById("target");
142+
el.onpointerdown = pointerdownHandler;
143+
el.onpointermove = pointermoveHandler;
144+
145+
// Use same handler for pointer{up,cancel,out,leave} events since
146+
// the semantics for these events - in this app - are the same.
147+
el.onpointerup = pointerupHandler;
148+
el.onpointercancel = pointerupHandler;
149+
el.onpointerout = pointerupHandler;
150+
el.onpointerleave = pointerupHandler;
151+
</script>
152+
</body>
153+
</html>

0 commit comments

Comments
 (0)