关于 pixijs-scene-dom-container
pixijs-scene-dom-container 是介绍 PixiJS DOMContainer 的技能指南,面向需要将 HTML 元素叠加在画布上的开发者。它说明如何让元素跟随场景图变换,并涵盖 DOM 生命周期和限制。
主要功能
- 01将 HTML 元素叠加到画布上
- 02同步场景图变换与透明度
- 03控制锚点、可见性和清理
- 04说明 DOM 元素的渲染限制
适用场景
- 01让输入框跟随场景对象定位
- 02在画布上叠加视频或 iframe
- 03放置需要丰富 HTML 的界面
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pixijs/ pixijs-skills --skill pixijs-scene-dom-container安装后在 Claude Code 中输入/pixijs-scene-dom-container确认已加载。
详细介绍
DOMContainer 会将 HTML 元素定位在 PixiJS 画布上方,并根据场景图驱动其 CSS 变换。可用于需要跟随显示对象位置的原生输入框、iframe、视频或富 HTML 内容。默认的 pixi.js 浏览器包会自动注册 DOMPipe;自定义构建需添加副作用导入 import 'pixi.js/dom'。
在 PixiJS v8 中,
DOMContainer被标记为 EXPERIMENTAL。此 API 可能会在次要版本之间发生变化。
假设你已熟悉 pixijs-scene-core-concepts。DOMContainer 扩展自 ViewContainer,因此它是叶节点:不要在其中嵌套 PixiJS 子对象。请将 DOM 内容嵌套在 HTML 元素本身中,或使用 Container 包装多个 DOMContainer 实例。Web Workers 中不可用;Worker 没有可供覆盖的 DOM。
快速开始
import "pixi.js/dom";
const input = document.createElement("input");
input.type = "text";
input.placeholder = "Enter name...";
const dom = new DOMContainer({
element: input,
anchor: 0.5,
});
dom.position.set(app.screen.width / 2, app.screen.height / 2);
app.stage.addChild(dom);
相关技能: pixijs-scene-core-concepts(场景图基础)、pixijs-scene-container(包装多个 DOM 覆盖层)、pixijs-events(画布与 DOM 上的指针处理)、pixijs-accessibility(屏幕阅读器覆盖层)。
构造函数选项
所有 Container 选项(position、scale、tint、label、filters、zIndex 等)在此处同样有效——请参阅 skills/pixijs-scene-core-concepts/references/constructor-options.md。
DOMContainerOptions 添加的叶节点专属选项:
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
element | HTMLElement | document.createElement('div') | 容器驱动的 HTML 元素。任何元素均有效:input、textarea、iframe、video、div 等。若省略,则会创建一个空的 <div>。 |
anchor | PointData | number | 0 | 元素相对于自身尺寸的原点。0 为左上角,0.5 为中心,1 为右下角。单个数值会同时设置两个轴;{ x, y } 则分别设置两个轴。 |
tint、filters、mask 和 blendMode 均可接受(继承自 Container),但不会产生视觉效果——DOM 元素位于 WebGL/WebGPU 管线之外。请通过 CSS 为这些效果设置样式。
核心模式
设置与副作用导入
import "pixi.js/dom";
import { DOMContainer } from "pixi.js";
也可以使用会注册管线并重新导出该类的组合导入:
import { DOMContainer } from "pixi.js/dom";
默认的 pixi.js 浏览器包已通过 browserAll.ts 为你导入 pixi.js/dom,因此在典型的浏览器应用中,DOMContainer 开箱即用。只有在设置 skipExtensionImports: true(自定义构建)或在非浏览器包下运行时,才需要显式添加 import 'pixi.js/dom' 这一行。
变换、锚点与透明度
const dom = new DOMContainer({
element: document.createElement("div"),
anchor: 0.5,
});
dom.position.set(400, 300);
dom.scale.set(1.5);
dom.rotation = Math.PI / 8;
dom.alpha = 0.5;
应用于 DOMContainer 的变换会以 CSS transform 的形式传递给元素。anchor 会相对于元素自身尺寸移动其原点:0 为左上角,0.5 为中心,1 为右下角。单个数值会同时设置两个轴;对象 { x, y } 则分别设置两个轴。每一帧都会将 alpha(包括继承自父级的 alpha)写入元素的 style.opacity。
如果未提供 element,默认会创建一个 <div>。
直接设置元素样式
const panel = document.createElement("div");
panel.innerHTML = "<h2>Score</h2><p>1500</p>";
panel.style.color = "white";
panel.style.fontFamily = "Arial";
panel.style.pointerEvents = "none";
const dom = new DOMContainer({ element: panel });
dom.position.set(50, 50);
app.stage.addChild(dom);
PixiJS 不会干预元素的 CSS 样式。共享根 <div> 会设置为 pointer-events: none,每个附加的元素默认设置为 pointer-events: auto。对于纯装饰性覆盖层,请将其覆盖设置为 none,这样画布仍可接收其下方的点击。
可见性和清理
dom.visible = false;
dom.visible = true;
dom.destroy();
将 visible = false 或将 DOMContainer 从场景图中移除,都会使元素脱离 DOM。恢复可见性后,元素会重新附加到 DOM。destroy() 会从父节点中移除元素并将内部引用设为 null;HTML 元素本身会保留,因此你可以在其他位置重新附加它:
const element = dom.element;
dom.destroy();
document.body.appendChild(element);
DOM 容器根节点
DOMPipe 使用一个共享的根 <div>,其 z-index: 1000,用于承载所有已附加的元素。它通过 app.domContainerRoot(一个 HTMLDivElement)公开。所有 DOMContainer 元素都会渲染在画布内容上方;你无法在 PixiJS 绘制调用之间插入 DOM 元素。
在首次渲染包含已附加 DOMContainer 的内容时,管道会自动将根节点附加到画布的父节点。如果需要在 DOM 树中明确且稳定地放置它(例如,画布与其他分层内容共用一个包装元素),请自行将它附加到 app.canvas 旁边:
document.body.appendChild(app.canvas);
document.body.appendChild(app.domContainerRoot);
根节点使用绝对定位,并通过 ResizeObserver 根据画布的 getBoundingClientRect() 重新计算变换,因此经过 CSS 缩放的画布也能保持对齐,无需额外操作。
常见错误
[MEDIUM] 自定义构建中遗漏 pixi.js/dom 导入
默认的浏览器包会自动注册 DOMPipe,因此大多数应用无需显式导入。只有在选择禁用自动导入时才需要:
await app.init({ skipExtensionImports: true });
// Now you must add this yourself:
import "pixi.js/dom";
在自定义构建中,如果没有注册,虽然仍可导入 DOMContainer,但渲染器没有可处理它的管道;元素永远不会与场景图同步,也不会显示。
[MEDIUM] 误以为滤镜、遮罩或混合模式会影响 DOM 元素
错误:
const dom = new DOMContainer();
dom.filters = [new BlurFilter()];
正确:
dom.element.style.filter = "blur(4px)";
DOM 元素是通过 CSS 变换定位的 HTML 覆盖层;它们不属于 WebGL/WebGPU 管线。PixiJS 滤镜、遮罩和混合模式对它们不起作用。请直接在元素上使用 CSS 滤镜和 CSS mix-blend-mode。
[MEDIUM] 不要在 DOMContainer 内嵌套子项
错误:
const dom = new DOMContainer();
dom.addChild(new Sprite(texture));
正确:
const group = new Container();
group.addChild(dom, new Sprite(texture));
DOMContainer 扩展自 ViewContainer,后者会设置 allowChildren = false。它是 PixiJS 场景图中的叶节点。对于 PixiJS 子项,请将 DOMContainer 与它们一起放在普通的 Container 中。对于嵌套 HTML,请在元素本身内嵌套(element.appendChild(...))。
[LOW] 忘记为居中定位设置锚点
默认锚点为 (0, 0),会将元素的左上角放在容器的位置上。若要让 UI 元素在其场景图位置居中,请设置 anchor: 0.5:
const dom = new DOMContainer({ element: myElement, anchor: 0.5 });
dom.position.set(400, 300);