pixijs-scene-container
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseContainerContainerSpriteGraphicsTextMeshAssumes familiarity with .
pixijs-scene-core-conceptsContainerContainerSpriteGraphicsTextMesh使用本技能需先熟悉。
pixijs-scene-core-conceptsQuick Start
快速开始
ts
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);Related skills: (scene graph mental model, masking, layers, render groups), / / / (leaf objects that go inside containers), (, hit testing), (Matrix, toGlobal/toLocal detail), (, culling, render groups).
pixijs-scene-core-conceptspixijs-scene-spritepixijs-scene-graphicspixijs-scene-textpixijs-scene-meshpixijs-eventseventModepixijs-mathpixijs-performancecacheAsTexturets
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);相关技能:(场景图思维模型、遮罩、图层、渲染组)、 / / / (可嵌套在容器中的叶子对象)、(、点击测试)、(Matrix、toGlobal/toLocal细节)、(、剔除、渲染组)。
pixijs-scene-core-conceptspixijs-scene-spritepixijs-scene-graphicspixijs-scene-textpixijs-scene-meshpixijs-eventseventModepixijs-mathpixijs-performancecacheAsTextureCore Patterns
核心模式
Constructor options
构造函数选项
ts
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),
});All options (, , , , , , etc.) are also valid here — see .
ContainerpositionscaletintlabelfilterszIndexskills/pixijs-scene-core-concepts/references/constructor-options.mdThe constructor uses to bulk-copy every field in the options object onto the instance except , , and . Any public property of is a valid constructor option: , , , , , , and so on. The options block above groups the most common ones; see the shared reference above for the full list.
ContainerassignWithIgnorechildrenparenteffectsContainercullablecullAreamaskfilterAreaeventModehitAreaisRenderGroup: truepixijs-scene-core-concepts/references/scene-management.mdsortableChildren: truezIndexzIndexoriginObservablePointpivotoriginPointDatacontainer.origin.set(x, y)pivotoriginboundsAreagetBounds()cullablecullAreaassignWithIgnorepixijs-performancets
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),
});所有选项(、、、、、等)均适用于此处——详见。
ContainerpositionscaletintlabelfilterszIndexskills/pixijs-scene-core-concepts/references/constructor-options.mdContainerassignWithIgnorechildrenparenteffectsContainercullablecullAreamaskfilterAreaeventModehitAreaisRenderGroup: truepixijs-scene-core-concepts/references/scene-management.mdsortableChildren: truezIndexzIndexoriginObservablePointpivotoriginPointDatacontainer.origin.set(x, y)pivotoriginboundsAreagetBounds()cullablecullAreaassignWithIgnorepixijs-performanceLeaves vs containers
叶子对象 vs 容器
ts
const parent = new Container();
const sprite = new Sprite(texture);
parent.addChild(sprite);Only (and subclasses intended to hold children, like ) should have children. , , , , particles, and content are leaves by convention in PixiJS v8. Wrap them in a whenever you need to group things: give the container the layout logic and keep the leaves pure visual data. Adding children to a leaf logs a deprecation warning and is scheduled to become a hard error.
ContainerRenderLayerSpriteGraphicsTextMeshParticleContainerDOMContainerContainerts
const parent = new Container();
const sprite = new Sprite(texture);
parent.addChild(sprite);只有(以及用于容纳子对象的子类,如)才能拥有子对象。在PixiJS v8中,、、、、粒子和内容默认是叶子对象。当你需要分组时,请将它们包装在中:让容器处理布局逻辑,叶子对象仅保留纯视觉数据。向叶子对象添加子对象会记录弃用警告,并计划在未来版本中变为硬错误。
ContainerRenderLayerSpriteGraphicsTextMeshParticleContainerDOMContainerContainerAdding and removing children
添加和移除子对象
ts
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);addChildaddChildAtsetChildIndexswapChildrenremoveChildren(beginIndex?, endIndex?)Calling with a child that already belongs to the same container silently moves it to the new index. No / / / events fire, because the parent-child relationship didn't change. Events only fire when the child comes from a different parent (or from no parent).
addChildAtaddedchildAddedremovedchildRemovedFor reparenting that preserves world transform (so the child doesn't visually jump), use / . For swapping a child in place while copying the old child's local transform, use .
reparentChildreparentChildAtreplaceChildts
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);addChildaddChildAtsetChildIndexswapChildrenremoveChildren(beginIndex?, endIndex?)如果调用时传入的子对象已属于同一个容器,它会静默地将子对象移动到新索引。此时不会触发 / / / 事件,因为父子关系没有改变。只有当子对象来自不同父对象(或无父对象)时才会触发事件。
addChildAtaddedchildAddedremovedchildRemoved如需在重新父化时保留世界变换(避免子对象视觉上跳变),请使用 / 。如需替换子对象并复制旧子对象的局部变换,请使用。
reparentChildreparentChildAtreplaceChildTransform properties
变换属性
ts
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,pivotareskews. AssigningObservablePointis valid and sets both axes.scale = 2 - is radians;
rotationis degrees; they are aliases that stay in sync.angle - sets the point in local space that maps to
pivotin parent space; changing it both moves and rotates the container.position - and
alphamultiply down through children.tintapplies to this container's draw instructions.blendMode - skips rendering and transform updates.
visible = falseskips rendering but still updates transforms (use when you needrenderable = falseor hit-testing without drawing).getBounds()
ts
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均为skew。赋值ObservablePoint是有效的,会同时设置两个轴。scale = 2 - 使用弧度;
rotation使用角度;它们是同步的别名。angle - 设置局部空间中映射到父空间
pivot的点;修改它会同时移动和旋转容器。position - 和
alpha会向下传递给子对象。tint应用于该容器的绘制指令。blendMode - 会跳过渲染和变换更新。
visible = false会跳过渲染,但仍会更新变换(适用于需要renderable = false或点击测试但不需要绘制的场景)。getBounds()
zIndex and sortableChildren
zIndex与sortableChildren
ts
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);When is , the container re-sorts its children by before the next render. Changing any child's automatically re-marks the parent as needing sort. Sort only what you need to sort; leaving off is cheaper. If you want full manual control, call yourself after changing values.
sortableChildrentruezIndexzIndexsortableChildrencontainer.sortChildren()zIndexFor render-order control that is decoupled from the hierarchy (children keep their logical parent for transforms but render at a different z), use . See .
RenderLayerpixijs-scene-core-concepts/references/scene-management.mdts
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);当为时,容器会在下一次渲染前按重新排序其子对象。修改任何子对象的会自动标记父容器需要重新排序。仅对需要排序的内容启用该功能;关闭性能更优。如果需要完全手动控制,请在修改值后自行调用。
sortableChildrentruezIndexzIndexsortableChildrenzIndexcontainer.sortChildren()如需与层级解耦的渲染顺序控制(子对象保留逻辑父对象用于变换,但在不同z轴层级渲染),请使用。详见。
RenderLayerpixijs-scene-core-concepts/references/scene-management.mdBounds and coordinate conversion
边界与坐标转换
ts
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()BoundsRectanglexywidthheight.rectangleRectanglegetBounds(skipUpdate?: boolean, bounds?: Bounds)trueBoundstoGlobal(point)toLocal(point, from?)fromgetGlobalPosition()parent.toGlobal(this._position)ts
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()BoundsRectanglexywidthheight.rectangleRectanglegetBounds(skipUpdate?: boolean, bounds?: Bounds)trueBoundstoGlobal(point)toLocal(point, from?)fromgetGlobalPosition()parent.toGlobal(this._position)Sizing
尺寸设置
ts
const sprite = new Sprite(texture);
sprite.setSize(200, 100);
const { width, height } = sprite.getSize();setSizescale.width.heightsetSizets
const sprite = new Sprite(texture);
sprite.setSize(200, 100);
const { width, height } = sprite.getSize();setSizescale.width.heightsetSizeContainer events
容器事件
ts
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);| Event | Fires on | Arguments |
|---|---|---|
| the parent receiving the child | |
| the parent losing the child | |
| the child that was attached | |
| the child that was detached | |
| the destroyed container | |
| the container whose | |
These are emitted on the side of ; do not confuse them with pointer events from .
EventEmitterContainerpixijs-eventsdestroyedpositionscalepivotoriginskewparentchildrendestroy()ts
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);| 事件名称 | 触发对象 | 参数列表 |
|---|---|---|
| 接收子对象的父容器 | |
| 失去子对象的父容器 | |
| 被添加的子对象 | |
| 被移除的子对象 | |
| 被销毁的容器 | |
| | |
这些事件在的侧触发;请勿与中的指针事件混淆。
ContainerEventEmitterpixijs-eventsdestroyedpositionscalepivotoriginskewparentchildrendestroy()Per-frame updates with onRender
使用onRender进行每帧更新
ts
const container = new Container();
container.onRender = (renderer) => {
container.rotation += 0.01;
};
container.onRender = null;onRenderRendererupdateTransformonRender = nullts
const container = new Container();
container.onRender = (renderer) => {
container.rotation += 0.01;
};
container.onRender = null;onRenderRendererupdateTransformonRender = nullFinding and removing from parent
查找子对象与从父容器移除
ts
const player = world.getChildByLabel("player");
const enemies = world.getChildrenByLabel(/enemy-\d+/, true);
const bounds = hud.getLocalBounds();
oldSprite.removeFromParent();- — first match by string or
getChildByLabel(label, deep?). PassRegExpfor a recursive search.true - — all matches. Accepts an optional reusable output array.
getChildrenByLabel(label, deep?, out?) - — bounds in this container's own coordinate space, ignoring parent transforms. Cheaper than
getLocalBounds()for self-contained layout math.getBounds() - — detaches
removeFromParent()from its current parent (no-op if already orphaned).this
ts
const player = world.getChildByLabel("player");
const enemies = world.getChildrenByLabel(/enemy-\d+/, true);
const bounds = hud.getLocalBounds();
oldSprite.removeFromParent();- ——按字符串或
getChildByLabel(label, deep?)查找第一个匹配项。传入RegExp可进行递归搜索。true - ——查找所有匹配项。接受可选的可复用输出数组。
getChildrenByLabel(label, deep?, out?) - ——该容器自身坐标空间中的边界,忽略父容器变换。对于自包含的布局计算,比
getLocalBounds()更高效。getBounds() - ——将当前对象从其父容器中分离(如果已无父容器则无操作)。
removeFromParent()
Destroy
销毁
ts
container.destroy();
container.destroy({
children: true,
texture: true,
textureSource: true,
});
console.log(container.destroyed);By default unlinks this container from its parent and tears down its own state. Pass to recursively destroy every descendant; this is the usual call for killing a whole subtree. and additionally destroy the GPU resources referenced by leaf children (useful for sprites whose textures you loaded just for them). If is on, disable it with before destroying.
destroy(){ children: true }texture: truetextureSource: truecacheAsTexturecontainer.cacheAsTexture(false)ts
container.destroy();
container.destroy({
children: true,
texture: true,
textureSource: true,
});
console.log(container.destroyed);默认情况下,会将该容器与父容器解绑,并销毁自身状态。传入可递归销毁所有后代;这是销毁整个子树的常用调用方式。和会额外销毁叶子子对象引用的GPU资源(适用于仅为其加载纹理的精灵)。如果启用了,请在销毁前调用禁用它。
destroy(){ children: true }texture: truetextureSource: truecacheAsTexturecontainer.cacheAsTexture(false)Common Mistakes
常见错误
[CRITICAL] Adding children to leaf scene objects
[严重] 向叶子场景对象添加子对象
Wrong:
ts
const sprite = new Sprite(texture);
const overlay = new Sprite(overlayTexture);
sprite.addChild(overlay);Correct:
ts
const group = new Container();
const sprite = new Sprite(texture);
const overlay = new Sprite(overlayTexture);
group.addChild(sprite, overlay);Sprites, Graphics, Text, and Mesh are leaves. Adding children to them logs a deprecation warning now and will be an error in a future version. Always wrap them in a when you need grouping.
Container错误示例:
ts
const sprite = new Sprite(texture);
const overlay = new Sprite(overlayTexture);
sprite.addChild(overlay);正确示例:
ts
const group = new Container();
const sprite = new Sprite(texture);
const overlay = new Sprite(overlayTexture);
group.addChild(sprite, overlay);Sprite、Graphics、Text和Mesh是叶子对象。向它们添加子对象会记录弃用警告,并将在未来版本中变为错误。当你需要分组时,请始终将它们包装在中。
Container[HIGH] Expecting getBounds() to return a Rectangle
[高风险] 期望getBounds()返回Rectangle
Wrong:
ts
const rect = container.getBounds();
rect.contains(x, y); // TypeError: contains is not a functionCorrect:
ts
const rect = container.getBounds().rectangle;
rect.contains(x, y);
const bounds = container.getBounds();
console.log(bounds.width, bounds.height);getBounds()BoundsxywidthheightRectangle.contains()Rectangle.rectangle错误示例:
ts
const rect = container.getBounds();
rect.contains(x, y); // TypeError: contains is not a function正确示例:
ts
const rect = container.getBounds().rectangle;
rect.contains(x, y);
const bounds = container.getBounds();
console.log(bounds.width, bounds.height);在v8中,返回实例。它的基本getter(、、、)可用,但对于等特定方法,或需要传入的API,请读取属性。
getBounds()Boundsxywidthheight.contains()RectangleRectangle.rectangle[HIGH] Using cacheAsBitmap instead of cacheAsTexture
[高风险] 使用cacheAsBitmap而非cacheAsTexture
Wrong:
ts
container.cacheAsBitmap = true;Correct:
ts
container.cacheAsTexture(true);cacheAsBitmapcacheAsTexture()cacheAsTexture(false)destroy()错误示例:
ts
container.cacheAsBitmap = true;正确示例:
ts
container.cacheAsTexture(true);v7中的属性在v8中重命名为方法。调用前请始终使用禁用它。
cacheAsBitmapcacheAsTexture()destroy()cacheAsTexture(false)[MEDIUM] Using container.name instead of container.label
[中风险] 使用container.name而非container.label
namelabelgetChildByLabel在v8中,已重命名为。旧属性仍可作为弃用别名使用;是v8中按名称查找子对象的方式。
namelabelgetChildByLabel[MEDIUM] Setting both pivot and origin on the same container
[中风险] 在同一个容器上同时设置pivot和origin
Pivot shifts the projection of the local origin in parent space (moves the object as a side-effect of changing the rotation center). Origin changes the rotation/scale center without displacement. Setting both on the same container produces unexpected compounding; pick one.
Pivot会改变父空间中局部原点的投影(修改旋转中心时会导致对象位移)。Origin会改变旋转/缩放中心但不会导致位移。在同一个容器上同时设置两者会产生意外的复合行为;请选择其中一个。