-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathposition-probe.html
104 lines (95 loc) · 3.71 KB
/
position-probe.html
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
<m-group x="3" ry="30" y="4">
<m-position-probe range="7" debug="true" id="my-probe" interval="100"></m-position-probe>
<m-image id="canvas-view" rx="90" y="-3.5" collide="false" width="14" height="14"></m-image>
<m-group id="user-presence-holder"></m-group>
</m-group>
<script>
const connectedUsers = new Map();
const userPresenceHolder = document.getElementById("user-presence-holder");
const positionProbe = document.getElementById("my-probe");
function getOrCreateUser(connectionId, position, rotation) {
const user = connectedUsers.get(connectionId);
if (user) {
user.position = position;
user.rotation = rotation;
return user;
}
const userCube = document.createElement("m-cube");
userCube.setAttribute("collide", false);
userCube.setAttribute("width", 0.25);
userCube.setAttribute("height", 0.25);
userCube.setAttribute("depth", 0.25);
userCube.setAttribute("color", `#${Math.floor(Math.random() * 0xffffff).toString(16)}`);
userPresenceHolder.append(userCube);
const newUser = {
cube: userCube,
position,
rotation,
};
connectedUsers.set(connectionId, newUser);
return newUser;
}
function clearUser(connectionId) {
const user = connectedUsers.get(connectionId);
if (!user) return;
user.cube.remove();
connectedUsers.delete(connectionId);
}
function setCubePosition(connectionId, position, rotation) {
const user = getOrCreateUser(connectionId, position, rotation);
user.cube.setAttribute("x", position.x);
user.cube.setAttribute("y", position.y + 2);
user.cube.setAttribute("z", position.z);
user.cube.setAttribute("rx", rotation.x);
user.cube.setAttribute("ry", rotation.y);
user.cube.setAttribute("rz", rotation.z);
}
window.addEventListener("disconnected", (event) => {
const { connectionId } = event.detail;
clearUser(connectionId);
drawState();
});
positionProbe.addEventListener("positionenter", (event) => {
const { connectionId, elementRelative, documentRelative } = event.detail;
setCubePosition(connectionId, elementRelative.position, elementRelative.rotation);
drawState();
});
positionProbe.addEventListener("positionmove", (event) => {
const { connectionId, elementRelative, documentRelative } = event.detail;
/*
It's possible to receive an update without an explicit enter event if this user is already in the range of
this element when the document is reloaded. In this case, we need to create the user as if this is an
enter event.
*/
setCubePosition(connectionId, elementRelative.position, elementRelative.rotation);
drawState();
});
positionProbe.addEventListener("positionleave", (event) => {
const { connectionId } = event.detail;
clearUser(connectionId);
drawState();
});
const canvasView = document.getElementById("canvas-view");
const canvas = document.createElement("canvas");
canvas.width = 512;
canvas.height = 512;
const scale = 512/parseFloat(canvasView.getAttribute("width"));
const pointDrawSize = 64;
const halfPointDrawSize = pointDrawSize / 2;
const ctx = canvas.getContext("2d");
function drawState() {
ctx.clearRect(0, 0, 512, 512);
ctx.fillStyle = "red";
ctx.fillRect(128, 128, 128, 128);
ctx.fillStyle = "orange";
ctx.fillRect(256, 256, 128, 128);
ctx.fillStyle = "green";
for (const [connectionId, user] of connectedUsers) {
ctx.fillRect(256 + user.position.x * scale - halfPointDrawSize, 256 - user.position.z * scale - halfPointDrawSize, pointDrawSize, pointDrawSize);
}
ctx.strokeRect(0, 0, 512, 512);
const dataUri = canvas.toDataURL("image/png");
canvasView.setAttribute("src", dataUri);
}
drawState();
</script>