pixijs-application

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Application
is the convenience wrapper that owns a renderer, a root
stage
Container, a canvas, and the Ticker/Resize plugins. In v8 the constructor takes no arguments; all configuration is passed to the async
app.init()
call which instantiates the renderer via
autoDetectRenderer
.
Application
是一个便捷的封装类,它包含了渲染器、根容器
stage
、画布以及 Ticker/Resize 插件。在v8版本中,构造函数不接收任何参数;所有配置都通过异步的
app.init()
调用传入,该调用会通过
autoDetectRenderer
实例化渲染器。

Quick Start

快速开始

ts
import { Application } from "pixi.js";

const app = new Application();

await app.init({
  resizeTo: window,
  background: "#1099bb",
  antialias: true,
  preference: "webgl",
  autoDensity: true,
  resolution: window.devicePixelRatio,
});

document.body.appendChild(app.canvas);
Related skills:
pixijs-core-concepts
(renderers, render pipeline),
pixijs-ticker
(render loop detail),
pixijs-scene-container
(working with
app.stage
),
pixijs-environments
(non-browser setups).
ts
import { Application } from "pixi.js";

const app = new Application();

await app.init({
  resizeTo: window,
  background: "#1099bb",
  antialias: true,
  preference: "webgl",
  autoDensity: true,
  resolution: window.devicePixelRatio,
});

document.body.appendChild(app.canvas);
相关技能:
pixijs-core-concepts
(渲染器、渲染管线)、
pixijs-ticker
(渲染循环细节)、
pixijs-scene-container
app.stage
相关操作)、
pixijs-environments
(非浏览器环境配置)。

Core Patterns

核心模式

Lifecycle: construct, init, render, destroy

生命周期:构造、初始化、渲染、销毁

ts
import { Application } from "pixi.js";

const app = new Application();

await app.init({ width: 800, height: 600 });
document.body.appendChild(app.canvas);

// ... run scene, ticker drives app.render() automatically ...

app.destroy(
  { removeView: true, releaseGlobalResources: true },
  { children: true, texture: true, textureSource: true },
);
  • new Application()
    allocates the instance but creates nothing. Options passed here are ignored with a v8 deprecation warning.
  • app.init(options)
    is async. It builds the renderer, wires up plugins, and must complete before you can use
    app.canvas
    ,
    app.renderer
    , or
    app.screen
    .
  • The TickerPlugin calls
    app.render()
    every frame once init resolves (unless
    autoStart: false
    ).
  • app.destroy(rendererDestroyOptions, stageDestroyOptions)
    — the first argument forwards to
    renderer.destroy()
    . Pass
    true
    or
    { removeView: true }
    to remove the canvas from the DOM. Add
    releaseGlobalResources: true
    to drain global pools (batches, texture caches) when tearing down and re-creating an app in the same tab; omitting it is the usual cause of flickering and stale textures after a re-init (see
    pixijs-performance
    ).
ts
import { Application } from "pixi.js";

const app = new Application();

await app.init({ width: 800, height: 600 });
document.body.appendChild(app.canvas);

// ... 运行场景,ticker 会自动驱动 app.render() ...

app.destroy(
  { removeView: true, releaseGlobalResources: true },
  { children: true, texture: true, textureSource: true },
);
  • new Application()
    仅分配实例但不创建任何资源。在此处传入的配置会被忽略并触发v8版本的弃用警告。
  • app.init(options)
    是异步方法。它会构建渲染器、关联插件,只有当该方法执行完成后,你才能使用
    app.canvas
    app.renderer
    app.screen
  • 一旦初始化完成,TickerPlugin 会在每一帧调用
    app.render()
    (除非设置
    autoStart: false
    )。
  • app.destroy(rendererDestroyOptions, stageDestroyOptions)
    — 第一个参数会传递给
    renderer.destroy()
    。传入
    true
    { removeView: true }
    可将画布从DOM中移除。添加
    releaseGlobalResources: true
    可在销毁并重新创建应用时清空全局池(批次、纹理缓存);如果省略该参数,通常会导致重新初始化后出现闪烁和纹理失效的问题(详见
    pixijs-performance
    )。

