pixijs-scene-dom-container

pixijs-scene-dom-container

热门

当需要在 PixiJS v8 画布上叠加 HTML 元素时使用此技能。涵盖 DOMContainer 的 element、anchor 以及场景图驱动的 CSS 变换、pixi.js/dom 副作用导入、DOMPipe 注册、可见性同步、指针事件处理。触发词:DOMContainer、pixi.js/dom、DOMPipe、HTML 叠加、画布上的输入框、iframe 叠加、DOMContainerOptions、element、anchor、构造函数选项。

293Star
16Fork
更新于 2026/6/4
SKILL.md
readonly只读
name
pixijs-scene-dom-container
description

当需要在 PixiJS v8 画布上叠加 HTML 元素时使用此技能。涵盖 DOMContainer 的 element、anchor 以及场景图驱动的 CSS 变换、pixi.js/dom 副作用导入、DOMPipe 注册、可见性同步、指针事件处理。触发词:DOMContainer、pixi.js/dom、DOMPipe、HTML 叠加、画布上的输入框、iframe 叠加、DOMContainerOptions、element、anchor、构造函数选项。

DOMContainer 将一个 HTML 元素定位在 PixiJS 画布上方,并使其 CSS 变换由场景图驱动。用于需要跟随显示对象位置的原生输入框、iframe、视频或富 HTML。默认的 pixi.js 浏览器包会自动注册 DOMPipe;自定义构建需要添加副作用导入 import 'pixi.js/dom'

DOMContainer 在 PixiJS v8 中标记为实验性。API 可能在次要版本之间发生变化。

假设熟悉 pixijs-scene-core-conceptsDOMContainer 继承自 ViewContainer,因此它是一个叶子节点:不要在它内部嵌套 PixiJS 子对象。将 DOM 内容嵌套在 HTML 元素本身内部,或者将多个 DOMContainer 实例包装在一个 Container 中。在 Web Worker 中不可用;worker 没有 DOM 可以叠加。

快速开始

import "pixi.js/dom";

const input = document.createElement("input");
input.type = "text";
input.placeholder = "输入名称...";

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 选项(positionscaletintlabelfilterszIndex 等)在此同样有效——参见 skills/pixijs-scene-core-concepts/references/constructor-options.md

DOMContainerOptions 添加的叶子节点特定选项:

选项 类型 默认值 描述
element HTMLElement document.createElement('div') 容器驱动的 HTML 元素。任何元素都有效:inputtextareaiframevideodiv 等。如果省略,会创建一个空的 <div>
anchor PointData | number 0 元素相对于自身尺寸的原点。0 为左上角,0.5 为中心,1 为右下角。单个数字同时设置两个轴;{ x, y } 分别设置每个轴。

tintfiltersmaskblendMode 被接受(继承自 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(包括继承的父级透明度)每帧写入元素的 style.opacity

如果未提供 element,默认会创建一个 <div>

直接样式化元素

const panel = document.createElement("div");
panel.innerHTML = "<h2>分数</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 中分离。恢复可见性会重新附加它。destroy() 从父节点移除元素并清空内部引用;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 缩放的画布无需额外工作即可保持对齐。

常见错误

[中等] 自定义构建中缺少 pixi.js/dom 导入

默认浏览器包自动注册 DOMPipe,因此大多数应用不需要显式导入。仅当你选择退出自动导入时才需要:

await app.init({ skipExtensionImports: true });
// 现在你必须自己添加:
import "pixi.js/dom";

在自定义构建下未注册时,DOMContainer 仍然可以导入,但渲染器没有管道来处理它;元素永远不会与场景图同步,也永远不会出现。

[中等] 期望滤镜、遮罩或混合模式影响 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

[中等] 不要在 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(...))。

[低] 忘记设置锚点以实现居中定位

默认锚点为 (0, 0),将元素的左上角放置在容器的位置。要将 UI 元素居中于其场景图位置,设置 anchor: 0.5

const dom = new DOMContainer({ element: myElement, anchor: 0.5 });
dom.position.set(400, 300);

API 参考