mcpField
P
pixijs-html-source

pixijs-html-source

github.com/pixijs開発3584.6k 回インストール4 週間前に更新
リポジトリ

pixijs-html-source について

DOM 要素や不変スナップショットを PixiJS v8 のテクスチャソースとして扱うスキルです。PixiJS 内でブラウザー要素を描画する開発者向けに、ライブ更新とスナップショットのライフサイクルを説明します。

主な機能

  1. 01DOM 要素をテクスチャソース化
  2. 02HTMLSource によるライブ更新
  3. 03不変の ElementImageSource スナップショット
  4. 04Sprite、Texture、Mesh で利用可能
  5. 05ブラウザー対応確認とリソース解放

活用シーン

  1. 01PixiJS シーン内に操作可能な DOM 要素を表示
  2. 02変化する要素を必要に応じてテクスチャへ再描画
  3. 03トランジションやトレイル用の静的スナップショットを保持

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/pixijs/pixijs-skills --skill pixijs-html-source

インストール後、Claude Code で/pixijs-html-sourceを入力して読み込まれたか確認します。

詳細

HTMLSource と ElementImageSource は、DOM 要素を TextureSource に変換します。変換後は、Sprite、Texture フレーム、Mesh へのマッピングなど、通常のテクスチャが使える場所ならどこでも使用できます。HTMLSource はライブ要素のピクセルを GPU に反映します(要素はブラウザー内で引き続き編集やクリックが可能です)。ElementImageSource は再描画されない不変のスナップショットをラップします。どちらも pixi.js/html-source にあり、このパスからインポートすると拡張機能が登録されます。

これらのソースは、実験段階の HTML-in-Canvas ブラウザープロポーザルに依存しており、PixiJS v8 では EXPERIMENTAL としてマークされています。ブラウザー API を有効にする必要があります。有効になっていない場合、初回レンダリング時にテクスチャアップローダーがエラーをスローします。この機能に依存する前に、canvas.requestPaint で機能を検出してください。この API はマイナーリリース間で変更される可能性があります。

pixijs-scene-sprite とテクスチャに関する知識を前提としています。これらはテクスチャ ソース であり、表示オブジェクトではありません。画面に表示するには、Sprite(または Texture/Mesh)でラップしてください。Web Workers では使用できません。ワーカーにはキャプチャ対象の DOM がないためです。

クイックスタート

import { Application, Sprite } from "pixi.js";
import { HTMLSource } from "pixi.js/html-source";

const app = new Application();
await app.init({ resizeTo: window });
document.body.appendChild(app.canvas);

// The element must be a direct child of the Pixi canvas.
const form = document.createElement("form");
form.innerHTML = '<input value="still editable" />';
app.canvas.appendChild(form);

// Render the live form as a sprite. It stays interactive in the browser.
const source = new HTMLSource({ resource: form });
const sprite = Sprite.from(source);

sprite.anchor.set(0.5);
sprite.position.set(app.screen.width / 2, app.screen.height / 2);
app.stage.addChild(sprite);

関連スキル: pixijs-scene-sprite(テクスチャを表示)、pixijs-scene-mesh(ジオメトリにマッピング、PerspectiveMesh)、pixijs-scene-dom-container(逆の用途:GPU パイプラインの外側で、キャンバスの 上に HTML を重ねて表示)、pixijs-assets(テクスチャソースとローダー/キャッシュ)、pixijs-environments(Web Workers では DOM を利用できません)。

コンストラクターのオプション

どちらのソースも TextureSource を拡張しているため、すべての TextureSourceOptions(resolution、scaleMode、addressMode、label など)が有効です。それぞれで resource が必須です。

HTMLSourceOptions(ライブ要素):

オプション型デフォルト説明
resourceElement—必須です。描画するライブ DOM 要素です。所有するキャンバスの直接の子である必要があります。そうでない場合、コンストラクターは例外をスローします。
canvasHTMLSourceCanvas—要素のレイアウトサブツリーを所有するキャンバスです。要素がキャンバスの直接の子である場合は resource.parentElement から推測されます。推測できない場合は指定してください。
autoLayoutbooleantrue所有するキャンバスに layoutsubtree 属性を設定します。この属性がある場合に限り、ブラウザーはキャンバスの子要素をレイアウトして描画します。自分で <canvas layoutsubtree> を記述する場合は false に設定してください。
autoUpdatebooleantrueキャンバスの paint イベントを監視し、要素の再描画時に再アップロードします。一度だけキャプチャする静的なテクスチャの場合は false に設定してください。
autoRequestPaintbooleantrue構築後に初回の描画を一度リクエストします。継続的なアニメーションの場合は false に設定し、フレームごとに自分で source.requestPaint() を呼び出してください。

