How Pixi.js Calculates Ticker Delta Time
This article explains how Pixi.js calculates and manages delta time within its Ticker update loop. You will learn how the framework translates raw millisecond differences between animation frames into a normalized delta time value, allowing you to create smooth, frame-rate independent animations and game physics.
The Foundation: requestAnimationFrame and High-Resolution Time
At its core, the PIXI.Ticker class relies on the
browser’s native requestAnimationFrame (rAF) API to drive
its continuous update loop. Each time the browser is ready to paint a
new frame, it triggers the Ticker’s internal update method.
To measure the exact passage of time between these frames, Pixi.js
uses performance.now(). This built-in web API returns a
highly accurate, sub-millisecond timestamp representing the time elapsed
since the document was loaded.
The Calculation Process
Each time the Ticker’s update loop executes, Pixi.js performs a series of calculations to determine how much time has passed since the previous frame.
1. Determining Elapsed Milliseconds
First, Pixi.js captures the current timestamp (\(T_{current}\)) and subtracts the timestamp of the previous frame (\(T_{previous}\)):
\[\text{elapsedMS} = T_{current} - T_{previous}\]
This gives the raw number of milliseconds that have elapsed since the last update.
2. Normalizing to Target FPS (Delta Time)
Instead of forcing developers to work directly with millisecond
values, Pixi.js converts this elapsed time into a normalized ratio
called deltaTime.
By default, Pixi.js targets a standard frame rate of 60 frames per second (FPS). At 60 FPS, one single frame should ideally take approximately 16.66 milliseconds (\(1000 \text{ ms} / 60\)).
To calculate the normalized deltaTime, Pixi.js divides
the actual elapsed milliseconds by this ideal frame duration:
\[\text{deltaTime} = \frac{\text{elapsedMS}}{16.66}\]
- If the game is running at a perfect 60 FPS, the
elapsed time is 16.66ms. The resulting
deltaTimeis1.0. - If the game lags and runs at 30 FPS, the elapsed
time doubles to 33.33ms. The resulting
deltaTimeis2.0. - If the game runs on a 120Hz monitor (120 FPS), the
elapsed time halves to 8.33ms. The resulting
deltaTimeis0.5.
3. Applying the Speed Factor
Pixi.js Tickers also feature a speed property, which
acts as a scalar multiplier. The final deltaTime passed to
your listener functions is multiplied by this value (which defaults to
1):
\[\text{finalDeltaTime} = \text{deltaTime} \times \text{speed}\]
This allows you to easily fast-forward, slow down, or pause animations globally by adjusting the Ticker’s speed.
Key Ticker Properties Reference
When writing code inside a Pixi.js Ticker listener, you have access to several time-related properties on the ticker instance:
ticker.deltaTime: The normalized delta time value (scaled around1.0for 60 FPS). Use this to scale your movement and physics calculations.ticker.elapsedMS: The actual, unscaled milliseconds passed since the last frame.ticker.deltaMS: The elapsed milliseconds multiplied by the ticker’s current speed.ticker.speed: The speed factor modifier.
Why Using Delta Time Matters
Using the normalized deltaTime provided by Pixi.js
ensures frame-rate independence. For example, if you want a sprite to
move across the screen, multiplying its velocity by the delta time
ensures it moves at the same physical speed regardless of whether the
user is on a 60Hz screen, a 144Hz screen, or experiencing performance
lag:
app.ticker.add((ticker) => {
// This sprite will move at a consistent speed on all devices
sprite.x += 5 * ticker.deltaTime;
});