Key init options

核心初始化选项

ts
await app.init({
  width: 800,
  height: 600,
  background: 0x1099bb,
  backgroundAlpha: 1,

  antialias: true,
  resolution: window.devicePixelRatio,
  autoDensity: true,

  preference: "webgpu",

  autoStart: true,
  sharedTicker: false,

  resizeTo: window,

  canvas: document.querySelector("#game-canvas") as HTMLCanvasElement,
});
For every option — view/canvas, background, renderer preference (including the array form), ticker, resize, culler, events, accessibility, WebGL/WebGPU context flags, Graphics bezier smoothness, GC, and per-renderer overrides (
webgl
/
webgpu
/
canvasOptions
) — see references/application-options.md.
ts
await app.init({
  width: 800,
  height: 600,
  background: 0x1099bb,
  backgroundAlpha: 1,

  antialias: true,
  resolution: window.devicePixelRatio,
  autoDensity: true,

  preference: "webgpu",

  autoStart: true,
  sharedTicker: false,

  resizeTo: window,

  canvas: document.querySelector("#game-canvas") as HTMLCanvasElement,
});
关于所有选项——视图/画布、背景、渲染器偏好设置(包括数组形式)、ticker、resize、culler、事件、无障碍访问、WebGL/WebGPU上下文标志、Graphics贝塞尔曲线平滑度、GC以及各渲染器的覆盖配置(
webgl
/
webgpu
/
canvasOptions
),请查看 references/application-options.md

Application properties

Application 属性

ts
app.stage; // root Container; add all display objects here
app.renderer; // the WebGL/WebGPU/Canvas renderer instance
app.canvas; // the HTMLCanvasElement (insert it into the DOM yourself)
app.screen; // Rectangle describing the visible area in CSS pixels
app.domContainerRoot; // HTMLDivElement that holds DOMContainer overlays
app.stage
is a plain
Container
. For scene graph detail (transforms, addChild, destroy) see
pixijs-scene-container
. For renderer-level operations (extract, generateTexture, custom systems) see
pixijs-core-concepts
and
pixijs-custom-rendering
.
app.domContainerRoot
is the
<div>
that the renderer uses to host
DOMContainer
overlays; append it next to
app.canvas
when you need DOM elements pinned to scene nodes (see
pixijs-scene-dom-container
).
ts
app.stage; // 根容器;所有显示对象都需要添加到这里
app.renderer; // WebGL/WebGPU/Canvas 渲染器实例
app.canvas; // HTMLCanvasElement(需要你自行插入到DOM中)
app.screen; // 描述CSS像素可见区域的Rectangle对象
app.domContainerRoot; // 用于承载DOMContainer覆盖层的HTMLDivElement
app.stage
是一个普通的
Container
。关于场景图的细节(变换、addChild、销毁)请查看
pixijs-scene-container
。关于渲染器级别的操作(提取、生成纹理、自定义系统)请查看
pixijs-core-concepts
pixijs-custom-rendering
app.domContainerRoot
是渲染器用于承载
DOMContainer
覆盖层的
<div>
;当你需要将DOM元素固定到场景节点时,需将其与
app.canvas
一起添加到DOM中(详见
pixijs-scene-dom-container
)。

ResizePlugin

ResizePlugin

Set
resizeTo
at init (or reassign
app.resizeTo
later) to have the plugin listen for the
resize
event and call
renderer.resize()
with the target element's client size. Combine with
autoDensity: true
and
resolution: window.devicePixelRatio
for high-DPI output.
ts
await app.init({ resizeTo: window });

app.resizeTo = document.querySelector("#game-container") as HTMLElement;

