@zakkster/lite-gamepad
v1.0.0
Published
Unified keyboard + gamepad input poller. Radial deadzone, diagonal normalization, AbortController cleanup.
Maintainers
Readme
@zakkster/lite-gamepad
🎮 What is lite-gamepad?
@zakkster/lite-gamepad unifies WASD, arrow keys, and gamepad analog sticks into a single normalized Float32Array(2) movement vector.
It gives you:
- 🎮 Unified keyboard + gamepad in one API
- 🕹️ Radial deadzone with smooth scaling (no snap)
- ↗️ Diagonal normalization (no speed boost on diagonals)
- 🧹 AbortController cleanup — no leaked listeners
- 🔢 Uint8Array key state (zero allocation per poll)
- 🪶 < 1 KB minified
Call poll() once per frame — get a normalized direction vector.
Part of the @zakkster/lite-* ecosystem — micro-libraries built for deterministic, cache-friendly game development.
🚀 Install
npm i @zakkster/lite-gamepad🕹️ Quick Start
import { InputVectorizer } from '@zakkster/lite-gamepad';
const input = new InputVectorizer();
function gameLoop() {
const [dx, dy] = input.poll();
player.x += dx * speed * dt;
player.y += dy * speed * dt;
requestAnimationFrame(gameLoop);
}
// Check action buttons
if (input.isActionPressed(32, 0)) shoot(); // Space or Gamepad A
// Cleanup
input.destroy();🧠 Why This Exists
Keyboard gives you [-1, 0, 1] per axis. Gamepad gives you [-1.0 ... 1.0] with deadzone drift. lite-gamepad normalizes both into the same Float32Array(2) — clamped magnitude, smooth deadzone, zero allocation.
📊 Comparison
| Library | Size | Keyboard | Gamepad | Deadzone | Normalized | Install |
|---------|------|----------|---------|----------|------------|---------|
| gamepad.js | ~3 KB | No | Yes | Basic | No | npm i gamepad.js |
| keymaster | ~4 KB | Yes | No | N/A | No | npm i keymaster |
| lite-gamepad | < 1 KB | Yes | Yes | Radial smooth | Yes | npm i @zakkster/lite-gamepad |
⚙️ API
new InputVectorizer()
poll() — Returns Float32Array(2) normalized movement vector. Call once per frame.
isActionPressed(keyCode, gamepadButtonIndex?) — Check action key/button state
destroy() — Cleans up all event listeners via AbortController
🧪 Benchmark
N/A — input polling is I/O bound, not CPU bound.
Key advantage: zero allocation per poll() call (Float32Array reuse).📦 TypeScript
Full TypeScript declarations included in InputVectorizer.d.ts.
📚 LLM-Friendly Documentation
See llms.txt for AI-optimized metadata and usage examples.
License
MIT
