-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjoystickvr2.js
113 lines (90 loc) · 3.77 KB
/
joystickvr2.js
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
106
107
108
109
110
111
112
113
class JoystickVR2
{
// stickID: ID of HTML element (representing joystick) that will be dragged
// maxDistance: maximum amount joystick can move in any direction
// deadzone: joystick must move at least this amount from origin to register value change
constructor( stickID, maxDistance, deadzone )
{
let stick = document.getElementById("stick2");
// location from which drag begins, used to calculate offsets
this.dragStart = null;
// track touch identifier in case multiple joysticks present
this.touchId = null;
this.active = false;
this.value = { x: 0, y: 0 };
let self = this;
function handleDown(event)
{
self.active = true;
// all drag movements are instantaneous
stick.style.transition = '0s';
// touch event fired before mouse event; prevent redundant mouse event from firing
event.preventDefault();
if (event.changedTouches)
self.dragStart = { x: event.changedTouches[0].clientX, y: event.changedTouches[0].clientY };
else
self.dragStart = { x: event.clientX, y: event.clientY };
// if this is a touch event, keep track of which one
if (event.changedTouches)
self.touchId = event.changedTouches[0].identifier;
let drone = document.getElementById("droneobject");
// drone.removeAttribute("animation");
}
function handleMove(event)
{
if ( !self.active ) return;
// if this is a touch event, make sure it is the right one
// also handle multiple simultaneous touchmove events
let touchmoveId = null;
if (event.changedTouches)
{
for (let i = 0; i < event.changedTouches.length; i++)
{
if (self.touchId == event.changedTouches[i].identifier)
{
touchmoveId = i;
event.clientX = event.changedTouches[i].clientX;
event.clientY = event.changedTouches[i].clientY;
}
}
if (touchmoveId == null) return;
}
const xDiff = event.clientX - self.dragStart.x;
const yDiff = event.clientY - self.dragStart.y;
const angle = Math.atan2(yDiff, xDiff);
const distance = Math.min(maxDistance, Math.hypot(xDiff, yDiff));
const xPosition = distance * Math.cos(angle);
const yPosition = distance * Math.sin(angle);
// move stick image to new position
stick.style.transform = `translate3d(${xPosition}px, ${yPosition}px, 0px)`;
// deadzone adjustment
const distance2 = (distance < deadzone) ? 0 : maxDistance / (maxDistance - deadzone) * (distance - deadzone);
const xPosition2 = distance2 * Math.cos(angle);
const yPosition2 = distance2 * Math.sin(angle);
const xPercent = parseFloat((xPosition2 / maxDistance).toFixed(4));
const yPercent = parseFloat((yPosition2 / maxDistance).toFixed(4));
self.value = { x: xPercent, y: yPercent };
}
function handleUp(event)
{
if ( !self.active ) return;
// if this is a touch event, make sure it is the right one
if (event.changedTouches && self.touchId != event.changedTouches[0].identifier) return;
// transition the joystick position back to center
stick.style.transition = '.2s';
stick.style.transform = `translate3d(0px, 0px, 0px)`;
// reset everything
self.value = { x: 0, y: 0 };
self.touchId = null;
self.active = false;
// let drone = document.getElementById("droneobject");
// drone.setAttribute("animation", "dur: 200; property: rotation; to: 0 0 0;");
}
stick.addEventListener('mousedown', handleDown);
stick.addEventListener('touchstart', handleDown);
document.addEventListener('mousemove', handleMove, {passive: false});
document.addEventListener('touchmove', handleMove, {passive: false});
document.addEventListener('mouseup', handleUp);
document.addEventListener('touchend', handleUp);
}
}