app.resize(); // immediate resize to the target's current size
app.queueResize(); // defer the resize to the next animation frame
app.cancelResize(); // drop a pending queueResize
The plugin keeps the canvas matched to the target.
app.screen
and
app.canvas.width/height
update in response; read them after the resize to place UI.
  • app.resize()
    — immediate synchronous resize.
  • app.queueResize()
    — coalesces rapid calls by deferring to the next frame; internally used by the
    window.resize
    listener to avoid redundant work.
  • app.cancelResize()
    — cancels a queued resize. Call this before tearing down your own layout code that triggered
    queueResize
    .
在初始化时设置
resizeTo
(或之后重新赋值
app.resizeTo
),插件会监听
resize
事件,并根据目标元素的客户端尺寸调用
renderer.resize()
。结合
autoDensity: true
resolution: window.devicePixelRatio
可实现高DPI输出。
ts
await app.init({ resizeTo: window });

app.resizeTo = document.querySelector("#game-container") as HTMLElement;

app.resize(); // 立即同步调整尺寸
app.queueResize(); // 将尺寸调整延迟到下一动画帧
app.cancelResize(); // 取消已排队的尺寸调整
该插件会保持画布与目标元素尺寸匹配。
app.screen
app.canvas.width/height
会随之更新;调整尺寸完成后可读取这些属性来布局UI。
  • app.resize()
    — 立即同步调整尺寸。
  • app.queueResize()
    — 通过延迟到下一帧来合并频繁的调用;
    window.resize
    监听器内部会使用该方法来避免冗余操作。
  • app.cancelResize()
    — 取消已排队的尺寸调整。在销毁触发
    queueResize
    的自定义布局代码前调用该方法。

Ticker basics

Ticker 基础

The TickerPlugin creates
app.ticker
and registers
app.render()
on it at
UPDATE_PRIORITY.LOW
. Control the loop with
app.start()
/
app.stop()
and add callbacks with
app.ticker.add
/
app.ticker.addOnce
:
ts
app.ticker.add((ticker) => {
  sprite.rotation += 0.01 * ticker.deltaTime;
});

app.ticker.addOnce(() => {
  console.log("runs once on the next frame, then removes itself");
});

app.stop(); // pause the render loop (e.g. tab hidden)
app.start(); // resume
The callback receives the
Ticker
instance; read
ticker.deltaTime
for a frame-rate-independent multiplier (~1.0 at 60fps),
ticker.deltaMS
for real milliseconds, or
ticker.FPS
for the current frame rate. See
pixijs-ticker
for priorities, FPS capping,
onRender
, shared vs private tickers, and the v8 callback signature change.
TickerPlugin 会创建
app.ticker
,并将
app.render()
注册到
UPDATE_PRIORITY.LOW
优先级。可通过
app.start()
/
app.stop()
控制循环,通过
app.ticker.add
/
app.ticker.addOnce
添加回调:
ts
app.ticker.add((ticker) => {
  sprite.rotation += 0.01 * ticker.deltaTime;
});

app.ticker.addOnce(() => {
  console.log("在下一帧运行一次,然后自动移除");
});

app.stop(); // 暂停渲染循环(例如标签页隐藏时)
app.start(); // 恢复渲染循环
回调函数会接收
Ticker
实例;可读取
ticker.deltaTime
获取帧率无关的乘数(60fps时约为1.0),
ticker.deltaMS
获取实际毫秒数,或
ticker.FPS
获取当前帧率。关于优先级、FPS限制、
onRender
、共享与私有ticker以及v8版本回调签名的变化,请查看
pixijs-ticker

Manual render loop

手动渲染循环

ts
await app.init({ autoStart: false, width: 800, height: 600 });
document.body.appendChild(app.canvas);

function frame() {
  updateScene();
  app.render();
  requestAnimationFrame(frame);
}
frame();
autoStart: false
prevents the TickerPlugin from starting the ticker automatically. Call
app.render()
yourself (or
app.renderer.render({ container: app.stage })
for the same effect). If you still want registered ticker callbacks to fire, call
app.ticker.update()
inside your loop before
app.render()
.
ts
await app.init({ autoStart: false, width: 800, height: 600 });
document.body.appendChild(app.canvas);

