-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
169 lines (146 loc) · 3.98 KB
/
script.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
const POPUP_TYPES = {
ERROR: 0,
SELECT: 1,
};
let showingVideo = false;
async function main() {
// Hydrate buttons
hydrate();
// Check for permission to use media devices
let permission = await getPermission();
if (!permission) {
configurePopup(POPUP_TYPES.ERROR);
setErrorMessage(`Unable to access your device's camera. Please enable camera permission in your browser's settings in order to use this site.`);
showPopup();
return;
}
// Permission has been granted! Show device selector
await showDevicesPrompt();
}
/**
* @returns {Boolean} - True if permission was granted
*/
async function getPermission() {
try {
await navigator.mediaDevices.getUserMedia({video: true, audio: true}); // Request to get permission
return true;
} catch (_) {
return false;
}
}
async function showDevicesPrompt() {
hideSettings();
showingVideo = false;
let devices = await navigator.mediaDevices.enumerateDevices();
devices = devices.filter(d => d.kind == 'videoinput');
if (devices.length == 0) {
configurePopup(POPUP_TYPES.ERROR);
setErrorMessage(`No camera devices detected! Permission should be granted, is your webcam connected properly?`);
showPopup();
}
setSelectElement(devices);
configurePopup(POPUP_TYPES.SELECT);
showPopup();
}
/**
* @param {String} id
*/
async function loadCamera(id) {
hidePopup();
let stream = await navigator.mediaDevices.getUserMedia({
video: {
deviceId: id,
}
});
el('webcam').srcObject = stream;
el('webcam').play();
// Add settings
showSettings();
showingVideo = true;
}
function setSelectElement(devices) {
const select = el('device-select');
select.replaceChildren(); // Remove existing options
for (let device of devices) {
let option = document.createElement('option');
option.value = device.deviceId;
option.innerText = device.label;
select.appendChild(option);
}
}
function hydrate() {
el('popup-close').addEventListener('click', hidePopup);
el('refresh-button').addEventListener('click', () => {window.location.reload()});
el('submit-button').addEventListener('click', () => {
loadCamera(el('device-select').value);
});
el('settings').addEventListener('click', () => {showDevicesPrompt()});
let idleTimer = undefined;
el('webcam').addEventListener('pointermove', () => {
if (showingVideo) {
showSettings();
clearTimeout(idleTimer);
idleTimer = setTimeout(() => {
hideSettings();
}, 2000);
}
});
}
/**
* @param {String} msg
*/
function setErrorMessage(msg) {
el('error-span').innerText = msg;
}
function showPopup() {
const div = el('popup-div');
div.style.top = '6rem';
showMask();
}
function hidePopup() {
const div = el('popup-div');
div.style.top = '-20rem';
hideMask();
}
function showSettings() {
const set = el('settings');
set.style.bottom = '1rem';
}
function hideSettings() {
const set = el('settings');
set.style.bottom = '-6rem';
}
function showMask() {
const mask = el('mask');
mask.style.opacity = '0.7';
mask.style.pointerEvents = 'auto';
}
function hideMask() {
const mask = el('mask');
mask.style.opacity = '0.0';
mask.style.pointerEvents = 'none';
}
/**
* @param {POPUP_TYPES} type
*/
function configurePopup(type) {
const popups = ['popup-content-error', 'popup-content-select'];
for (let name of popups) el(name).style.display = 'none'; // Hide all pop-up messages
switch (type) {
case POPUP_TYPES.ERROR:
el(popups[0]).style.display = '';
break;
case POPUP_TYPES.SELECT:
el(popups[1]).style.display = '';
break;
}
}
/**
* @param {String} e
* @returns {HTMLElement}
*/
function el(e) {
return document.getElementById(e);
}
// Start main
main();