
pixijs-scene-core-concepts
熱門當你需要整體理解 PixiJS v8 場景圖(scene graph)時使用此技能:容器(Container)與葉節點(leaf)的區別、本地/世界座標、剔除(culling)、渲染群組(render group)、可排序子節點(sortable children)、遮罩(masking)、RenderLayer、所有場景節點共用的建構選項,以及各葉節點技能對應的顯示物件。觸發關鍵字:場景圖、顯示清單、Container、Sprite、Graphics、Text、Mesh、ParticleContainer、DOMContainer、GifSprite、遮罩、渲染群組、RenderLayer、世界變換、建構選項、ContainerOptions。
當你需要整體理解 PixiJS v8 場景圖(scene graph)時使用此技能:容器(Container)與葉節點(leaf)的區別、本地/世界座標、剔除(culling)、渲染群組(render group)、可排序子節點(sortable children)、遮罩(masking)、RenderLayer、所有場景節點共用的建構選項,以及各葉節點技能對應的顯示物件。觸發關鍵字:場景圖、顯示清單、Container、Sprite、Graphics、Text、Mesh、ParticleContainer、DOMContainer、GifSprite、遮罩、渲染群組、RenderLayer、世界變換、建構選項、ContainerOptions。
此技能是所有 pixijs-scene-* 葉節點技能共享的心智模型。它說明 PixiJS v8 中的場景圖是什麼、Container 與葉節點的差異,以及每個概念的位置。它不會深入任何單一 API;而是架構各個部分,並指向負責的葉節點技能或參考檔案。
快速入門
const world = new Container({ isRenderGroup: true });
app.stage.addChild(world);
const hero = new Container({ label: "hero" });
hero.addChild(new Sprite(bodyTexture));
hero.addChild(new Sprite(faceTexture));
world.addChild(hero);
const mask = new Graphics().rect(0, 0, 800, 600).fill(0xffffff);
world.mask = mask;
world.addChild(mask);
hero.position.set(world.width / 2, world.height / 2);
相關技能: pixijs-scene-container(Container API 詳細說明)、葉節點技能(pixijs-scene-sprite、pixijs-scene-graphics、pixijs-scene-text、pixijs-scene-mesh、pixijs-scene-particle-container、pixijs-scene-dom-container、pixijs-scene-gif)、pixijs-events(點擊測試會遍歷場景圖)、pixijs-performance(快取、剔除、渲染群組)、pixijs-math(Matrix、toGlobal/toLocal 詳細說明)。
核心概念
場景圖是什麼
PixiJS 場景圖是以 app.stage 為根節點的顯示物件樹。每個節點都有父節點、相對於父節點的變換(位置、縮放、旋轉、錨點、傾斜),以及可選的視覺狀態(alpha、tint、blendMode、可見性)。每幀渲染器會遍歷這棵樹,將變換和視覺狀態合成到世界空間,剔除畫面外的物件,並發出繪圖呼叫。場景圖既是佈局模型,也是渲染順序:較早的兄弟節點繪製在較晚的兄弟節點之後。
v8 中的每個顯示物件都是 Container 的子類別。舊版的 DisplayObject 已被移除。
Container 與葉節點(重要)
樹中有兩種角色:
- 容器(Container):容納子節點的節點。使用
Container(或RenderLayer)來分組、定位或變換其他節點。 - 葉節點(Leaf):繪製某些內容且沒有子節點的節點。使用
Sprite、Graphics、Text、Mesh、ParticleContainer的Particle、DOMContainer或GifSprite作為葉節點。
在 PixiJS v8 中,葉節點不得有子節點。對 Sprite / Graphics / Text / Mesh 添加子節點會記錄棄用警告,並計劃在未來變成硬性錯誤。規則是:任何需要子節點的節點都使用 Container;不要將子節點嵌套在葉場景物件內部。 如果需要將葉節點與其他葉節點分組,請將它們包在 Container 中。
這個區別正是 pixijs-scene-* 技能如此拆分的原因:pixijs-scene-container 涵蓋分組節點,而每個葉節點都有自己的技能,專注於其繪製行為。
變換與座標空間
每個容器從其 position、scale、rotation、pivot 和 skew 組成一個 localTransform(一個 Matrix)。渲染器將父節點的 localTransform 相乘,產生 worldTransform(如果鏈中有渲染群組,則還有 groupTransform),將本地點映射到場景根空間。使用 toGlobal(point) 和 toLocal(point, from?) 在空間之間轉換,使用 getGlobalPosition() 取得此物件的世界位置。完整的 Matrix 詳細資訊在 pixijs-math 中;變換設定器和 toLocal/toGlobal 在 pixijs-scene-container 中。
渲染順序與顯式 z 排序
子節點按陣列順序渲染:索引 0 最先,最後索引最後。要在單個容器上進行顯式 z 排序,設定 sortableChildren = true 並為子節點指定 zIndex 值。如果需要渲染順序與邏輯層級結構解耦(例如,角色的父節點是遊戲世界,但繪製發生在 UI 層),請使用 RenderLayer。詳細資訊,包括何時偏好 sortableChildren 與 RenderLayer,請參閱 references/scene-management.md。
渲染群組
將容器標記為 isRenderGroup: true(或呼叫 container.enableRenderGroup())告訴 PixiJS 將其變換作為單一矩陣在 GPU 上應用,而不是每幀在 CPU 上重新計算每個後代的 worldTransform。在大型、穩定的子樹(如世界、UI 層或視差條)上使用渲染群組。詳細資訊在 references/scene-management.md 中。
剔除
cullable = true 加上 cullArea: Rectangle 告訴 CullerPlugin(或任何剔除傳遞)跳過渲染落在可見區域外的物件。cullableChildren = false 會短路子樹的遞迴剔除,適用於子節點始終在螢幕上的情況。剔除是效能主題;pixijs-performance 和 references/scene-management.md 涵蓋了取捨。
遮罩
設定 container.mask 為另一個顯示物件以裁剪其渲染。PixiJS 會自動選擇遮罩類型:Graphics 或 Container 遮罩使用模板緩衝區,Sprite 遮罩使用 Alpha 濾鏡,數字則選擇 ColorMask。所有四種遮罩類型(AlphaMask、StencilMask、ScissorMask、ColorMask)都在 references/masking.md 中說明。
可見性、Alpha、Tint 與混合模式
visible = false 跳過渲染和變換更新;renderable = false 跳過渲染但仍更新變換(當點擊測試或邊界查詢需要保持活躍時使用)。alpha 和 tint 會向下傳遞到子樹;blendMode 控制此容器的繪圖指令如何與目標上已有的內容合成。完整的混合模式列表請參閱 pixijs-blend-modes,每個節點的狀態請參閱 pixijs-scene-container。
銷毀語義
container.destroy() 解除一個節點的連結。container.destroy({ children: true }) 遞迴銷毀整個子樹;銷毀分支時始終使用此方法。texture: true 和 textureSource: true 會額外銷毀葉節點擁有的 GPU 資源。如果啟用了 cacheAsTexture,請在銷毀前停用它。pixijs-scene-container 記錄了完整的簽名。
生命週期事件
容器會發出層級結構和可見性變更的事件:父節點上的 childAdded / childRemoved,子節點上的 added / removed,以及容器本身的 visibleChanged 和 destroyed。適用於連接反應式 UI 更新或資源記帳。完整詳細資訊在 references/container-hierarchy.md 中。
葉節點比較:哪個技能涵蓋哪個物件
| 葉節點 | 主要用途 | 技能 |
|---|---|---|
Sprite |
在指定位置繪製單一紋理(變體 NineSliceSprite 用於可調整大小的 UI 面板,TilingSprite 用於重複背景)。 |
pixijs-scene-sprite |
Text / BitmapText / HTMLText / SplitText / SplitBitmapText |
渲染文字。基於 Canvas 的 Text 用於一般用途,BitmapText 用於大量低成本文字,HTMLText 用於豐富的 HTML/CSS 佈局,分割變體用於逐字元動畫。 |
pixijs-scene-text |
Graphics |
向量繪圖:形狀、線條、路徑、填色、描邊。由 GraphicsContext 支援。 |
pixijs-scene-graphics |
Mesh / MeshSimple / MeshPlane / MeshRope / PerspectiveMesh |
帶有著色器或紋理的自訂幾何體。使用 MeshRope 製作紋理路徑跟隨的帶狀效果,PerspectiveMesh 用於 2D 透視。 |
pixijs-scene-mesh |
ParticleContainer + Particle |
數千個輕量級精靈,具有受限的變換集,用於高吞吐量的粒子效果。 | pixijs-scene-particle-container |
DOMContainer |
在場景圖內定位的 HTML 元素渲染(適用於輸入框、iframe、無障礙覆蓋層)。 | pixijs-scene-dom-container |
GifSprite |
將動畫 GIF 播放為顯示物件。需要 pixi.js/gif。 |
pixijs-scene-gif |
Container 本身在 pixijs-scene-container 中說明,是所有葉節點所在的節點。
何時使用什麼(快速決策)
- "我想分組和變換一些顯示物件" →
Container,參閱pixijs-scene-container。 - "我想繪製一個紋理" →
Sprite,參閱pixijs-scene-sprite。 - "我想繪製向量形狀或路徑" →
Graphics,參閱pixijs-scene-graphics。 - "我想繪製文字" →
Text/BitmapText/HTMLText,參閱pixijs-scene-text。 - "我想要數千個低成本精靈" →
ParticleContainer,參閱pixijs-scene-particle-container。 - "我想要自訂幾何體網格或變形精靈" →
Mesh或其變體,參閱pixijs-scene-mesh。 - "我想裁剪一個子樹" → 設定
.mask,參閱references/masking.md。 - "我想要解耦的渲染順序" →
RenderLayer,參閱references/scene-management.md。 - "我想要大型穩定子樹的 GPU 級變換" →
isRenderGroup: true,參閱references/scene-management.md。 - "我想跳過畫面外渲染" →
cullable = true+CullerPlugin,參閱pixijs-performance。
參考資料
- references/constructor-options.md:所有
Container衍生節點繼承的約 30 個欄位(變換、顯示、層級結構、排序、佈局、效果、回呼),包含預設值、型別以及何時適合逐行賦值。所有葉節點技能的共享參考。 - references/container-hierarchy.md:新增/移除/交換子節點、保留變換的重新父級化、標籤導航、銷毀子樹。
- references/transforms.md:位置、縮放、旋轉、錨點、原點、傾斜、toGlobal/toLocal、三個矩陣(local/group/world)、邊界。
- references/masking.md:AlphaMask、StencilMask、ScissorMask、ColorMask、反向遮罩、成本比較。
- references/layers.md:
RenderLayer、附加/分離、排序圖層、圖層與邏輯父節點分離。 - references/render-groups.md:
isRenderGroup、GPU 級變換、何時使用、渲染群組與cacheAsTexture的比較。 - references/scene-management.md:綜合視圖;渲染群組、
RenderLayer、剔除、zIndex 排序、boundsArea。
常見錯誤
[重要] 將子節點新增到葉顯示物件
錯誤:
const sprite = new Sprite(texture);
sprite.addChild(new Graphics().rect(0, 0, 10, 10).fill(0xff0000));
正確:
const group = new Container();
group.addChild(new Sprite(texture));
group.addChild(new Graphics().rect(0, 0, 10, 10).fill(0xff0000));
在 v8 中,葉節點(Sprite、Graphics、Text、Mesh、ParticleContainer、DOMContainer、GifSprite)技術上繼承自 Container,但不應容納子節點。將子節點新增到葉節點會產生未定義的渲染行為。當需要分組時,將葉節點包在 Container 中。
[重要] 引用 DisplayObject
錯誤:
import { DisplayObject } from "pixi.js"; // v8 中沒有此匯出
function moveNode(node: DisplayObject) {
node.x += 1;
}
正確:
import { Container } from "pixi.js";
function moveNode(node: Container) {
node.x += 1;
}
DisplayObject 在 v8 中被移除。每個顯示物件——包括 Sprite、Graphics、Text、Mesh——現在都是 Container 的子類別。使用 Container 作為基底型別。
[高] 在大型靜態子樹上忘記 isRenderGroup
錯誤:
const world = new Container();
for (let i = 0; i < 5000; i++) {
world.addChild(new Sprite(texture));
}
app.stage.addChild(world);
正確:
const world = new Container({ isRenderGroup: true });
for (let i = 0; i < 5000; i++) {
world.addChild(new Sprite(texture));
}
app.stage.addChild(world);
沒有 isRenderGroup: true,渲染器每幀都會重新計算每個子節點相對於父節點的變換。將子樹標記為渲染群組會快取變換和繪圖狀態,直到子節點發生變化,這對於大型或大部分靜態的樹至關重要。
[高] 將 child.x 視為世界空間
錯誤:
const enemy = new Container();
enemy.x = 500;
world.addChild(enemy);
world.x = 200;
console.log(enemy.x); // 500(本地),不是 700(世界)
正確:
const worldPos = enemy.toGlobal({ x: 0, y: 0 });
console.log(worldPos.x); // 700
Container.x/y/scale/rotation 是相對於父節點的本地值。使用 toGlobal(point) 計算世界空間座標,或使用 getGlobalPosition() 取得容器在世界空間的原點。世界變換不會以簡單的 x/y 對形式暴露。
[中] 沒有 zIndex 的 sortableChildren
錯誤:
const layer = new Container();
layer.sortableChildren = true;
layer.addChild(bg); // 沒有 zIndex
layer.addChild(mid); // 沒有 zIndex
layer.addChild(fg); // 沒有 zIndex
// 順序不變——所有 zIndex 預設為 0
正確:
const layer = new Container();
layer.sortableChildren = true;
bg.zIndex = 0;
mid.zIndex = 10;
fg.zIndex = 20;
layer.addChild(bg, mid, fg);
sortableChildren 在渲染前按 zIndex 重新排序子節點,但僅在子節點具有不同的 zIndex 值時才生效。僅設定父節點標誌沒有可見效果。
工具
PixiJS Devtools Chrome 擴充功能 讓您即時檢查和操作執行中的場景圖。對於任何非平凡的佈局或渲染順序除錯,請安裝它。





