Skip to content

la-pandev/precise-browser-timer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

precise-browser-timer

A precise browser-based timer that uses requestAnimationFrame for accurate scheduling. Supports multiple independent tick cycles, playback speed control, and seeded pseudo-random number generation per tick.

Install

npm install precise-browser-timer
# or
bun add precise-browser-timer

Usage

import { PreciseBrowserTimer } from "precise-browser-timer";

const timer = new PreciseBrowserTimer({
  tick_cycle_list: [
    {
      tick_unit_ms: 100, // fire every 100ms
      on_tick: (tick, prand_numbers, elapsed_ms) => {
        console.log(`Tick ${tick} at ${elapsed_ms}ms`);
      },
    },
  ],
});

timer.start();

// pause and resume
timer.pause();
timer.start();

// permanently stop
timer.stop();

Options

new PreciseBrowserTimer({
  seed?: number;              // RNG seed for deterministic random numbers (default: 0)
  playback_speed?: number;    // 0 < speed <= 1, values below 1 slow down playback (default: 1)
  tick_cycle_list: PreciseTimerTickCycle[];
  on_before_start?: (timestamp_ms: number) => void;
});

Tick Cycle

Each entry in tick_cycle_list runs independently:

{
  tick_unit_ms: number;          // interval between ticks (min 5ms)

  on_tick: (
    tick: number,                // current tick counter
    prand_numbers: number[],     // per-tick random numbers (see prand_range_list)
    elapsed_ms: number,          // total elapsed time since timer start
    ticked_at_ts_ms: number      // absolute timestamp of this tick
  ) => void;

  on_complete?: (
    last_tick: number,
    elapsed_ms: number,
    completed_at_ts_ms: number
  ) => void;

  do_until_value?: number;       // stop condition value
  do_until_unit?: 'ms' | 'tick'; // interpret do_until_value as ms or tick count

  loop?: boolean;                // restart the cycle instead of completing

  prand_range_list?: Array<{ from: number; to: number }>;
  // generates one random integer per range, seeded deterministically per tick
}

Examples

Run for 5 seconds then stop

new PreciseBrowserTimer({
  tick_cycle_list: [
    {
      tick_unit_ms: 16,
      do_until_value: 5000,
      do_until_unit: "ms",
      on_tick: (tick) => render(tick),
      on_complete: () => console.log("done"),
    },
  ],
}).start();

Multiple independent cycles

new PreciseBrowserTimer({
  tick_cycle_list: [
    {
      tick_unit_ms: 100,
      on_tick: (tick) => updateUI(tick),
    },
    {
      tick_unit_ms: 1000,
      on_tick: (tick) => saveProgress(tick),
    },
  ],
}).start();

Random numbers per tick

new PreciseBrowserTimer({
  seed: 42,
  tick_cycle_list: [
    {
      tick_unit_ms: 200,
      prand_range_list: [
        { from: 0, to: 100 },  // first number: 0–100
        { from: -10, to: 10 }, // second number: -10–10
      ],
      on_tick: (tick, [x, y]) => {
        moveSprite(x, y);
      },
    },
  ],
}).start();

Slow-motion playback

const timer = new PreciseBrowserTimer({
  playback_speed: 0.5, // half speed
  tick_cycle_list: [...],
}).start();

// change speed at runtime
timer.changePlaybackSpeed(0.25);

Seek to a tick

const cycle = { tick_unit_ms: 100, on_tick: render };

const timer = new PreciseBrowserTimer({
  tick_cycle_list: [cycle],
}).start();

// jump to tick 50
timer.scheduleTickChange(cycle, 50);

// or seek by timestamp
timer.scheduleTickChangeByTimestamp(cycle, 5000); // jump to 5s position

API

Method Description
start() Start the timer
pause() Pause — tick state is preserved, start() resumes from where it left off
stop() Permanently stop — cannot be restarted
changePlaybackSpeed(speed) Change speed at runtime
scheduleTickChange(cycle, tick) Jump to a specific tick on next frame
scheduleTickChangeByTimestamp(cycle, ms) Jump to a tick derived from a timestamp

License

MIT

About

A precise browser-based timer that uses requestAnimationFrame for accurate scheduling.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors