@armniko/ticker
v2.3.0
Published
A lightweight, zero-dependency JavaScript/TypeScript library for running an application loop with separate logic and draw ticks, time scaling, FPS limiting, and low-FPS detection.
Maintainers
Readme
Ticker
A lightweight, zero-dependency JavaScript/TypeScript library for running an application loop with separate logic and draw ticks, time scaling, FPS limiting and low-FPS detection.
Why Ticker?
- 🎯 Decoupled logic & rendering — update game state and draw frames independently
- 🎚️ FPS control — cap your draw rate to save CPU/battery
- ⏱️ Time scaling — slow down or speed up time without touching your game logic
- 📉 Low-FPS callbacks — react when performance degrades (e.g. lower visual quality)
- 🧪 Test-friendly — ships with
TickerMockfor deterministic unit tests - 📦 Zero dependencies and fully typed
Installation
npm install @armniko/tickerUsage
import { Ticker, Time } from '@armniko/ticker';
const element: { position: { x: number, y: number } } = { position: { x: 0, y: 0 } };
const animation: { durationMs: number, distancePx: number } = {
durationMs: 2000,
distancePx: 500,
}
const ticker: Ticker = new Ticker();
ticker.addLogicTask((time: Time): void => {
const pxPerMs: number = animation.distancePx / animation.durationMs;
element.position.x += pxPerMs * time.deltaMs;
});
ticker.addDrawTask((): void => {
// draw
});Ticker instance methods:
- start() – starts ticker.
- stop() – stops ticker.
- isStarted() – checks if ticker is started.
- setFps(options: { min?: number; max?: number; expected?: number }) - set min, max or expected FPS
- min (default: 0) – defines value at which lowFps task callbacks will be called.
- max (default: 60) – defines drawing FPS limit.
- expected (default: 60) - defines expected logical and drawing FPS at which app should work in normal conditions.
- setTimeScale(scale: number) – set time scale.
- addLogicTask(callback) – register callback for update app logic. Returns TickerTaskId.
- addDrawTask(callback) – register callback for update app screen. Returns TickerTaskId.
- addLowFpsTask(callback) – register callback that will be called when reached min FPS. Returns TickerTaskId.
- remove(taskId: TickerTaskId) – removes the provided task.
- fps() – current FPS at which app operates.
- timeScale() – current time scale at which app operates.
Migration
v1 -> v2
Before (v1):
import { Ticker } from '@armniko/ticker';
const element: { position: { x: number, y: number } } = { position: { x: 0, y: 0 } };
const animation: { durationMs: number, distancePx: number } = {
durationMs: 2000,
distancePx: 500,
}
const ticker: Ticker = new Ticker({
onLogicTick: (): void => {
const pxPerMs: number = distancePx / animationDurationMs;
element.position.x += pxPerMs * ticker.msBetweenTicks();
},
onDrawTick: (): void => {
// draw element
},
});
ticker.start();After (v2):
import { Ticker, Time } from '@armniko/ticker';
const element: { position: { x: number, y: number } } = { position: { x: 0, y: 0 } };
const animation: { durationMs: number, distancePx: number } = {
durationMs: 2000,
distancePx: 500,
}
const ticker: Ticker = new Ticker();
ticker.addLogicTask((time: Time): void => {
const pxPerMs: number = distancePx / animationDurationMs;
element.position.x += pxPerMs * time.deltaMs;
});
ticker.addDrawTask((): void => {
// draw element
});
ticker.start();