36 lines
1.5 KiB
TypeScript
36 lines
1.5 KiB
TypeScript
export const POINTER_CONTRACT_SCHEMA_VERSION = 1 as const;
|
|
export type PointerKind = "mouse" | "touch" | "pen";
|
|
|
|
export interface PointerObservation {
|
|
schemaVersion: typeof POINTER_CONTRACT_SCHEMA_VERSION;
|
|
pointerType: PointerKind;
|
|
pointerId: number;
|
|
pressure: number;
|
|
tiltX: number;
|
|
tiltY: number;
|
|
button: number;
|
|
buttons: number;
|
|
cancelled: boolean;
|
|
}
|
|
|
|
function bounded(value: number, min: number, max: number, fallback: number): number {
|
|
return Number.isFinite(value) ? Math.max(min, Math.min(max, value)) : fallback;
|
|
}
|
|
|
|
export function observePointerEvent(event: { pointerType?: string; pointerId?: number; pressure?: number; tiltX?: number; tiltY?: number; button?: number; buttons?: number; type?: string }): PointerObservation {
|
|
const pointerType = event.pointerType === "touch" || event.pointerType === "pen" || event.pointerType === "mouse" ? event.pointerType : null;
|
|
if (!pointerType) throw new Error("POINTER_TYPE_UNSUPPORTED");
|
|
if (!Number.isSafeInteger(event.pointerId) || event.pointerId! < 0) throw new Error("POINTER_ID_INVALID");
|
|
return {
|
|
schemaVersion: POINTER_CONTRACT_SCHEMA_VERSION,
|
|
pointerType,
|
|
pointerId: event.pointerId!,
|
|
pressure: bounded(event.pressure ?? (pointerType === "mouse" ? 0 : 0.5), 0, 1, 0),
|
|
tiltX: bounded(event.tiltX ?? 0, -90, 90, 0),
|
|
tiltY: bounded(event.tiltY ?? 0, -90, 90, 0),
|
|
button: Number.isInteger(event.button) ? event.button! : -1,
|
|
buttons: Number.isInteger(event.buttons) && event.buttons! >= 0 ? event.buttons! : 0,
|
|
cancelled: event.type === "pointercancel",
|
|
};
|
|
}
|