overhaul permission system

This commit is contained in:
Bit Borealis 2023-10-05 08:58:31 +00:00
parent b53d410049
commit 246401baa6
Signed by: theotheroracle
GPG Key ID: 2D816A2DCA6E5649
4 changed files with 211 additions and 29 deletions

View File

@ -18,3 +18,19 @@ h3 {
.combo-switch [type=range] {
flex-grow: 1;
}
#gyroBox {
display: none;
}
#accelBox {
display: none;
}
#orientBox {
display: none;
}
#unsupported-warning {
display: none;
}

View File

@ -38,11 +38,26 @@ h1 {
text-align: center;
}
.warning {
background-color: var(--secondary);
border-radius: 10px;
padding: 20px;
font-weight: bold;
margin: auto;
width: 75%;
display: block;
}
.button-box a:focus {
border: 15px solid var(--foreground);
outline: none;
}
p {
text-align: center;
font-size: large;
}
body {
background-color: var(--background);
font-family: sans-serif;

View File

@ -17,7 +17,7 @@ function connect_ws() {
ws.binaryType = "arraybuffer";
ws.addEventListener("open", () => {
const message = UpdateRequest.create({ paramRefresh: true});
const message = UpdateRequest.create({ paramRefresh: true });
const request = UpdateRequest.encode(message).finish();
if (socket) {
socket.send(request);
@ -79,30 +79,73 @@ switches.forEach((switchElement) => {
// Declare a global interface for the window object
declare global {
interface Window {
Accelerometer: any;
Gyroscope: any;
AbsoluteOrientationSensor: any;
}
}
if (window.AbsoluteOrientationSensor) {
// Create an AbsoluteOrientationSensor object
const sensor = new window.AbsoluteOrientationSensor({ frequency: 60, referenceFrame: 'device' });
function show(element: HTMLElement) {
if (element) {
element.style.display = "flex";
}
}
Promise.all([
// @ts-ignore
navigator.permissions.query({ name: "accelerometer" }),
// @ts-ignore
navigator.permissions.query({ name: "magnetometer" }),
// @ts-ignore
navigator.permissions.query({ name: "gyroscope" }),
]).then((results: PermissionStatus[]) => {
if (!results.every((result) => result.state === "granted")) {
console.log("No permissions to use AbsoluteOrientationSensor.");
function checkPerms() {
const permissionsToCheck = ['accelerometer', 'gyroscope', 'magnetometer'];
const permissionPromises = permissionsToCheck.map(permissionName => {
if (!navigator.permissions.query) {
console.log('Permissions API not supported');
return Promise.resolve(null);
}
});
return navigator.permissions.query({ name: permissionName as any })
.catch(error => {
console.log(`Permission not supported: ${permissionName}`);
return null;
});
}).filter(Boolean);
// Create a renderer
Promise.all(permissionPromises).then((results: (PermissionStatus | null)[]) => {
const warning = document.getElementById("unsupported-warning") as HTMLElement;
const gyro = document.getElementById("gyroBox") as HTMLElement;
const accel = document.getElementById("accelBox") as HTMLElement;
const orient = document.getElementById("orientBox") as HTMLElement;
let isAccelerometerSupported = "Accelerometer" in window;
let isGyroscopeSupported = "Gyroscope" in window;
let isAbsoluteOrientationSensorSupported = "AbsoluteOrientationSensor" in window;
if (!results.every((result) => result !== null && result.state === "granted")) {
show(warning)
console.log("shown")
} else {
if (isAccelerometerSupported) {
console.log("Accelerometer is supported.");
show(accel)
sensorStart("Accelerometer", "accelBox", "accel");
}
if (isGyroscopeSupported) {
console.log("Gyroscope is supported.");
show(gyro)
sensorStart("Gyroscope", "gyroBox", "gyro");
}
if (isAccelerometerSupported) {
console.log("AbsoluteOrientationSensor is supported.");
show(orient)
sensorStart("AbsoluteOrientationSensor", "orientBox", "orient");
}
if (!isAccelerometerSupported && !isGyroscopeSupported && !isAbsoluteOrientationSensorSupported) {
console.log("None of the interfaces are supported.");
show(warning)
}
}
})
};
function setupThreeJsScene() {
const sceneSize = new THREE.Vector3(100, 100, 100);
const renderer = new THREE.WebGLRenderer({alpha: true});
const renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(sceneSize.x, sceneSize.y);
renderer.setPixelRatio(window.devicePixelRatio / 2.5);
const scene = new THREE.Scene();
@ -110,17 +153,105 @@ if (window.AbsoluteOrientationSensor) {
const axes = new THREE.AxesHelper(5);
scene.add(axes);
const camera = new THREE.PerspectiveCamera(75, sceneSize.x/sceneSize.y, 0.1, 1000);
const camera = new THREE.PerspectiveCamera(75, sceneSize.x / sceneSize.y, 0.1, 1000);
camera.translateOnAxis(scene.up.clone(), 2);
camera.lookAt(axes.position);
return { renderer, scene, axes, camera };
}
function handleSensorReading(
sensor: any,
scene: THREE.Scene,
calibratedDirection: THREE.Vector3 | null,
currentDirection: THREE.Vector3 | null,
relativeDirection: THREE.Vector3 | null,
render: (direction: THREE.Quaternion | null) => void
) {
sensor.addEventListener('reading', () => {
// Apply the sensor's quaternion to the vector
const orientation = new THREE.Quaternion(...sensor.quaternion).normalize();
// Set the initial orientation if it's not set already
currentDirection = scene.up.clone().applyQuaternion(orientation);
if (!calibratedDirection) {
calibratedDirection = currentDirection;
console.log("cal", calibratedDirection);
}
relativeDirection = calibratedDirection.clone().sub(currentDirection).normalize();
const relativeOrientation = new THREE.Quaternion().setFromUnitVectors(calibratedDirection, currentDirection);
render(relativeOrientation);
});
}
type sensorType = "Accelerometer" | "Gyroscope" | "AbsoluteOrientationSensor";
const sensorConstructors: { [K in sensorType]: any } = {
"Accelerometer": window.Accelerometer,
"Gyroscope": window.Gyroscope,
"AbsoluteOrientationSensor": window.AbsoluteOrientationSensor
};
// Then in your sensorStart function:
function sensorStart(sensorName: sensorType, boxId: string, checkboxId: string) {
const SensorConstructor = sensorConstructors[sensorName];
if (SensorConstructor) {
const sensor = new SensorConstructor({ frequency: 60, referenceFrame: 'device' });
// Set up Three.js scene
const { renderer, scene, axes, camera } = setupThreeJsScene();
// Define render function
const render = (direction: THREE.Quaternion | null) => {
if (!direction) {
direction = new THREE.Quaternion().identity();
}
axes.setRotationFromQuaternion(direction);
renderer.render(scene, camera);
}
// Initialize default orientation
let calibratedDirection: THREE.Vector3 | null = null;
let currentDirection: THREE.Vector3 | null = null;
let relativeDirection: THREE.Vector3 | null = null;
// Handle sensor readings
handleSensorReading(sensor, scene, calibratedDirection, currentDirection, relativeDirection, render);
// Render the first frame
render(null);
} else {
console.log(`No constructor found for sensor: ${sensorName}`);
}
}
function gyroStart() {
// Create an AbsoluteOrientationSensor object
const sensor = new window.AbsoluteOrientationSensor({ frequency: 60, referenceFrame: 'device' });
// Create a renderer
const sceneSize = new THREE.Vector3(100, 100, 100);
const renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(sceneSize.x, sceneSize.y);
renderer.setPixelRatio(window.devicePixelRatio / 2.5);
const scene = new THREE.Scene();
const axes = new THREE.AxesHelper(5);
scene.add(axes);
const camera = new THREE.PerspectiveCamera(75, sceneSize.x / sceneSize.y, 0.1, 1000);
camera.translateOnAxis(scene.up.clone(), 2);
camera.lookAt(axes.position);
// Get the checkbox element
const gyroBox = document.getElementById("gyroBox");
const checkbox = document.getElementById('gyro') as HTMLInputElement;
const gyroBox = document.getElementById("gyroBox") as HTMLElement;
const checkbox = document.getElementById("gyro") as HTMLInputElement;
(gyroBox || document.body).appendChild(renderer.domElement);
gyroBox?.hidden == false;
show(gyroBox);
// Create an arrow
@ -195,7 +326,6 @@ if (window.AbsoluteOrientationSensor) {
// Render the first frame
render(null);
} else {
// Log a message to the console if AbsoluteOrientationSensor is not supported
console.log('AbsoluteOrientationSensor is not supported in this browser.');
}
checkPerms();

View File

@ -60,12 +60,33 @@
<input type="range" id="fr_size" name="freq_range" min="0" max="127">
</div>
</div>
</div>
<h1>Controls</h1>
<div class="flex-container">
<div class="button-box">
<div hidden class="combo-switch" id="gyroBox">
<input type="checkbox" id="gyro" name="tilt">
<h3>Tilt</h3>
<div id="debugGyro"></div>
</div>
<div hidden class="combo-switch" id="accelBox">
<input type="checkbox" id="accel" name="swing">
<h3>Swing</h3>
<div id="debugAccel"></div>
</div>
<div hidden class="combo-switch" id="orientBox">
<input type="checkbox" id="orient" name="move">
<h3>Move</h3>
<div id="debugOrient"></div>
</div>
<div hidden class="combo-switch" id="gyroBox">
<input type="checkbox" id="gyro" name="gyro">
<h3>Gyro</h3>
<div id="debugData"></div>
</div>
<p hidden class="warning" id="unsupported-warning">
Uh Oh! Seems like your device doesn't support any control options :(
You can still use the sliders above though !
</p>
</div>
</body>