pixijs-application

Par pixijs · pixijs-skills

Utilisez cette compétence lors de la création et de la configuration d'une Application PixiJS v8. Couvre new Application() + les options async app.init() (width, height, background, antialias, resolution, autoDensity, preference, resizeTo, autoStart, sharedTicker, canvas, useBackBuffer, powerPreference, eventFeatures, accessibilityOptions, gcActive, bezierSmoothness, ainsi que les surcharges par renderer webgl/webgpu/canvasOptions), l'accès à app.stage/renderer/canvas/screen/domContainerRoot, ResizePlugin, TickerPlugin, CullerPlugin (cullable, cullArea), la création de plugins ApplicationPlugin personnalisés via ExtensionType.Application, le cycle de vie start/stop, et app.destroy() avec releaseGlobalResources. Se déclenche sur : Application, app.init, app.stage, app.renderer, app.canvas, app.screen, app.domContainerRoot, ApplicationOptions, ApplicationPlugin, ExtensionType.Application, resizeTo, preference, autoStart, sharedTicker, useBackBuffer, powerPreference, skipExtensionImports, preferWebGLVersion, preserveDrawingBuffer, cullable, CullerPlugin, app.start, app.stop, app.destroy, releaseGlobalResources.

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

Application est le wrapper de commodité qui possède un renderer, un Container stage racine, un canvas et les plugins Ticker/Resize. En v8, le constructeur ne prend aucun argument ; toute la configuration est passée à l'appel async app.init() qui instancie le renderer via autoDetectRenderer.

Démarrage rapide

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

Skills associées : pixijs-core-concepts (renderers, pipeline de rendu), pixijs-ticker (détail de la boucle de rendu), pixijs-scene-container (travailler avec app.stage), pixijs-environments (configurations non-navigateur).

Motifs fondamentaux

Cycle de vie : construct, init, render, destroy

import { Application } from "pixi.js";

const app = new Application();

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

// ... exécuter la scène, le ticker lance app.render() automatiquement ...

app.destroy(
  { removeView: true, releaseGlobalResources: true },
  { children: true, texture: true, textureSource: true },
);
  • new Application() alloue l'instance mais ne crée rien. Les options passées ici sont ignorées avec un avertissement de dépréciation v8.
  • app.init(options) est async. Elle construit le renderer, câble les plugins et doit se terminer avant que vous puissiez utiliser app.canvas, app.renderer ou app.screen.
  • Le TickerPlugin appelle app.render() à chaque frame une fois init résolu (sauf si autoStart: false).
  • app.destroy(rendererDestroyOptions, stageDestroyOptions) — le premier argument est transmis à renderer.destroy(). Passez true ou { removeView: true } pour retirer le canvas du DOM. Ajoutez releaseGlobalResources: true pour vider les pools globaux (batches, caches de textures) lors du démontage et de la recréation d'une app dans le même onglet ; l'ommettre est la cause habituelle du scintillement et des textures obsolètes après une réinit (voir pixijs-performance).

Options d'init clés

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

Pour chaque option — view/canvas, background, préférence de renderer (y compris la forme tableau), ticker, resize, culler, events, accessibility, drapeaux de contexte WebGL/WebGPU, lissage des courbes Bézier Graphics, GC et surcharges par renderer (webgl / webgpu / canvasOptions) — voir references/application-options.md.

Propriétés d'Application

app.stage; // Container racine ; ajouter tous les display objects ici
app.renderer; // l'instance du renderer WebGL/WebGPU/Canvas
app.canvas; // l'HTMLCanvasElement (l'insérer dans le DOM vous-même)
app.screen; // Rectangle décrivant la zone visible en pixels CSS
app.domContainerRoot; // HTMLDivElement qui contient les overlays DOMContainer

app.stage est un plain Container. Pour les détails du graphe de scène (transforms, addChild, destroy) voir pixijs-scene-container. Pour les opérations au niveau du renderer (extract, generateTexture, systèmes personnalisés) voir pixijs-core-concepts et pixijs-custom-rendering. app.domContainerRoot est le <div> que le renderer utilise pour héberger les overlays DOMContainer ; l'ajouter à côté de app.canvas quand vous avez besoin d'éléments DOM épinglés aux nœuds de la scène (voir pixijs-scene-dom-container).

ResizePlugin

Définissez resizeTo à l'init (ou réassignez app.resizeTo plus tard) pour que le plugin écoute l'événement resize et appelle renderer.resize() avec la taille client de l'élément cible. Combinez avec autoDensity: true et resolution: window.devicePixelRatio pour une sortie haute résolution.

await app.init({ resizeTo: window });

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

app.resize(); // redimensionnement immédiat à la taille actuelle de la cible
app.queueResize(); // reporter le redimensionnement à la prochaine frame d'animation
app.cancelResize(); // abandonner un queueResize en attente

