fixed some stuff with gyro

This commit is contained in:
Brandon Johnson
2026-01-26 11:18:32 -05:00
parent 19895401c1
commit de32cafd91
4 changed files with 56 additions and 44 deletions

View File

@@ -174,56 +174,60 @@
if (!field || !select || (!hasTouch && !hasGyro)) {
field?.classList.add('hidden');
} else {
field.classList.remove('hidden');
const options = [];
if (hasGyro) options.push({ value: 'gyro', label: 'Gyro' });
if (hasTouch) options.push({ value: 'touch', label: 'Touchscreen' });
select.replaceChildren(...options.map((opt) => {
const el = document.createElement('option');
el.value = opt.value;
el.textContent = opt.label;
return el;
}));
const key = 'smb_control_mode';
const saved = localStorage.getItem(key);
if (saved && options.some((o) => o.value === saved)) {
select.value = saved;
if (options.length === 0) {
field.classList.add('hidden');
} else {
select.value = hasTouch ? 'touch' : 'gyro';
localStorage.setItem(key, select.value);
}
field.classList.remove('hidden');
select.innerHTML = '';
for (const opt of options) {
const el = document.createElement('option');
el.value = opt.value;
el.textContent = opt.label;
select.appendChild(el);
}
const syncGyroUi = () => {
const showGyro = select.value === 'gyro';
gyroButton?.classList.toggle('hidden', !showGyro);
gyroHelper?.classList.toggle('hidden', !showGyro);
};
const key = 'smb_control_mode';
const saved = localStorage.getItem(key);
if (saved && options.some((o) => o.value === saved)) {
select.value = saved;
} else {
select.value = hasTouch ? 'touch' : 'gyro';
localStorage.setItem(key, select.value);
}
syncGyroUi();
const syncGyroUi = () => {
const showGyro = select.value === 'gyro';
gyroButton?.classList.toggle('hidden', !showGyro);
gyroHelper?.classList.toggle('hidden', !showGyro);
};
select.addEventListener('change', async () => {
let next = select.value;
syncGyroUi();
// iOS: gyro requires a user-gesture permission prompt.
if (next === 'gyro' && typeof window.DeviceOrientationEvent?.requestPermission === 'function') {
try {
const result = await window.DeviceOrientationEvent.requestPermission();
if (result !== 'granted') {
select.addEventListener('change', async () => {
let next = select.value;
// iOS: gyro requires a user-gesture permission prompt.
if (next === 'gyro' && typeof window.DeviceOrientationEvent?.requestPermission === 'function') {
try {
const result = await window.DeviceOrientationEvent.requestPermission();
if (result !== 'granted') {
next = hasTouch ? 'touch' : 'gyro';
select.value = next;
}
} catch {
next = hasTouch ? 'touch' : 'gyro';
select.value = next;
}
} catch {
next = hasTouch ? 'touch' : 'gyro';
select.value = next;
}
}
localStorage.setItem(key, next);
syncGyroUi();
});
localStorage.setItem(key, next);
syncGyroUi();
});
}
}
</script>

View File

@@ -169,7 +169,7 @@ export class Input {
const MAX_ANGLE = 25;
const x = (gamma - this.gyro.baseGamma) / MAX_ANGLE;
const y = (this.gyro.baseBeta - beta) / MAX_ANGLE;
const y = (beta - this.gyro.baseBeta) / MAX_ANGLE;
this.gyro.value.x = clamp(x, -1, 1);
this.gyro.value.y = clamp(y, -1, 1);
},

View File

@@ -58,6 +58,7 @@ const hudCanvas = document.getElementById('hud-canvas') as HTMLCanvasElement;
const overlay = document.getElementById('overlay') as HTMLElement;
const stageFade = document.getElementById('stage-fade') as HTMLElement;
const mobileMenuButton = document.getElementById('mobile-menu-button') as HTMLButtonElement | null;
const controlModeField = document.getElementById('control-mode-field') as HTMLElement | null;
const controlModeSelect = document.getElementById('control-mode') as HTMLSelectElement | null;
const gyroRecalibrateButton = document.getElementById('gyro-recalibrate') as HTMLButtonElement | null;
const gyroHelper = document.getElementById('gyro-helper') as HTMLElement | null;
@@ -646,6 +647,8 @@ function bindVolumeControl(
function renderFrame(now: number) {
requestAnimationFrame(renderFrame);
updateGyroHelper();
if (!running || !viewerInput || !camera) {
lastTime = now;
return;
@@ -679,7 +682,6 @@ function renderFrame(now: number) {
resizeCanvasToDisplaySize(canvas);
resizeCanvasToDisplaySize(hudCanvas);
hudRenderer.resize(hudCanvas.width, hudCanvas.height);
updateGyroHelper();
if (game.loadingStage) {
const hudDelta = now - lastHudTime;
@@ -735,8 +737,12 @@ function updateGyroHelper() {
if (!controlModeSelect || !gyroHelper || !gyroHelperFrame) {
return;
}
const showGyro = controlModeSelect.value === 'gyro';
const hasGyroOption = Array.from(controlModeSelect.options).some((opt) => opt.value === 'gyro');
const showGyro = hasGyroOption && controlModeSelect.value === 'gyro';
gyroHelper.classList.toggle('hidden', !showGyro);
if (controlModeField) {
controlModeField.classList.toggle('hidden', controlModeSelect.options.length === 0);
}
if (!showGyro) {
return;
}
@@ -745,8 +751,10 @@ function updateGyroHelper() {
gyroHelperFrame.style.opacity = '0.5';
return;
}
const x = clamp(-sample.beta, -30, 30);
const y = clamp(sample.gamma, -30, 30);
const deltaBeta = sample.baselineSet ? sample.beta - sample.baseBeta : sample.beta;
const deltaGamma = sample.baselineSet ? sample.gamma - sample.baseGamma : sample.gamma;
const x = clamp(-deltaBeta, -30, 30);
const y = clamp(deltaGamma, -30, 30);
gyroHelperFrame.style.opacity = '1';
gyroHelperFrame.style.setProperty('--gyro-x', `${x}deg`);
gyroHelperFrame.style.setProperty('--gyro-y', `${y}deg`);

View File

@@ -126,7 +126,7 @@ body.gameplay-active {
}
.hidden {
display: none;
display: none !important;
}
.panel {
@@ -209,13 +209,13 @@ body.gameplay-active {
.gyro-helper-ghost {
background: rgba(255, 255, 255, 0.06);
transform: rotateX(60deg) rotateZ(45deg);
transform: rotateX(60deg);
}
.gyro-helper-device {
background: rgba(255, 159, 28, 0.2);
border-color: rgba(255, 159, 28, 0.65);
transform: rotateX(calc(60deg + var(--gyro-x))) rotateZ(45deg) rotateY(var(--gyro-y));
transform: rotateX(calc(60deg + var(--gyro-x))) rotateY(var(--gyro-y));
transition: transform 80ms linear;
}