function frame() {
  updateScene();
  app.render();
  requestAnimationFrame(frame);
}
frame();
autoStart: false
会阻止TickerPlugin自动启动ticker。你需要自行调用
app.render()
(或调用
app.renderer.render({ container: app.stage })
,效果相同)。如果你仍希望已注册的ticker回调执行,需在循环中的
app.render()
之前调用
app.ticker.update()

CullerPlugin (opt-in)

CullerPlugin(可选启用)

The CullerPlugin skips rendering containers that fall outside
app.renderer.screen
. It isn't registered by default; add it before creating your app:
ts
import {
  Application,
  Container,
  Sprite,
  extensions,
  CullerPlugin,
  Rectangle,
} from "pixi.js";

extensions.add(CullerPlugin);

const app = new Application();
await app.init({ width: 800, height: 600 });

const world = new Container();
world.cullable = true; // this container is culled when its bounds leave the screen
world.cullableChildren = true; // default; set `false` to skip recursing into children

const tile = Sprite.from("tile.png");
tile.cullable = true;
world.addChild(tile);
app.stage.addChild(world);
Containers are not culled unless
cullable
is set. Override the default bounds check with
container.cullArea = new Rectangle(x, y, w, h)
when child bounds are expensive to compute. The plugin wraps
app.render()
so
Culler.shared.cull(app.stage, app.renderer.screen)
runs before every frame. See
pixijs-performance
for when culling pays off.
CullerPlugin 会跳过渲染那些超出
app.renderer.screen
范围的容器。它默认未注册;需在创建应用前添加:
ts
import {
  Application,
  Container,
  Sprite,
  extensions,
  CullerPlugin,
  Rectangle,
} from "pixi.js";

extensions.add(CullerPlugin);

const app = new Application();
await app.init({ width: 800, height: 600 });

const world = new Container();
world.cullable = true; // 当该容器的边界超出屏幕时会被剔除
world.cullableChildren = true; // 默认值;设置为`false`可跳过对子容器的递归检查

const tile = Sprite.from("tile.png");
tile.cullable = true;
world.addChild(tile);
app.stage.addChild(world);
只有设置了
cullable
的容器才会被剔除。当子容器的边界计算成本较高时,可通过
container.cullArea = new Rectangle(x, y, w, h)
覆盖默认的边界检查。该插件会封装
app.render()
,因此每一帧渲染前都会执行
Culler.shared.cull(app.stage, app.renderer.screen)
。关于剔除的适用场景,请查看
pixijs-performance

Custom Application plugins

自定义Application插件

Extend
Application
by registering a class with
static init
,
static destroy
, and
static extension = ExtensionType.Application
. Both methods are called with
this
bound to the Application instance, so
this.renderer
and
this.stage
are available.
ts
import {
  Application,
  ExtensionType,
  extensions,
  type ApplicationOptions,
} from "pixi.js";

class FpsOverlay {
  public static extension = ExtensionType.Application;

  public static init(this: Application, options: Partial<ApplicationOptions>) {
    // runs inside app.init() after the renderer is created
    // attach props/methods to `this` to expose them on the app
  }

  public static destroy(this: Application) {
    // runs inside app.destroy() — tear down anything you attached
  }
}

extensions.add(FpsOverlay);
Plugins initialize in registration order and destroy in reverse. To add typed options for your plugin, extend
PixiMixins.ApplicationOptions
:
ts
declare global {
  namespace PixiMixins {
    interface ApplicationOptions {
      fpsOverlay?: { visible?: boolean };
    }
  }
}

