pixijs-scene-dom-container について
キャンバス上に HTML 要素を重ねたい開発者向けの、PixiJS DOMContainer のスキルガイドです。シーンの変換との同期、要素のライフサイクル、DOM 描画の制約を説明します。
主な機能
- 01HTML 要素のキャンバスへの重ね合わせ
- 02シーン変換と不透明度の同期
- 03アンカー、表示、破棄の管理
- 04DOM 描画の制約の把握
活用シーン
- 01入力欄をシーンオブジェクトに追従させる
- 02キャンバス上に動画や iframe を重ねる
- 03リッチな HTML の UI 要素を配置する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pixijs/ pixijs-skills --skill pixijs-scene-dom-containerインストール後、Claude Code で/pixijs-scene-dom-containerを入力して読み込まれたか確認します。
詳細
DOMContainer は PixiJS キャンバス上に HTML 要素を配置し、シーングラフに基づいて CSS トランスフォームを適用します。ネイティブ入力要素、iframe、動画、またはディスプレイオブジェクトの位置に追従させる必要があるリッチ HTML に使用します。デフォルトの pixi.js ブラウザーバンドルでは DOMPipe が自動的に登録されます。カスタムビルドでは、副作用インポート import 'pixi.js/dom' を追加してください。
DOMContainerは PixiJS v8 で EXPERIMENTAL としてマークされています。マイナーリリース間で API が変更される可能性があります。
pixijs-scene-core-concepts を理解していることを前提としています。DOMContainer は ViewContainer を継承するため、リーフです。内部に PixiJS の子をネストしないでください。DOM コンテンツは HTML 要素自体の中にネストするか、複数の DOMContainer インスタンスを Container でラップしてください。Web Workers では使用できません。ワーカーにはオーバーレイする 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 は右下です。数値を 1 つ指定すると両軸に適用され、{ x, y } を指定すると各軸を個別に設定できます。 |
Container から継承された tint、filters、mask、blendMode も指定できますが、視覚的な効果はありません。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 をそのまま使用できます。明示的な import 'pixi.js/dom' の行が必要なのは、skipExtensionImports: true を設定した場合(カスタムビルド)またはブラウザー以外のバンドルで実行する場合だけです。
トランスフォーム、アンカー、アルファ
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 は右下です。数値を 1 つ指定すると両軸に適用され、オブジェクト { x, y } を指定すると各軸を個別に設定できます。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 から切り離されます。表示を復元すると、再びアタッチされます。destroy() は要素を親ノードから削除し、内部参照を null にします。HTML 要素自体は保持されるため、別の場所に再アタッチできます。
const element = dom.element;
dom.destroy();
document.body.appendChild(element);
DOM コンテナのルート
DOMPipe は、アタッチされたすべての要素を格納する、z-index: 1000 の共有ルート <div> を使用します。これは 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 の子要素を配置する場合は、通常の Container の中で DOMContainer と一緒にラップしてください。HTML をネストする場合は、要素自体の中にネストしてください(element.appendChild(...))。
[LOW] 中央配置でアンカーの設定を忘れる
デフォルトのアンカーは (0, 0) で、要素の左上隅がコンテナの位置に配置されます。UI 要素をシーングラフ上の位置に中央配置するには、anchor: 0.5 を設定してください。
const dom = new DOMContainer({ element: myElement, anchor: 0.5 });
dom.position.set(400, 300);