diff --git a/src/routes/gamepad/+page.svelte b/src/routes/gamepad/+page.svelte index 67d73ed..025bec6 100644 --- a/src/routes/gamepad/+page.svelte +++ b/src/routes/gamepad/+page.svelte @@ -2,6 +2,7 @@ import { onMount } from 'svelte'; import { browser } from '$app/environment'; import debug from 'debug'; + const dbg = debug('app:camera'); let gamepads: Gamepad[] = []; @@ -9,13 +10,55 @@ let buttons: GamepadButton[] = []; let axes: number[] = []; + const axisHistory: number[][] = []; + const sizes: [number, number][] = []; + const contexts: CanvasRenderingContext2D[] = []; + + function update() { + buttons = currentGamepad?.buttons.concat() || []; + axes = currentGamepad?.axes.concat() || []; + + axisHistory.push(axes); + if (axisHistory.length > 1024) { + axisHistory.shift(); + } + + for (let i = 0; i < axes.length; i++) { + if (!contexts[i]) { + const canvas = document.querySelector(`canvas[data-axis="${i}"]`) as HTMLCanvasElement; + if (!canvas) continue; + if (!canvas.checkVisibility()) continue; + contexts[i] = canvas.getContext('2d') as CanvasRenderingContext2D; + sizes[i] = [canvas.width, canvas.height]; + } + const ctx = contexts[i]; + if (!ctx) continue; + + const [width, height] = sizes[i]; + + ctx.clearRect(0, 0, width, height); + ctx.strokeStyle = `rgba(255, 0, 0, 0.5)`; + ctx.beginPath(); + ctx.moveTo(0, height / 2); + ctx.lineTo(width, height / 2); + ctx.stroke(); + + ctx.strokeStyle = 'white'; + ctx.beginPath(); + ctx.moveTo(width - axisHistory.length, height / 2); + for (let j = 0; j < axisHistory.length; j++) { + const x = width - axisHistory.length + j; + const y = ((axisHistory[j][i] + 1) * (height - 2)) / 2 + 1; + ctx.lineTo(x, y); + } + ctx.stroke(); + } + + requestAnimationFrame(update); + } + $: { if (currentGamepad) { - function update() { - buttons = currentGamepad?.buttons.concat() || []; - axes = currentGamepad?.axes.concat() || []; - requestAnimationFrame(update); - } update(); } } @@ -86,6 +129,10 @@ {axis.toFixed(2)} +
+ History + +
{/each} @@ -160,4 +207,9 @@ } } } + + canvas { + background: black; + width: 100%; + }