This commit is contained in:
Tomáš Mládek 2024-02-20 17:07:58 +01:00
parent e1e2e77f39
commit ce010c1270
3 changed files with 178 additions and 1 deletions

View file

@ -38,4 +38,16 @@ button, .button {
background: black;
color: white;
}
select {
background: black;
color: white;
padding: 0.25em 0.5em;
border-radius: 0.25em;
border: 1px solid white;
&:disabled {
opacity: 0.7;
}
}

View file

@ -83,9 +83,11 @@
<div class="controls">
<label>
Device
<select bind:value={currentDevice} id="device">
<select bind:value={currentDevice} disabled={!devices.length}>
{#each devices as device}
<option value={device.deviceId}>{device.label || '???'}</option>
{:else}
<option>No camera found</option>
{/each}
</select>
</label>

View file

@ -0,0 +1,163 @@
<script lang="ts">
import { onMount } from 'svelte';
import { browser } from '$app/environment';
import debug from 'debug';
const dbg = debug('app:camera');
let gamepads: Gamepad[] = [];
let currentGamepad: Gamepad | undefined;
let buttons: GamepadButton[] = [];
let axes: number[] = [];
$: {
if (currentGamepad) {
function update() {
buttons = currentGamepad?.buttons.concat() || [];
axes = currentGamepad?.axes.concat() || [];
requestAnimationFrame(update);
}
update();
}
}
$: dbg('Gamepads %O', gamepads);
$: dbg('Current gamepad %s', currentGamepad);
$: currentGamepad?.vibrationActuator?.playEffect('dual-rumble', {
duration: 1000
});
onMount(() => {
refreshGamepads();
});
async function refreshGamepads() {
gamepads = browser ? (navigator.getGamepads().filter(Boolean) as Gamepad[]) : [];
currentGamepad = gamepads[0];
}
onMount(() => {
window.addEventListener('gamepadconnected', (e) => {
dbg('Gamepad connected', e);
refreshGamepads();
});
window.addEventListener('gamepaddisconnected', (e) => {
dbg('Gamepad disconnected', e);
refreshGamepads();
});
});
</script>
<h2><i class="ti ti-device-gamepad"></i> Gamepad & Joystick Tests</h2>
<div class="controls">
<label>
Device
<select disabled={!gamepads.length}>
{#each gamepads as gamepad}
<option value={gamepad.index}>{gamepad.id}</option>
{:else}
<option>No gamepads detected. (Try pressing a button)</option>
{/each}
</select>
</label>
<button on:click={refreshGamepads}>
<i class="ti ti-refresh"></i>
Refresh
</button>
</div>
{#if currentGamepad}
<section>
<h3>Buttons</h3>
<ul class="buttons">
{#each buttons as button, i}
<li class:pressed={button.pressed}>{i}</li>
{/each}
</ul>
</section>
<section>
<h3>Axes</h3>
<div class="axes">
{#each axes as axis, i (i)}
<div class="axis">
<div>
<span>{i}</span>
<progress value={axis + 1} max="2"></progress>
<span>{axis.toFixed(2)}</span>
</div>
</div>
{/each}
</div>
</section>
{/if}
<style>
.controls {
display: flex;
align-items: end;
justify-content: stretch;
gap: 1em;
& label:first-child {
flex-grow: 1;
min-width: 0;
}
}
label {
display: flex;
flex-direction: column;
gap: 0.2em;
font-size: 0.8em;
& select {
font-size: initial;
}
}
h3 {
margin-top: 2em;
text-align: center;
}
.buttons {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
& li {
display: block;
width: 2em;
height: 2em;
border: 1px solid white;
border-radius: 0.75em;
text-align: center;
line-height: 2em;
&.pressed {
background-color: darkred;
color: white;
}
}
}
.axes {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.5em 2em;
& .axis div {
display: flex;
gap: 0.25em;
& progress {
flex-grow: 1;
}
}
}
</style>