-
Notifications
You must be signed in to change notification settings - Fork 0
/
gamepads.js
126 lines (115 loc) · 4.29 KB
/
gamepads.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
114
115
116
117
118
119
120
121
122
123
124
125
// TODO: gamepad button/axis display doesn't go away when controller disconnects
// TODO: right-click menu on gamepad list to allow enabling/disabling sending controllers
// TODO: show display for first gamepad when it connects
function getGamepads() {
return Array.from(navigator.getGamepads()).filter(gamepad => gamepad);
}
function getSortedGamepads() {
var sortedGamepads = [];
$("#gamepad-list #gamepad").each(function() {
sortedGamepads.push(getGamepads().find(gamepad => gamepad.index == $(this).val()));
});
return sortedGamepads;
}
function anyGamepadsConnected() {
return Boolean(getGamepads().length);
}
function getSelectedGamepad() {
var index = $("#gamepad-list .active").val();
return getGamepads().find(gamepad => gamepad.index == index);
}
function addGamepadLI(text, isGamepad, index) {
$("#gamepad-list").append(
"<li class=\"collection-item\" id=\"" + (isGamepad ? "gamepad" : "default")
+ "\" value=\"" + index + "\" style=\"white-space: nowrap; max-width: "
+ $("#gamepad-list").css("width") + "; overflow: hidden; text-overflow: ellipsis\">"
+ text + "</li>");
if (isGamepad) $("#gamepad-list").children().last().click(function() {
if ($(this).hasClass("active")) {
$(this).removeClass("active");
clearGamepadState();
} else {
$("#gamepad-list").children("#gamepad").removeClass("active");
$(this).addClass("active");
}
});
}
function updateGamepads() {
$("#gamepad-list").children().remove();
if (anyGamepadsConnected()) getGamepads().forEach(gamepad => {
addGamepadLI(getFriendlyGamepadId(gamepad), true, gamepad.index)
});
else addGamepadLI("Connect a controller or push a button");
}
function getFriendlyGamepadId(gamepad) {
return gamepad.id.substring(0, gamepad.id.indexOf('(') - 1);
}
// TODO: can we do this only when state changes maybe?
function renderGamepadState() {
var gamepad = getSelectedGamepad();
if (!gamepad) return;
clearGamepadState();
var context = $("#gamepad-state").get(0).getContext("2d");
context.font = "14px Arial" // TODO font
context.textBaseline = "top";
context.fillStyle = "white";
context.fillText("Axes", 20, 10);
const startY = 40;
const gapY = 20;
var col = 0;
gamepad.axes.forEach(axis => {
context.beginPath();
context.moveTo(20, startY + col * gapY);
context.lineTo(100, startY + col * gapY);
context.lineWidth = "15";
context.strokeStyle = "grey";
context.stroke();
context.beginPath();
context.moveTo(20, startY + col * gapY);
context.lineTo(axis * 40 + 60, startY + col * gapY);
context.lineWidth = "15";
context.strokeStyle = "green";
context.stroke();
context.font = "14px Arial"
context.textBaseline = "middle";
context.fillStyle = "white";
context.fillText(col + ": " + axis.toFixed(2), 22, startY + col * gapY);
col++;
});
context.font = "14px Arial"
context.textBaseline = "top";
context.fillStyle = "white";
context.fillText("Buttons", 140, 10);
const startX = 140;
const gapX = 40;
const maxButtonsPerCol = 5;
var col = 0;
var row = 0;
gamepad.buttons.forEach(button => {
context.beginPath();
context.moveTo(startX + row * gapX, startY + col * gapY);
context.lineTo(startX + row * gapX + 20, startY + col * gapY);
context.lineWidth = "15";
context.strokeStyle = button.value ? "green" : "grey";
context.stroke();
context.font = "14px Arial"
context.textBaseline = "middle";
context.fillStyle = "white";
var label = col + row * maxButtonsPerCol;
var textOffset = context.measureText(label).width * 0.5;
context.fillText(label, startX + row * gapX + 10 - textOffset, startY + col * gapY);
if (++col >= maxButtonsPerCol) {
row++;
col = 0;
}
});
}
function clearGamepadState() {
var context = $("#gamepad-state").get(0).getContext("2d");
context.clearRect(0, 0, $("#gamepad-state")[0].width, $("#gamepad-state")[0].height);
}
module.exports = {
update: updateGamepads,
renderState: renderGamepadState,
getSorted: getSortedGamepads
}