Le plugin maintient le canvas aligné avec la cible. app.screen et app.canvas.width/height se mettent à jour en réponse ; les lire après le redimensionnement pour placer l'UI.

  • app.resize() — redimensionnement synchrone immédiat.
  • app.queueResize() — coalesce les appels rapides en reportant à la frame suivante ; utilisé en interne par le listener window.resize pour éviter les travaux redondants.
  • app.cancelResize() — annule un redimensionnement en attente. Appelez ceci avant de démanteler votre propre code de layout qui a déclenché queueResize.

Principes de base du Ticker

Le TickerPlugin crée app.ticker et enregistre app.render() dessus à UPDATE_PRIORITY.LOW. Contrôlez la boucle avec app.start()/app.stop() et ajoutez des callbacks avec app.ticker.add / app.ticker.addOnce :

app.ticker.add((ticker) => {
  sprite.rotation += 0.01 * ticker.deltaTime;
});

app.ticker.addOnce(() => {
  console.log("s'exécute une fois à la prochaine frame, puis se supprime");
});

app.stop(); // pause la boucle de rendu (p.ex. onglet caché)
app.start(); // reprendre

Le callback reçoit l'instance Ticker ; lisez ticker.deltaTime pour un multiplicateur indépendant de la fréquence d'images (~1,0 à 60fps), ticker.deltaMS pour les vrais millisecondes, ou ticker.FPS pour la fréquence d'images actuelle. Voir pixijs-ticker pour les priorités, le FPS capping, onRender, les tickers partagés vs privés, et le changement de signature de callback v8.

Boucle de rendu manuelle

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

function frame() {
  updateScene();
  app.render();
  requestAnimationFrame(frame);
}
frame();

autoStart: false empêche le TickerPlugin de démarrer le ticker automatiquement. Appelez app.render() vous-même (ou app.renderer.render({ container: app.stage }) pour le même effet). Si vous voulez toujours que les callbacks ticker enregistrés se déclenchent, appelez app.ticker.update() dans votre boucle avant app.render().

CullerPlugin (opt-in)

Le CullerPlugin saute le rendu des containers qui se situent en dehors de app.renderer.screen. Il n'est pas enregistré par défaut ; ajoutez-le avant de créer votre app :

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; // ce container est culled quand ses bounds quittent l'écran
world.cullableChildren = true; // défaut ; mettre à `false` pour sauter la récursion sur les enfants

const tile = Sprite.from("tile.png");
tile.cullable = true;
world.addChild(tile);
app.stage.addChild(world);

Les containers ne sont pas cullés à moins que cullable soit défini. Surchargez la vérification des bounds par défaut avec container.cullArea = new Rectangle(x, y, w, h) quand les bounds des enfants sont coûteux à calculer. Le plugin enveloppe app.render() donc Culler.shared.cull(app.stage, app.renderer.screen) s'exécute avant chaque frame. Voir pixijs-performance pour savoir quand le culling en vaut la peine.

Plugins Application personnalisés

Étendez Application en enregistrant une classe avec static init, static destroy et static extension = ExtensionType.Application. Les deux méthodes sont appelées avec this lié à l'instance Application, donc this.renderer et this.stage sont disponibles.

import {
  Application,
  ExtensionType,
  extensions,
  type ApplicationOptions,
} from "pixi.js";

class FpsOverlay {
  public static extension = ExtensionType.Application;

  public static init(this: Application, options: Partial<ApplicationOptions>) {
    // s'exécute à l'intérieur de app.init() après la création du renderer
    // attacher des props/méthodes à `this` pour les exposer sur l'app
  }

  public static destroy(this: Application) {
    // s'exécute à l'intérieur de app.destroy() — démanteler tout ce que vous avez attaché
  }
}

extensions.add(FpsOverlay);

Les plugins s'initialisent dans l'ordre d'enregistrement et se détruisent à l'inverse. Pour ajouter des options typées pour votre plugin, étendez PixiMixins.ApplicationOptions :

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

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

Les ResizePlugin, TickerPlugin et CullerPlugin opt-in intégrés utilisent tous ce même contrat. Si vous définissez skipExtensionImports: true, enregistrez les intégrés dont vous avez besoin vous-même (extensions.add(ResizePlugin, TickerPlugin)).

Erreurs courantes

[CRITIQUE] Passer des options au constructeur

Mauvais :

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

Correct :

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

En v8, le constructeur Application ne prend aucun argument. Les options passées là sont ignorées et consignent un avertissement de dépréciation ; le renderer est créé uniquement à l'intérieur de l'appel async init().

[HAUT] Utiliser app.view au lieu de app.canvas

Mauvais :

document.body.appendChild(app.view);

Correct :

document.body.appendChild(app.canvas);

app.view a été renommé en app.canvas en v8. L'ancien getter fonctionne toujours mais émet un avertissement de dépréciation.

[MOYEN] Accéder à app.canvas ou app.renderer avant que init se termine

Mauvais :

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

Correct :

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

app.renderer, app.canvas et app.screen ne sont remplis qu'une fois que la promise init() se résout. Y accéder plus tôt retourne undefined.

Référence API

Skills similaires