DOM ENGINEV0.10.0FIZLET

INPUT V0.10.0

fizlet/input

One controller for keys, pointer and a touch stick, mapped to named intents. Listeners only record; the engine's read phase latches edges and measures the target, so a step sees a stable snapshot. Keys typed into the host page's fields (or inside [data-fizlet-ignore]) never count. Held state is dropped on window blur, when the engine pauses, on dispose() and on destroy: nothing stays stuck. hit (an intent or the pointer): a press is seen by exactly one fixed step, the first step after it, even when that comes frames later (0-step frames while catching up) and never again in the same frame's later steps. Outside a step (read, render), hit is true for the one frame whose read latched it. Presses between two steps count once.

fizlet/input · GZIP1,283 B1.3 KB of a 1.5 KB budget

Measured on this build: minified and gzipped with everything it imports, the way npm run size checks the budget in CI.

MODULES · hosted on this site
import { controls } from "https://coded-dot-design.github.io/fizlet/dist/input.js";
NPM · COMING SOON
npm install fizlet   # not published yet
import { controls } from "fizlet/input";
IN SHORT
const pad = controls(e, { keys: { fire: ["Space"] } });
if (pad.hit("fire")) fire(); // true for one frame
if (pad.pointer.hit) aim(pad.pointer.x, pad.pointer.y);

API

Every export, with its doc comment, read from the published type declarations of v0.10.0.

ControlsOptions interface

export interface ControlsOptions {
    /** intent → key codes, e.g. { fire: ["Space"], up: ["KeyW", "ArrowUp"] } (KeyboardEvent.code). */
    keys?: Record<string, string[]>;
    /** Where the pointer is measured and the stick lives (default: the engine root, else window). */
    target?: HTMLElement;
    /** Touch: a drag that starts on the left half (or anywhere: "any") drives a virtual stick. */
    stick?: "left" | "any" | false;
    /** Stick radius in CSS px (default 60). */
    radius?: number;
}

controls function

export declare function controls(e: Engine, o?: ControlsOptions): {
    /** Held right now (any of its keys, or press()). */
    down: (intent: string) => boolean;
    /** Pressed: true in the first step after the press; outside steps, for the frame it latched. */
    hit: (intent: string) => boolean;
    /** -1..1 from two intents (keys), plus the stick when it's active. */
    axis(neg: string, pos: string, stickAxis?: 0 | 1): number;
    pointer: {
        readonly x: number;
        readonly y: number;
        readonly down: boolean;
        readonly hit: boolean;
    };
    stick: {
        readonly x: number;
        readonly y: number;
        readonly active: boolean;
    };
    /** Press an intent from code (on-screen keys): `press("strike")`. */
    press(intent: string, down?: boolean): void;
    /** Drive the stick from code (an on-screen stick, fizlet/pad): x, y in -1..1; `on = false` lets go. */
    steer(x: number, y: number, on?: boolean): void;
    dispose: () => void;
    system: System;
};

Controls type

export type Controls = ReturnType<typeof controls>;