ElementImageSourceOptions(不変のスナップショット):

オプション型デフォルト説明
resourceElementImage—必須です。canvas.captureElementImage(element) によるスナップショットです。
autoClosebooleanfalseソースの破棄時に snapshot.close() を呼び出します。スナップショットをほかのソースと共有する場合は false のままにしてください。そうしないと、解放後のリソースを使用することになります。

静的な HTMLSource.defaultOptions オブジェクトを使って、すべての HTMLSource のデフォルトを変更できます。たとえば、HTMLSource.defaultOptions.autoUpdate = false のように設定します。

基本パターン

セットアップと副作用のあるインポート
import "pixi.js/html-source";
import { HTMLSource, ElementImageSource } from "pixi.js/html-source";

pixi.js/html-source は extensions.add(...) を呼び出して、HTMLSource、ElementImageSource およびそれらの WebGL/WebGPU アップローダーを登録します。これがないと、レンダラーには 'html' アップローダーがなく、これらのソースは描画されません。クラスは pixi.js ではなく pixi.js/html-source からエクスポートされます。

pixi.js/html-source から名前付きエクスポートをインポートすると、副作用も実行されます。そのため、このパスからほかにインポートするものがない場合に限り、単独の import 'pixi.js/html-source' が必要です。

機能検出とブラウザーのサポート

HTML-in-Canvas API はブラウザーフラグで制御されています。この API に依存する前に、機能を検出してください。

import type { HTMLSourceCanvas } from "pixi.js/html-source";

const canvas = app.canvas as HTMLSourceCanvas;

if (canvas.requestPaint) {
  // HTML-in-Canvas is available.
}

型付きの requestPaint および captureElementImage メンバーを使うには、app.canvas を HTMLSourceCanvas にキャストしてください。ブラウザーが API に対応していない場合、source.requestPaint() は false を返します。API が無効な場合、テクスチャアップローダーは初回の描画時に例外をスローします。

API がない場合、初回のアップロード時に、WebGL では [HTMLSource] WebGLRenderingContext.texElementImage2D is not available...、WebGPU では [HTMLSource] GPUQueue.copyElementImageToTexture is not available... がスローされます。

HTMLSource を使用したライブ要素
const form = document.createElement("form");
app.canvas.appendChild(form); // direct child of the canvas

const source = new HTMLSource({ resource: form });
const sprite = Sprite.from(source);

要素はレンダラーの <canvas> の直接の子である必要があります。ソースは resource.parentElement から所有するキャンバスを推定します(または canvas を渡します)。デフォルトでは、キャンバスに layoutsubtree を設定し、キャンバスの paint イベントを監視して、初回の描画を一度リクエストします。最初の描画が行われるまで、source.isReady は false です。その後は true になります。autoUpdate が false の場合は、直ちに true になります。resourceWidth/resourceHeight は、要素の実ピクセルサイズ(offsetWidth/offsetHeight)を返します。

requestPaint を使用した連続アニメーション
const source = new HTMLSource({ resource: clock, autoRequestPaint: false });
const sprite = Sprite.from(source);

app.ticker.add(() => {
  clock.textContent = new Date().toLocaleTimeString();
  source.requestPaint(); // re-snapshot the DOM this frame
});

ブラウザーは、要求があった場合にのみキャンバスの子要素を再描画します。フレームごとに内容が変わる要素では、autoRequestPaint: false を設定し、独自のティッカー内で source.requestPaint() を呼び出して、任意のタイミングで再描画を実行します。

ElementImageSource を使用した不変スナップショット
import { ElementImageSource } from "pixi.js/html-source";
import type { HTMLSourceCanvas } from "pixi.js/html-source";

const canvas = app.canvas as HTMLSourceCanvas;
const snapshot = canvas.captureElementImage!(element);

const source = new ElementImageSource({ resource: snapshot, autoClose: true });
const sprite = Sprite.from(source);

