Compare commits
2 Commits
e1e2e77f39
...
9f97d117db
Author | SHA1 | Date |
---|---|---|
Tomáš Mládek | 9f97d117db | |
Tomáš Mládek | ce010c1270 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue