🏃 Independent render FPS – update ticker in PixiJS
| 🔮 Simple, drop-in API | ✨ Supports PixiJS 8, 7 and 6+ |
| ✅ Plugin compatible | 💪 Configurable, with sensible defaults |
| 🤏 Tiny (<2kB) | 🍃 No dependencies, tree-shakeable |
const ticker = new InterpolatedTicker({ renderer, stage }); const mySprite = new Sprite({ texture: Assets.get("cat") }); ticker.start({ // triggered at a fixed interval update: (fixedDeltaMS: number) { mySprite.x += 5; mySprite.angle += 0.1; } });
npm i pixijs-interpolated-ticker
const ticker = new InterpolatedTicker({ renderer, stage }); const mySprite = new Sprite({ texture: "cat" }); ticker.start({ update: (fixedDeltaMS: number) { // triggered at a fixed interval // (fixedMS never changes) }, render: (renderDeltaMS: number, progress: number) { // triggered at display refresh rate // e.g. drawing additional particle effects, etc. }, }); // increasing the speed affects the rate at which update(fixedDeltaMS) is // executed, but does not affect the value of fixedDeltaMS. ticker.speed = 2; // limit render FPS ticker.renderFPS = 30; ticker.on("fps", (fps) => { // render FPS updated }); ticker.on("devicefps", (fps) => { // device FPS updated (independent of actual renders) });
When starting the event loop, you may supply the following lifecycle event hooks
| Hook | Event | Description |
|---|---|---|
update |
Required Fixed timestep update |
The core update loop of the program. Note: Changes made to containers here will be interpolated in the render loop. This may be triggered zero, one or many times in a render call (based on the target fixedDeltaMS and interpolated ticker speed).Note: Changing the interpolated ticker speed changes the true rate at which the update function is triggered, but fixedDeltaMS is not affected. |
prepareRender |
Optional A render frame is about to render. |
Changes made here to containers will affect the "end" state for container interpolation. Triggered at the start of each render cycle, before container interpolation. |
render |
Optional (Recommended) A render frame is about to render. |
Triggered immediately before each renderer.render() call, after container interpolation.Note: Changes made to containers here will be rendered, but may be reverted to its prepareRender state if the container was expecting to be interpolated. |
postRender |
Optional A frame has been rendered. |
Triggered after each renderer.render() call, after container interpolation is restored. |
new InterpolatedTicker(options: { /** * PixiJS renderer. */ renderer: Renderer; /** * Stage root view. */ stage: Container; /** * Fixed timestep interval in milliseconds. * * @default 16.666666666666668 */ fixedDeltaMS?: number; /** * Whether container interpolation is enabled. * * When enabled, container values (position, scale, rotation, alpha) are * rendered at interpolated positions. * * @default true */ interpolation?: boolean; /** * Container interpolation options (when enabled). * * @default undefined */ interpolationOptions?: { /** * Maximum interpolatable change in position x/y. * * @default 100 */ maxDeltaPosition?: number; /** * Maximum interpolatable change in scale. * * @default 1 */ maxDeltaScale?: number; /** * Maximum interpolatable change in rotation. * * @default Math.PI/2 */ maxDeltaRotation?: number; /** * Maximum interpolatable change in alpha. * * @default 0.5 */ maxDeltaAlpha?: number; /** * Initial number of containers to preallocate interpolation memory for. * * @default 256 */ capacity?: number; /** * Maximum number of containers to allocate interpolation memory for. * * @default 4096 */ maxCapacity?: number; }, /** * The display refresh rate to target (in frames per second). Actual render * rate will vary on different displays. * * A value of `0` means unlimited refresh rate. * * @default 0 */ renderFPS?: number; /** * When `renderFPS` set, this is the maximum tolerance in milliseconds for * limiting the render frame interval. * * @default 7.0 */ renderIntervalToleranceMS?: number; /** * Maximum frame time in milliseconds that fixed updates may accrue for * before frame time stops accruing. Scaled by `speed`. * * @default fixedDeltaMS*3 */ maxFrameTimeMS?: number; /** * The minimum interval in milliseconds that fluctuations in FPS are reported. * * Listen for "fps" and "devicefps" events. * * @default 1000 */ fpsIntervalMS?: number; /** * The rounding level for FPS detection (e.g. 0.01). * * @default 1 */ fpsPrecision?: number; })
Configuring individual containers.
| Property | Description |
|---|---|
isInterpolated |
Set false to disable interpolation on this container. Defaults to this.visible. |
hasInterpolatedChildren |
Set false to disable interpolation on this container's descendants. Defaults to this.isInterpolated. |
const container = new Container(); // skip interpolation on this container and its children container.isInterpolated = false; // actually ...lets allow children to be interpolated anyway container.hasInterpolatedChildren = true;
PixiJS InterpolatedTicker is an implementation of the ideas laid out in Gafferongames' Fix Your Timestep article, and is a spiritual successor to kittykatattack/smoothie.
