ticker

@webgamelibs/ticker

A lightweight Ticker class for frame-based game loops. It uses requestAnimationFrame under the hood and optionally supports an FPS cap.

Installation

yarn add @webgamelibs/ticker
# or
npm install @webgamelibs/ticker

Type definitions (.d.ts) are bundled, so it works seamlessly with TypeScript.

Usage

import { Ticker } from '@webgamelibs/ticker'

const ticker = new Ticker((deltaTime) => {
  // deltaTime: elapsed time in seconds (float)
  console.log(`Elapsed time per frame: ${deltaTime.toFixed(3)}s`)
})

// Enable FPS cap
ticker.setFpsCap(60)

// Disable FPS cap
ticker.disableFpsCap()

// Stop the loop when no longer needed
ticker.remove()

Constructor

new Ticker(onTick: (deltaTime: number) => void, fps?: number)

Methods

Method Description
setFpsCap(fps) Dynamically set the FPS cap. Passing a value ≤ 0 disables the cap.
disableFpsCap() Disables FPS capping, resuming uncapped execution.
remove() Stops the internal requestAnimationFrame loop and cleans up.

How FPS Cap Works

This design ensures a consistent update rate for game logic while still using requestAnimationFrame for smooth rendering.

Error Handling

const ticker = new Ticker(() => {
  throw new Error('Test error')
})
// The error is logged, but the game loop continues.

Handling Large deltaTime After Tab Switch

requestAnimationFrame pauses or slows in inactive tabs, which may produce very large deltaTime values once the tab becomes active again. Ticker does not clamp these values by default — clamp manually if needed:

const MAX_DT = 1 / 15 // Clamp to 15 FPS minimum
const ticker = new Ticker((dt) => {
  update(Math.min(dt, MAX_DT))
})

Testing

This package is tested with Jest.

yarn add --dev jest ts-jest @types/jest jest-environment-jsdom

Minimal example:

import { Ticker } from './ticker'

test('Ticker passes deltaTime to onTick', () => {
  const onTick = jest.fn()
  const ticker = new Ticker(onTick)

  // Mock requestAnimationFrame and advance time manually here...
  
  ticker.remove()
  expect(onTick).toHaveBeenCalled()
})

For a full-featured test suite (including FPS cap scenarios and cancellation), see src/ticker.test.ts.

License

MIT License