captureElementImage() は、要素の現在のピクセルを不変の ElementImage に固定します。所有するキャンバスも paint リスナーも再描画のライフサイクルもないため、ソースは構築した時点ですぐに使用可能です。要素の破棄後も保持する必要がある場合や、スナップショットを他の場所に渡す場合(トランジション、「粉砕」効果、トレイル効果など)に使用します。使用後は snapshot.close() でスナップショットを解放するか、autoClose: true を渡して、destroy() 時にソースが閉じるようにします。

スプライト、テクスチャ、メッシュでソースを使用する

どちらのソースも通常の TextureSource です。Sprite.from(source)/Texture.from(source) でラップして、フレーム分割またはスライスしてサブテクスチャを作成するか、メッシュにマッピングします。

import { Rectangle, Texture } from "pixi.js";

// A 64x64 slice of the rendered element.
const chunk = new Texture({
  source,
  frame: new Rectangle(0, 0, 64, 64),
});

// Mapped onto geometry (e.g. a perspective warp).
const mesh = new PerspectiveMesh({ texture: Texture.from(source) /* ... */ });
自動検出と優先順位
// Resolves to an HTMLSource (element) or ElementImageSource (snapshot) only as a last resort.
const sprite = Sprite.from(elementAlreadyInTheCanvas);

Texture.from/Sprite.from に渡された汎用 HTML 要素または ElementImage は、テクスチャソースの優先順位が最も低い(-10)これらのソースに解決されるため、他の組み込みソースが処理できないリソースだけを受け取ります。画像、動画、キャンバスの各要素は意図的に対象外です。これらには、専用のより高速なソースがあります。オプション(autoUpdate、autoClose)が必要な場合や、SVG などの HTML 以外の要素を使用する場合は、ソースを明示的に構築してください。

よくある間違い

[HIGH] pixi.js からインポートして pixi.js/html-source からインポートしない

誤り:

import { HTMLSource } from "pixi.js"; // not exported from the core entry

正しい例:

import { HTMLSource } from "pixi.js/html-source";

HTMLSource、ElementImageSource、および 'html' アップローダーは pixi.js/html-source にのみ存在します。このパスから何かをインポートすると拡張機能が登録されます。このモジュールには副作用があると指定されているため、クラスだけをインポートした場合も、バンドラーは登録処理を保持します。

[HIGH] ブラウザー API が有効だと思い込む

HTML-in-Canvas 提案は、デフォルトでは提供されていません。API が無効の場合、アップローダーは初回のレンダリング時にエラーをスローします。まず機能を検出してください。

const canvas = app.canvas as HTMLSourceCanvas;
if (!canvas.requestPaint) {
  // Fall back to a static image, DOMContainer overlay, or a message.
}
[MEDIUM] 要素がキャンバスの直接の子ではない
document.body.appendChild(form); // wrong parent
const source = new HTMLSource({ resource: form }); // throws

HTMLSource は、要素が所有するキャンバスの直接の子(app.canvas.appendChild(form))であることを必要とし、そうでない場合はエラーをスローします。ソースを構築する前に要素をキャンバスに追加するか、canvas オプションを渡してください。

[MEDIUM] requestPaint を呼び出さずにライブ要素が更新されると思い込む

アニメーションしない要素は、ブラウザーの paint イベント時に自動更新されます(autoUpdate: true)。フレームごとに変わる内容は、描画を発生させる何かがない限り再アップロードされません。source.requestPaint() を毎フレーム呼び出して更新してください(autoRequestPaint: false を設定します)。

[MEDIUM] 使用中の ElementImage を閉じる
const source = new ElementImageSource({ resource: snapshot, autoClose: true });
const other = new ElementImageSource({ resource: snapshot }); // shares the snapshot

source.destroy(); // closes the snapshot — `other` is now a use-after-free

ソースがスナップショットを排他的に所有する場合にのみ、autoClose: true を設定してください。スナップショットを共有する場合は autoClose を無効のままにし、最後のソースが破棄された後に一度だけ snapshot.close() を呼び出してください。

クリーンアップ

source.destroy();

HTMLSource.destroy() は、キャンバスの paint リスナーを切り離し、キャンバスへの参照を null にします。ElementImageSource.destroy() は、autoClose が設定されている場合にスナップショットを閉じます。設定されていない場合は、メモリを解放するために自分で snapshot.close() を呼び出してください。

API Reference

コメント