static_html_Display.js`static_html_Display.js`は、HTMLテンプレートを基にCanvasへ描画し、Three.jsのテクスチャとして利用できるモジュールです。 動的・静的コンテンツ両方に対応しており、HTML要素を3D空間内でインタラクティブに操作できます。
static get template() メソッドで、HTMLの基本構造(ヘッダー、セクション、フッターなど)を定義します。
this.imageConfigs, this.videoConfigs, this.canvasConfigs を使用して、
画像、動画、Canvas要素のレイアウト(サイズ・配置)を設定します。
テンプレート内のプレースホルダー要素のサイズは、ここで指定した値に合わせられます。
`static_html_Display.js` の基本的な使い方と、各設定項目の詳細、具体的なサンプルコードを説明します。
static get template()):このメソッド内に記述されたHTMLが、Canvasに描画されるコンテンツの基本レイアウトとなります。 ヘッダー、セクション、フッターなど、自由に要素を配置・カスタマイズできます。 テンプレート内には、後述する画像、動画、Canvasなどのプレースホルダー要素を配置できます。
static get template() {
return `
<div id="container">
<header>
<h1>My Website</h1>
</header>
<section>
<!-- ここにプレースホルダーを配置 -->
<div id="imagePlaceholder1" style="width:640px; height:360px;"></div>
<div id="videoPlaceholder1" style="width:640px; height:360px;"></div>
<div id="canvasPlaceholder1" style="width:800px; height:600px;"></div>
<button id="myButton">Click Me</button>
</section>
<footer>
<p>Copyright 2023</p>
</footer>
</div>
`;
}
テンプレート内に配置したプレースホルダー要素 (例: <div id="imagePlaceholder1"></div>) に対応する、
画像、動画、Canvas要素の設定を、imageConfigs, videoConfigs, canvasConfigs 配列に記述します。
プレースホルダー要素の style 属性で指定したサイズ (width, height) は、
default オブジェクト内の同名のプロパティで指定します。
imageConfigs):
this.imageConfigs = [
{
selector: '#imagePlaceholder1', // テンプレート内の対象要素 (IDで指定)
default: { width: 640, height: 360 } // プレースホルダーのサイズ
}
];
videoConfigs):
this.videoConfigs = [
{
selector: '#videoPlaceholder1', // テンプレート内の対象要素 (IDで指定)
url: 'path/to/video.mp4', // 動画ファイルのURL
default: { width: 640, height: 360 }, // プレースホルダーのサイズ
autoplay: true, //自動再生
loop: true, //ループ再生
muted: true, //ミュート
}
];
canvasConfigs):
this.canvasConfigs = [
{
selector: '#canvasPlaceholder1', // テンプレート内の対象要素 (IDで指定)
default: { width: 800, height: 600 } // プレースホルダーのサイズ
// ここに、Canvasへの描画処理を記述 (後述)
}
];
キャンバスの場合は、setupCanvas メソッドをオーバーライドして、Canvasへの描画処理を記述します。
setupCanvas(canvas, config) {
if (config.selector === '#canvasPlaceholder1') {
const ctx = canvas.getContext('2d');
// ここに、Canvasへの描画処理を記述
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
}
ユーザー操作対象の要素(例:ボタン)は、this.interactiveConfig に登録し、
レイアウト情報(位置、サイズ)を設定します。
登録された要素は、initializeUI() メソッド内で初期化され、
クリックやホバーなどのイベントが自動的に監視・通知されます。
this.interactiveConfig = [
{
selector: '#myButton', // 対象となるDOM要素 (テンプレート内のID)
default: { x: 50, y: 50, width: 100, height: 50 } // 位置とサイズ
}
];
initializeUI()内では、各要素に対応する初期化関数(例:_setup_myButton())が呼び出されます。
この関数内で、addEventListener を使ってイベントリスナーを登録するなど、
必要に応じた初期化処理を行います。
initializeUI() {
super.initializeUI(); // 必ず最初に super.initializeUI() を呼ぶ
this.interactiveConfig.forEach(config => {
if (config.selector === '#myButton') {
this._setup_myButton(config);
}
});
}
_setup_myButton(config) {
const element = this.liveComponentContainer.querySelector(config.selector);
element.addEventListener('click', () => {
// ボタンクリック時の処理
console.log('Button clicked!');
});
}
このコンポーネントは常に document.getElementById('liveComponentContainer') 内に生成されます。
描画更新やイベント処理は、このコンテナで一元管理され、最新の状態が維持されます。
liveComponentContainer は、StaticHTMLDisplay クラスのインスタンスが持つプロパティで、
動的に生成・更新されるHTML要素が格納されるコンテナ要素です。
このシステムは、WebGLとHTML/CSSを同一空間内で融合させた先進的なアーキテクチャを採用しています。DOM構造を不可視領域でレンダリングし、その結果を画像処理してWebGLの3D空間にテクスチャとしてマッピングします。 イベント処理は、イベント転送メカニズムを介してテクスチャ画像と非表示DOM要素間で連携します。動画、画像、Canvas要素はそれぞれ非表示領域で処理され、随時キャプチャされた画像が3D空間の指定領域にマッピングされます。
通常、このような異なる技術の統合はCORS(Cross-Origin Resource Sharing)などの問題を引き起こす可能性がありますが、本システムではSVGを活用することで、3D空間とDOM要素の合成を効率的に実現しています。
StaticHTMLDisplay.js参照)
// StaticHTMLDisplay.jsより抜粋 (初期化部分)
constructor(width, height, renderer, options = {}) {
// ...
// liveComponentContainerは、DOM要素を保持するためのコンテナ
this.liveComponentContainer = document.createElement('div');
this.liveComponentContainer.style.width = `${width}px`;
this.liveComponentContainer.style.height = `${height}px`;
this.liveComponentContainer.style.position = 'absolute';
this.liveComponentContainer.style.top = '0px';
this.liveComponentContainer.style.left = '0px';
// 視覚的には非表示にするが、DOMとしては存在させる
this.liveComponentContainer.style.visibility = 'hidden';
// ...
}
StaticHTMLDisplay.js参照)
// StaticHTMLDisplay.jsより抜粋 (更新処理)
update() {
// ...
if (this.needsUpdate) {
this.updateTexture(); // テクスチャを更新
}
// ...
}
updateTexture() {
// DOM要素をSVG文字列に変換
const svgString = this.createSVGString();
const img = new Image();
// SVG文字列をBlobオブジェクトに変換
const svgBlob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' });
// BlobオブジェクトからData URLを生成
const url = URL.createObjectURL(svgBlob);
img.onload = () => {
this.texture.image = img;
this.texture.needsUpdate = true; // Three.jsにテクスチャ更新を通知
URL.revokeObjectURL(url); // Data URLを解放
this.needsUpdate = false;
};
img.src = url; // Data URLを画像ソースに設定
}
// StaticHTMLDisplay.jsより抜粋(イベント処理)
handleEvent(event) {
// ...
// イベントを複製し、対象のDOM要素にディスパッチ
const clonedEvent = this.cloneAndDispatchEvent(event, targetElement);
// ...
}
// StaticHTMLDisplay.jsより抜粋 (SVG文字列生成)
createSVGString() {
// liveComponentContainer内のDOM要素をシリアライズ化
const serialized = new XMLSerializer().serializeToString(this.liveComponentContainer);
// SVG要素を生成し、シリアライズ化されたDOMをforeignObject内に配置
const svgString = `<svg xmlns='http://www.w3.org/2000/svg' width='${this.width}' height='${this.height}'>
<foreignObject x='0' y='0' width='${this.width}' height='${this.height}'>${serialized}</foreignObject>
</svg>`;
return svgString;
}