mcpField
P
pixijs-scene-dom-container

pixijs-scene-dom-container

github.com/pixijs开发3585.8k 次安装4 周前更新
代码仓库

关于 pixijs-scene-dom-container

pixijs-scene-dom-container 是介绍 PixiJS DOMContainer 的技能指南,面向需要将 HTML 元素叠加在画布上的开发者。它说明如何让元素跟随场景图变换,并涵盖 DOM 生命周期和限制。

主要功能

  1. 01将 HTML 元素叠加到画布上
  2. 02同步场景图变换与透明度
  3. 03控制锚点、可见性和清理
  4. 04说明 DOM 元素的渲染限制

适用场景

  1. 01让输入框跟随场景对象定位
  2. 02在画布上叠加视频或 iframe
  3. 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 添加的叶节点专属选项:

选项类型默认值说明
elementHTMLElementdocument.createElement('div')容器驱动的 HTML 元素。任何元素均有效:input、textarea、iframe、video、div 等。若省略,则会创建一个空的 <div>。
anchorPointData | number0元素相对于自身尺寸的原点。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);

API 参考

评论

支持 Markdown