mcpField
P
pixijs-application

pixijs-application

github.com/pixijs开发3586.2k 次安装4 周前更新
代码仓库

关于 pixijs-application

pixijs-application 是面向 PixiJS v8 Application 的专项技能,介绍异步初始化、渲染器与舞台访问,以及调整大小、Ticker 和生命周期管理。适合构建或配置 PixiJS 应用的开发者。

主要功能

  1. 01说明异步 Application 初始化
  2. 02介绍渲染器、画布与舞台属性
  3. 03配置自动调整大小与 Ticker
  4. 04管理销毁、插件和手动渲染

适用场景

  1. 01创建并初始化 PixiJS 应用
  2. 02让画布适配窗口或容器尺寸
  3. 03控制逐帧更新与应用销毁

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/pixijs/pixijs-skills --skill pixijs-application

安装后在 Claude Code 中输入/pixijs-application确认已加载。

附带文件references/application-options.md

详细介绍

Application 是一个便捷封装,拥有一个渲染器、一个根 stage Container、一个 canvas,以及 Ticker/Resize 插件。在 v8 中,构造函数不接受参数;所有配置都传入异步的 app.init() 调用,由它通过 autoDetectRenderer 实例化渲染器。

快速开始

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(非浏览器环境配置)。

核心模式

生命周期:构造、初始化、渲染、销毁
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() 会分配实例,但不会创建任何内容。在这里传入的选项会被忽略,并触发 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 中移除 canvas。在同一标签页中拆除并重新创建应用时,添加 releaseGlobalResources: true 可清理全局资源池(批处理、纹理缓存);省略此选项通常会导致重新初始化后画面闪烁和纹理过期(参见 pixijs-performance)。
关键初始化选项
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,
});

有关所有选项——view/canvas、背景、渲染器首选项(包括数组形式)、ticker、resize、culler、events、accessibility、WebGL/WebGPU 上下文标志、Graphics 贝塞尔平滑度、GC,以及每种渲染器的覆盖选项(webgl / webgpu / canvasOptions)——请参阅 references/application-options.md。

Application 属性
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 是一个普通的 Container。有关场景图详情(变换、addChild、destroy),请参阅 pixijs-scene-container。有关渲染器级操作(extract、generateTexture、自定义系统),请参阅 pixijs-core-concepts 和 pixijs-custom-rendering。app.domContainerRoot 是渲染器用于承载 DOMContainer 覆盖层的 <div>;需要将 DOM 元素固定到场景节点时,请将它追加到 app.canvas 旁边(参见 pixijs-scene-dom-container)。

ResizePlugin

在初始化时设置 resizeTo(或稍后重新赋值给 app.resizeTo),插件便会监听 resize 事件,并使用目标元素的客户端尺寸调用 renderer.resize()。结合 autoDensity: true 和 resolution: window.devicePixelRatio,即可获得高 DPI 输出。

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

该插件会使 canvas 始终与目标匹配。app.screen 和 app.canvas.width/height 会随之更新;调整大小后读取它们,即可放置 UI。

  • app.resize() —— 立即同步调整大小。
  • app.queueResize() —— 将调用推迟到下一帧,以合并快速连续的调用;内部的 window.resize 监听器会使用它来避免重复操作。
  • app.cancelResize() —— 取消排队的调整大小操作。在拆除触发了 queueResize 的自定义布局代码之前调用此方法。
Ticker 基础知识

TickerPlugin 会创建 app.ticker,并以 UPDATE_PRIORITY.LOW 优先级在其上注册 app.render()。使用 app.start()/app.stop() 控制循环,并通过 app.ticker.add / app.ticker.addOnce 添加回调:

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

回调会接收 Ticker 实例;读取 ticker.deltaTime 可获取与帧率无关的倍率(60fps 时约为 1.0),读取 ticker.deltaMS 可获取实际毫秒数,读取 ticker.FPS 可获取当前帧率。有关优先级、FPS 上限、onRender、共享与私有 ticker,以及 v8 回调签名变更,请参阅 pixijs-ticker。

手动渲染循环
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(可选启用)

CullerPlugin 会跳过渲染位于 app.renderer.screen 之外的容器。它默认不会注册;请在创建应用前添加:

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);

除非设置了 cullable,否则不会对容器进行剔除。当计算子项边界的开销较高时,可使用 container.cullArea = new Rectangle(x, y, w, h) 覆盖默认的边界检查。该插件会包装 app.render(),使 Culler.shared.cull(app.stage, app.renderer.screen) 在每一帧之前运行。关于何时进行剔除有收益,请参阅 pixijs-performance。

自定义 Application 插件

通过注册具有 static init、static destroy 和 static extension = ExtensionType.Application 的类来扩展 Application。这两个方法调用时都会将 this 绑定到 Application 实例,因此可以访问 this.renderer 和 this.stage。

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);

插件按注册顺序初始化,并按相反顺序销毁。若要为插件添加类型化选项,请扩展 PixiMixins.ApplicationOptions:

declare global {
  namespace PixiMixins {
    interface ApplicationOptions {
      fpsOverlay?: { visible?: boolean };
    }
  }
}

await app.init({ fpsOverlay: { visible: true } });

内置的 ResizePlugin、TickerPlugin 和可选启用的 CullerPlugin 都使用相同的约定。如果设置了 skipExtensionImports: true,请自行注册所需的内置插件(extensions.add(ResizePlugin, TickerPlugin))。

常见错误

[CRITICAL] 向构造函数传递选项

错误:

const app = new Application({ width: 800, height: 600 });
document.body.appendChild(app.canvas);

正确:

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

在 v8 中,Application 构造函数不接受参数。传入其中的选项会被忽略,并记录弃用警告;只有在异步 init() 调用中才会创建渲染器。

[HIGH] 使用 app.view 而不是 app.canvas

错误:

document.body.appendChild(app.view);

正确:

document.body.appendChild(app.canvas);

在 v8 中,app.view 已重命名为 app.canvas。旧 getter 仍可使用,但会发出弃用警告。

[MEDIUM] 在 init 完成前访问 app.canvas 或 app.renderer

错误:

const app = new Application();
document.body.appendChild(app.canvas);
app.init({ width: 800, height: 600 });

正确:

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

只有在 init() Promise 完成后,才会填充 app.renderer、app.canvas 和 app.screen。提前访问会返回 undefined。

API 参考

评论

支持 Markdown