await app.init({ fpsOverlay: { visible: true } });
The built-in
ResizePlugin
,
TickerPlugin
, and opt-in
CullerPlugin
all use this same contract. If you set
skipExtensionImports: true
, register the built-ins you need yourself (
extensions.add(ResizePlugin, TickerPlugin)
).
通过注册一个包含
static init
static destroy
static extension = ExtensionType.Application
的类来扩展
Application
。这两个方法的
this
会绑定到Application实例,因此可以访问
this.renderer
this.stage
ts
import {
  Application,
  ExtensionType,
  extensions,
  type ApplicationOptions,
} from "pixi.js";

class FpsOverlay {
  public static extension = ExtensionType.Application;

  public static init(this: Application, options: Partial<ApplicationOptions>) {
    // 在app.init()内部、渲染器创建后执行
    // 可将属性/方法绑定到`this`,从而在应用实例上暴露
  }

  public static destroy(this: Application) {
    // 在app.destroy()内部执行 — 清理你绑定的所有资源
  }
}

extensions.add(FpsOverlay);
插件会按照注册顺序初始化,并按照相反顺序销毁。若要为你的插件添加类型化选项,可扩展
PixiMixins.ApplicationOptions
ts
declare global {
  namespace PixiMixins {
    interface ApplicationOptions {
      fpsOverlay?: { visible?: boolean };
    }
  }
}

await app.init({ fpsOverlay: { visible: true } });
内置的
ResizePlugin
TickerPlugin
和可选的
CullerPlugin
都遵循这一约定。如果设置了
skipExtensionImports: true
,你需要自行注册所需的内置插件(
extensions.add(ResizePlugin, TickerPlugin)
)。

Common Mistakes

常见错误

[CRITICAL] Passing options to the constructor

[严重] 向构造函数传递配置选项

Wrong:
ts
const app = new Application({ width: 800, height: 600 });
document.body.appendChild(app.canvas);
Correct:
ts
const app = new Application();
await app.init({ width: 800, height: 600 });
document.body.appendChild(app.canvas);
In v8 the
Application
constructor takes no arguments. Options passed there are ignored and log a deprecation warning; the renderer is only created inside the async
init()
call.
错误写法:
ts
const app = new Application({ width: 800, height: 600 });
document.body.appendChild(app.canvas);
正确写法:
ts
const app = new Application();
await app.init({ width: 800, height: 600 });
document.body.appendChild(app.canvas);
在v8版本中,
Application
构造函数不接收任何参数。在此处传入的配置会被忽略并触发弃用警告;渲染器仅会在异步的
init()
调用中创建。

[HIGH] Using app.view instead of app.canvas

[高风险] 使用app.view而非app.canvas

Wrong:
ts
document.body.appendChild(app.view);
Correct:
ts
document.body.appendChild(app.canvas);
app.view
was renamed to
app.canvas
in v8. The old getter still works but emits a deprecation warning.
错误写法:
ts
document.body.appendChild(app.view);
正确写法:
ts
document.body.appendChild(app.canvas);
在v8版本中,
app.view
已重命名为
app.canvas
。旧的getter仍可使用但会触发弃用警告。

[MEDIUM] Touching app.canvas or app.renderer before init resolves

[中风险] 在初始化完成前访问app.canvas或app.renderer

Wrong:
ts
const app = new Application();
document.body.appendChild(app.canvas);
app.init({ width: 800, height: 600 });
Correct:
ts
const app = new Application();
await app.init({ width: 800, height: 600 });
document.body.appendChild(app.canvas);
app.renderer
,
app.canvas
, and
app.screen
are only populated once the
init()
promise resolves. Accessing them earlier returns
undefined
.
错误写法:
ts
const app = new Application();
document.body.appendChild(app.canvas);
app.init({ width: 800, height: 600 });
正确写法:
ts
const app = new Application();
await app.init({ width: 800, height: 600 });
document.body.appendChild(app.canvas);
只有当
init()
承诺完成后,
app.renderer
app.canvas
app.screen
才会被赋值。提前访问会返回
undefined

API Reference

API 参考