Container est le nœud polyvalent du graphe de scène PixiJS v8. Il contient des enfants et applique des transformations, de l'alpha, une teinte et un mode de mélange à tout son sous-arbre. Chaque objet d'affichage que vous créez sera soit un Container sur lequel vous construisez une branche, soit une feuille (Sprite, Graphics, Text, Mesh) que vous imbriquez à l'intérieur.
Suppose une familiarité avec pixijs-scene-core-concepts.
Démarrage rapide
const group = new Container({
label: "hero-group",
x: 200,
y: 150,
sortableChildren: true,
});
const body = new Sprite(await Assets.load("body.png"));
const head = new Sprite(await Assets.load("head.png"));
head.position.set(0, -40);
head.zIndex = 1;
group.addChild(body, head);
group.pivot.set(group.width / 2, group.height / 2);
group.scale.set(1.5);
app.stage.addChild(group);
Compétences associées : pixijs-scene-core-concepts (modèle conceptuel du graphe de scène, masquage, couches, groupes de rendu), pixijs-scene-sprite / pixijs-scene-graphics / pixijs-scene-text / pixijs-scene-mesh (objets feuilles à intégrer dans les conteneurs), pixijs-events (eventMode, test de sélection), pixijs-math (Matrix, détails toGlobal/toLocal), pixijs-performance (cacheAsTexture, culling, groupes de rendu).
Motifs fondamentaux
Options du constructeur
const container = new Container({
label: "world",
x: 100,
y: 50,
scale: 2,
rotation: Math.PI / 4,
alpha: 0.8,
visible: true,
tint: 0xffaa00,
blendMode: "add",
sortableChildren: true,
isRenderGroup: true,
origin: { x: 0, y: 0 },
boundsArea: new Rectangle(0, 0, 1920, 1080),
});
Toutes les options de Container (position, scale, tint, label, filters, zIndex, etc.) sont également valides ici — voir skills/pixijs-scene-core-concepts/references/constructor-options.md.
Le constructeur Container utilise assignWithIgnore pour copier en masse chaque champ de l'objet options sur l'instance, sauf children, parent et effects. Toute propriété publique de Container est une option de constructeur valide : cullable, cullArea, mask, filterArea, eventMode, hitArea, et ainsi de suite. Le bloc d'options ci-dessus regroupe les plus courantes ; consultez la référence partagée ci-dessus pour la liste complète.
isRenderGroup: true promeut le conteneur en son propre groupe de rendu afin que ses transformations soient appliquées sur le GPU plutôt que recalculées par enfant sur le CPU. Utilisez-le sur des sous-arbres stables (grands mondes statiques, couches d'UI). Ne pas abuser ; la plupart des scènes n'ont pas besoin de groupes de rendu explicites et trop de groupes nuisent aux performances. Profilez avant de promouvoir. Voir pixijs-scene-core-concepts/references/scene-management.md.
sortableChildren: true force les enfants à être retriés par zIndex au prochain rendu. Voir zIndex ci-dessous.
origin est un helper de transformation de première classe en v8 : un ObservablePoint qui agit comme centre de rotation/mise à l'échelle sans déplacer le conteneur. Tandis que pivot décale la projection de l'origine locale dans l'espace parent (donc la changer déplace l'objet), origin laisse la position inchangée et tourne/met à l'échelle simplement autour du point local spécifié. Accepte PointData, un seul nombre (appliqué aux deux axes), ou peut être défini en direct via container.origin.set(x, y). Définir à la fois pivot et origin sur le même conteneur produit un comportement composé et est déconseillé ; choisissez l'un ou l'autre.
boundsArea force getBounds() à retourner un rectangle fixe au lieu de mesurer récursivement les enfants ; c'est un gain de performance pour les conteneurs avec des centaines d'enfants bon marché et prévisibles.
cullable et cullArea sont des options de constructeur valides (la passe assignWithIgnore les copie comme n'importe quel autre champ), mais ils sont documentés dans pixijs-performance car la configuration du culling est une préoccupation de performance plutôt qu'une préoccupation du graphe de scène.
Feuilles vs conteneurs
const parent = new Container();
const sprite = new Sprite(texture);
parent.addChild(sprite);
Seul Container (et les sous-classes destinées à tenir des enfants, comme RenderLayer) doivent avoir des enfants. Sprite, Graphics, Text, Mesh, les particules ParticleContainer et le contenu DOMContainer sont des feuilles par convention dans PixiJS v8. Enveloppez-les dans un Container chaque fois que vous avez besoin de regrouper des choses : donnez au conteneur la logique de disposition et gardez les feuilles comme données visuelles pures. Ajouter des enfants à une feuille enregistre un avertissement de déppréciation et est prévu de devenir une erreur stricte.
Ajouter et supprimer des enfants
const parent = new Container();
parent.addChild(a, b, c);
parent.addChildAt(d, 0);
parent.swapChildren(a, b);
parent.setChildIndex(c, 0);
parent.removeChild(b);
parent.removeChildAt(0);
parent.removeChildren();
parent.removeChildren(0, 2);
addChild accepte n'importe quel nombre d'enfants et retourne le premier. Les enfants s'affichent dans l'ordre du tableau : l'index 0 est dessiné en premier (derrière), le dernier index est dessiné en dernier (devant). addChildAt insère à un index spécifique ; setChildIndex déplace un enfant existant ; swapChildren échange les positions de deux enfants.
removeChildren(beginIndex?, endIndex?) supprime une tranche et retourne le tableau supprimé.
Appeler addChildAt avec un enfant qui appartient déjà au même conteneur le déplace silencieusement vers le nouvel index. Aucun événement added / childAdded / removed / childRemoved n'est déclenché, car la relation parent-enfant n'a pas changé. Les événements sont déclenchés uniquement quand l'enfant vient d'un parent différent (ou d'aucun parent).
Pour une réaffectation de parent qui préserve la transformation mondiale (afin que l'enfant ne saute pas visuellement), utilisez reparentChild / reparentChildAt. Pour remplacer un enfant en place tout en copiant la transformation locale du vieil enfant, utilisez replaceChild.
Propriétés de transformation
const obj = new Container();
obj.x = 100;
obj.y = 200;
obj.position.set(100, 200);
obj.scale.set(2);
obj.scale = 2;
obj.rotation = Math.PI / 4;
obj.angle = 45;
obj.pivot.set(50, 50);
obj.skew.set(0.1, 0.2);
obj.alpha = 0.5;
obj.tint = 0xff0000;
obj.visible = false;
obj.renderable = false;
position,scale,pivot,skewsont desObservablePoint. Assignerscale = 2est valide et définit les deux axes.rotationest en radians ;angleest en degrés ; ce sont des alias qui restent synchronisés.pivotdéfinit le point en espace local qui correspond àpositionen espace parent ; le changer déplace et tourne le conteneur.alphaettintse multiplient vers le bas à travers les enfants.blendModes'applique aux instructions de dessin de ce conteneur.visible = falsesaute le rendu et les mises à jour de transformation.renderable = falsesaute le rendu mais met à jour quand même les transformations (à utiliser quand vous avez besoin degetBounds()ou du test de sélection sans dessiner).
zIndex et sortableChildren
const world = new Container({ sortableChildren: true });
const ground = new Sprite(groundTexture);
ground.zIndex = 0;
const player = new Sprite(playerTexture);
player.zIndex = 10;
const ui = new Sprite(uiTexture);
ui.zIndex = 100;
world.addChild(ground, player, ui);
Quand sortableChildren est true, le conteneur retrie ses enfants par zIndex avant le prochain rendu. Changer le zIndex de n'importe quel enfant marque automatiquement le parent comme ayant besoin d'un tri. Triez uniquement ce que vous avez besoin de trier ; laisser sortableChildren désactivé est moins cher. Si vous voulez un contrôle complètement manuel, appelez container.sortChildren() vous-même après avoir changé les valeurs de zIndex.
Pour un contrôle de l'ordre de rendu découplé de la hiérarchie (les enfants gardent leur parent logique pour les transformations mais se rendent à un z différent), utilisez RenderLayer. Voir pixijs-scene-core-concepts/references/scene-management.md.
Limites et conversion de coordonnées
const bounds = container.getBounds();
console.log(bounds.x, bounds.y, bounds.width, bounds.height);
const rect = container.getBounds().rectangle;
const local = new Point(10, 20);
const world = container.toGlobal(local);
const backToLocal = container.toLocal(world);
const selfPos = container.getGlobalPosition();
getBounds() retourne un objet Bounds (pas un Rectangle) ; il expose x, y, width, height, et un getter .rectangle pour les API qui ont besoin d'un vrai Rectangle. La signature est getBounds(skipUpdate?: boolean, bounds?: Bounds) — passez true comme premier argument pour sauter la mise à jour forcée des transformations, et une instance Bounds optionnelle comme deuxième argument pour éviter d'en allouer une nouvelle.
toGlobal(point) convertit un point dans l'espace local de ce conteneur en espace de racine de scène. toLocal(point, from?) convertit depuis l'espace local d'un autre conteneur (ou l'espace global si from est omis). getGlobalPosition() est un raccourci pour parent.toGlobal(this._position).
Dimensionnement
const sprite = new Sprite(texture);
sprite.setSize(200, 100);
const { width, height } = sprite.getSize();
setSize ajuste scale pour que les limites du conteneur s'ajustent à la taille de pixel demandée, en une seule opération. Définir .width et .height individuellement fonctionne, mais chaque assignation déclenche un recalcul de limites séparé ; préférez setSize quand vous changez les deux axes.
Événements de conteneur
const parent = new Container();
parent.on("childAdded", (child, container, index) => {
console.log("added at", index, child.label);
});
parent.on("childRemoved", (child, container, index) => {
console.log("removed from", index);
});
const child = new Container();
child.on("added", (newParent) => console.log("entered", newParent.label));
child.on("removed", (oldParent) => console.log("left", oldParent.label));
child.on("visibleChanged", (visible) => console.log("visible:", visible));
child.on("destroyed", (destroyed) => console.log("gone", destroyed.label));
parent.addChild(child);
| Événement | Déclenché sur | Arguments |
|---|---|---|
childAdded |
le parent recevant l'enfant | (child, container, index) |
childRemoved |
le parent perdant l'enfant | (child, container, index) |
added |
l'enfant qui a été attaché | (parent) |
removed |
l'enfant qui a été détaché | (parent) |
destroyed |
le conteneur détruit | (container) |
visibleChanged |
le conteneur dont visible a basculé |
(visible) |
Ces événements sont émis du côté EventEmitter de Container ; ne les confondez pas avec les événements de pointeur de pixijs-events.
destroyed est déclenché après le nettoyage interne mais avant la suppression des écouteurs, donc au moment où votre gestionnaire s'exécute position, scale, pivot, origin, skew et parent ont déjà été annulés, et children a été vidé (longueur 0, mais la référence du tableau elle-même n'est pas annulée). Capturez les données dont vous avez besoin du conteneur avant d'appeler destroy(), pas à l'intérieur du gestionnaire.
Mises à jour par frame avec onRender
const container = new Container();
container.onRender = (renderer) => {
container.rotation += 0.01;
};
container.onRender = null;
onRender s'exécute chaque frame tandis que le conteneur est rendu, et reçoit le Renderer actif. Utilisez-le pour l'animation légère ou les mises à jour par frame liées à un conteneur spécifique. En v7 ce motif était fait en remplaçant updateTransform, qui ne s'exécute plus à chaque frame en v8. Définissez onRender = null pour détacher le callback.
Recherche et suppression du parent
const player = world.getChildByLabel("player");
const enemies = world.getChildrenByLabel(/enemy-\d+/, true);
const bounds = hud.getLocalBounds();
oldSprite.removeFromParent();
getChildByLabel(label, deep?)— première correspondance par chaîne ouRegExp. Passeztruepour une recherche récursive.getChildrenByLabel(label, deep?, out?)— toutes les correspondances. Accepte un tableau de sortie réutilisable optionnel.getLocalBounds()— limites dans l'espace de coordonnées propre de ce conteneur, en ignorant les transformations du parent. Moins cher quegetBounds()pour les mathématiques de disposition autonomes.removeFromParent()— détachethisde son parent actuel (pas d'opération s'il est déjà orphelin).
Destruction
container.destroy();
container.destroy({
children: true,
texture: true,
textureSource: true,
});
console.log(container.destroyed);
Par défaut destroy() délien ce conteneur de son parent et démantèle son propre état. Passez { children: true } pour détruire récursivement chaque descendant ; c'est l'appel habituel pour tuer un sous-arbre entier. texture: true et textureSource: true détruisent en outre les ressources GPU référencées par les enfants feuilles (utile pour les sprites dont les textures vous avez chargées uniquement pour eux). Si cacheAsTexture est activé, désactivez-le avec container.cacheAsTexture(false) avant de détruire.
Erreurs courantes
[CRITIQUE] Ajouter des enfants aux objets de scène feuille
Mauvais :
const sprite = new Sprite(texture);
const overlay = new Sprite(overlayTexture);
sprite.addChild(overlay);
Correct :
const group = new Container();
const sprite = new Sprite(texture);
const overlay = new Sprite(overlayTexture);
group.addChild(sprite, overlay);
Sprites, Graphics, Text et Mesh sont des feuilles. Ajouter des enfants à ces derniers enregistre un avertissement de dépréciation maintenant et sera une erreur dans une version future. Enveloppez toujours-les dans un Container quand vous avez besoin de regroupement.
[HAUTE] S'attendre à ce que getBounds() retourne un Rectangle
Mauvais :
const rect = container.getBounds();
rect.contains(x, y); // TypeError: contains is not a function
Correct :
const rect = container.getBounds().rectangle;
rect.contains(x, y);
const bounds = container.getBounds();
console.log(bounds.width, bounds.height);
getBounds() retourne une instance Bounds en v8. Ses getters basiques (x, y, width, height) fonctionnent, mais pour les méthodes spécifiques à Rectangle comme .contains() ou le passage aux API qui nécessitent un Rectangle, lisez la propriété .rectangle.
[HAUTE] Utiliser cacheAsBitmap au lieu de cacheAsTexture
Mauvais :
container.cacheAsBitmap = true;
Correct :
container.cacheAsTexture(true);
cacheAsBitmap (propriété v7) a été renommé en cacheAsTexture() (une méthode) en v8. Toujours le désactiver avec cacheAsTexture(false) avant d'appeler destroy().
[MOYEN] Utiliser container.name au lieu de container.label
name a été renommé en label en v8. L'ancienne propriété fonctionne toujours en tant qu'alias déprécié ; getChildByLabel est la manière v8 de rechercher les enfants par nom.
[MOYEN] Définir à la fois pivot et origin sur le même conteneur
Pivot décale la projection de l'origine locale dans l'espace parent (déplace l'objet comme effet secondaire du changement du centre de rotation). Origin change le centre de rotation/mise à l'échelle sans déplacement. Définir les deux sur le même conteneur produit un comportement composé inattendu ; choisissez l'un ou l'autre.