Chrome 157 の HTML-in-Canvas: 2D、WebGL、WebGPU 内のインタラクティブ DOM

公開日: 2026 年 10 月 26 日

オリジン トライアルの成功を受けて、Chrome 157 では HTML-in-Canvas API の正式な安定版リリースが提供されます。HTML-in-Canvas API は、DOM のインタラクティブでアクセスしやすい世界と、<canvas> の高性能なピクセルレベルの制御とのギャップを埋めます。この API を使用すると、豊富なブラウザ機能と GPU アクセラレーションによるキャンバス グラフィックの両方のメリットを得ることができます。

HTML-in-Canvas API の概要を説明する動画。

キャンバスと DOM のジレンマ

以前は、視覚的に要求の厳しいウェブアプリを作成する場合、標準の HTML 要素と未加工のキャンバス コンテキストのどちらかを選択する必要がありました。

テクノロジー 強み 制限事項
<canvas> GPU アクセスによる低レベルのピクセル制御で、2D および 3D グラフィック パイプライン、カスタム シェーダー、オフスクリーン ワーカーを駆動します。データ量の多い UI の高パフォーマンスなレンダリング。 テキストの選択、コピー&ペースト、右クリック操作、テキストの折り返しなど、ウェブ プラットフォームの組み込み機能はありません。不透明なピクセル グリッドは、デフォルトではスクリーン リーダー、ページ内検索、自動翻訳、自動入力をサポートしていないため、フォールバックの実装が必要です。
HTML 組み込みのフォーム コントロール、レスポンシブ タイポグラフィ、CSS スタイル設定を備えた、すぐに使える Semantic UI。スクリーン リーダー、ページ内検索、DevTools のためのブラウザとの緊密な統合。 複雑な UI のパフォーマンスを制御する機能が制限されている。視覚効果は、直接的なピクセル操作やシェーダーを使用しない標準の CSS と SVG に制限されます。

HTML-in-Canvas 以前

この API が登場する前は、キャンバスを多用する UI を構築する場合、次の 2 つのアプローチから選択する必要があり、それぞれにデメリットがありました。

  1. テキストをキャンバス ピクセルとして直接レンダリングする(fillText()): アプリは、テキストと UI コントロールを未加工のピクセルとして命令的に描画していました。この方法には、次のようなデメリットがありました。
    • ユーザー補助機能の不具合: スクリーン リーダーやユーザー補助ツールは、非表示のフォールバック DOM を手動で構築して同期しない限り、キャンバス ピクセルを読み取ることができません。
    • ブラウザ機能の喪失: ユーザーは、ページ内検索(Ctrl/Cmd+F)での検索、テキストの自然なコピー&ペースト、コンテキスト メニューのトリガー、ブラウザの翻訳やスペルチェックの使用ができなくなります。
    • 複雑なタイポグラフィ エンジン: 国際化をサポートするには、大規模な JavaScript レイアウト エンジンをバンドルする必要があります。
  2. キャンバス上にフローティング HTML オーバーレイを配置する: たとえば、JavaScript で境界ボックスと行列変換を計算して、キャンバス上に標準の HTML 要素を配置するライブラリを使用します。このアプローチのデメリットは次のとおりです。
    • 同期ラグと視覚的なティアリング: 3D でのスクロール、ズーム、カメラの動きにより、フレーム時間差が原因で、オーバーレイ DOM 要素がキャンバス ピクセルに対してドリフトしたり、ジッターが発生したりすることがあります。
    • クリッピングと Z オーダーの制限: HTML オーバーレイは常にキャンバス バッファ全体の上に配置されます。3D シーンの内部に HTML を埋め込む(3D オブジェクトの背後、ガラス素材の内部、鏡に映った状態など)には、iframe から画像への複雑な回避策が必要でした。
    • パフォーマンスのオーバーヘッド: オーバーレイをキャンバスに揃えるには、JavaScript で各オーバーレイの変換を再計算し、フレームごとに style.transform に書き込む必要があります。ブラウザは各文字列を解析し、要素のスタイルを再計算してからフレームをレンダリングするため、オーバーレイを追加するたびにメインスレッドの処理が増加します。2D コンテキストでは、drawElementImage() が要素の位置を更新します。WebGL と WebGPU では、計算した変換を行列として updateElementGeometry() に渡します。どちらの場合も、ブラウザは CSS を解析せず、スタイルを再計算しません。

HTML-in-Canvas の主なメリット

HTML-in-Canvas は、こうしたトレードオフを解消します。HTML を <canvas> 要素内に配置することで、コンテンツはインタラクティブなままになり、すべてのブラウザ統合が自動的に機能します。

<canvas> 内でレンダリングされる HTML コンテンツは、<canvas> 外の HTML と同じ機能を持ちます。

  • テキストのレイアウトと書式設定: CSS スタイルが適用された複数行テキストや双方向テキストなど、テキストのレイアウトと書式設定をサポートします。
  • フォーム コントロール: 豊富な CSS とシェーダーのカスタマイズ オプションを備えた、表現力豊かなフォーム コントロール。
  • テキストの選択、コピー、貼り付け、右クリック: ユーザーは 3D シーン内のテキストをハイライト表示したり、コンテキスト メニューをトリガーしたりできます。
  • ユーザー補助: キャンバス内にレンダリングされた HTML コンテンツは、スクリーン リーダーのユーザー補助ツリーに公開されます。
  • ブラウザ機能の統合: 翻訳、自動入力、ページ内検索などのブラウザ機能がすぐに利用できます。ユーザーは、WebGL および WebGPU テクスチャ内のテキストを翻訳または検索できます。
  • 拡張機能の統合: ブラウザ拡張機能がコンテンツに作用します。たとえば、テキスト置換拡張機能は、3D メッシュにレンダリングされたテキストを自動的に更新します。
  • DevTools の統合: Chrome DevTools でキャンバス UI 要素の CSS スタイルを直接検査して調整できます。
  • インデックス登録可能性と AI エージェント: ウェブ クローラーと AI エージェントは、2D および 3D シーンにレンダリングされた DOM コンテンツをインデックスに登録できます。
  • メディアの編集とエクスポート: ライブ DOM 要素を含むフル キャンバス コンポジットを、画像(toDataURL()、toBlob())または動画ストリーム(captureStream())に直接エクスポートします。
キャンバスに直接レンダリングされたテキストと HTML-in-Canvas の機能統合を比較するデモ。HTML-in-Canvas ペインでは、コンテンツを選択して翻訳できます。また、自動入力などのブラウザ機能もすぐに利用できます。標準のキャンバス ペインでは、コンテンツは fillText メソッドを使用してキャンバスに直接レンダリングされ、インタラクティブではありません。

主なユースケース:

HTML-in-Canvas は、複数の領域で機能を提供します。

  • 大規模なキャンバスベースのアプリ: 重量級のウェブアプリは、UI コンポーネントをキャンバス ワークスペースに直接レンダリングできるため、ユーザー補助が向上し、バンドルサイズが削減されます。
  • 3D シーンとゲーム: 没入型の WebXR エクスペリエンスやゲームでは、ゲーム内の端末や読み取り可能な 3D ブックなどのインタラクティブな DOM 要素をシーン内に直接配置できます。
  • メディアの編集とエクスポート: 豊富な HTML タイポグラフィとシェーダー エフェクトを組み合わせたクリエイティブ ツールを使用すると、合成シーンを画像や動画ストリームに直接エクスポートできます。
  • 表現力豊かな UI: HTML コンテンツを未加工のピクセルとして操作し、シェーダー駆動の視覚効果を構築できます。

HTML-in-Canvas クイックスタート

キャンバスで HTML をレンダリングするには、次の手順が必要です。

  1. キャンバスを準備する。適切な属性を宣言的に設定して、HTML をキャンバスにレンダリングする必要があることをブラウザに知らせます。この設定は、2D、WebGL、WebGPU のコンテキストで共通です。キャンバスを設定する方法と、HTML 要素を個別に描画するように宣言する方法を学習します。

    <!-- Prepare your canvas by setting the `content` attribute -->
    <canvas id="canvas" width="600" height="400" content="drawable">
      <!-- Mark child as `drawable` to render to canvas -->
      <div id="myElement" drawable>
        <!-- Your HTML here -->
      </div>
    </canvas>
    
  2. 要素の画像をキャンバスに描画します。具体的な実装は、HTML を 2D、WebGL、WebGPU のいずれのコンテキストでレンダリングするかによって異なります。

    const ctx = canvas.getContext("2d");
    // Draw HTML element into canvas in 2D
    ctx.drawElementImage(myElement, myElementX, myElementY);
    
  3. 省略可: DOM とピクセルを同期します。ジオメトリの同期は、使用するコンテキストによっても異なります。2D では、デフォルトでブラウザが自動的に処理しますが、3D コンテキストでは、変換を構築して updateElementGeometry メソッドに渡す必要があります。

    // In 3D, construct a transform as needed, for example:
    const transform = new DOMMatrix().translate(x, y);
    // Synchronize the element's DOM and pixels
    canvas.updateElementGeometry(myElement, { canvasTransform: transform });
    

フレームワークとエコシステムのサポート

主要な WebGL および 3D グラフィック ライブラリは、HTML-in-Canvas をサポートしています。

  • Three.js: THREE.HTMLTexture を使用した試験運用版のサポートを提供します。

    const material = new THREE.MeshBasicMaterial();
    material.map = new THREE.HTMLTexture(uiElement);
    const mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), material);
    scene.add(mesh);
    
  • PlayCanvas: setSource() を使用した HTML テクスチャ ストリーミングをサポートしています。

    canvas.addEventListener('paint', () => {
      htmlTexture.setSource(htmlElement);
    }, { once: true });
    
  • Babylon.js: BABYLON.HtmlTexture を介して組み込みバインディングを提供します。

    const htmlTexture = new BABYLON.HtmlTexture("htmlTexture", uiElement, scene);
    material.diffuseTexture = htmlTexture;
    
  • PixiJS: HTMLSource を使用したバージョン v8.19.0 で組み込みサポートがリリースされました。

    import { HTMLSource } from 'pixi.js/html-source';
    const sprite = Sprite.from(new HTMLSource({ resource: form, autoUpdate: true }));
    app.stage.addChild(sprite);
    
  • CanvasUI: HTML-in-Canvas 専用に設計されたオープンソースのコンポーネント ライブラリ。

実装の詳細については、各フレームワークのドキュメントをご覧ください。

機能の検出とフォールバック戦略

クロスブラウザの互換性を確保するには、コードを実行する前に API のサポートを確認します。

export function supportsHtmlInCanvas() {
  if (typeof document === "undefined") return false;
  const canvas = document.createElement("canvas");
  canvas.setAttribute("content", "drawable");
  return canvas.content === "drawable";
}

API が利用できない場合は、代替 UI、フローティング HTML オーバーレイ、または利用可能なライブラリ(three-html-render、html2canvas、dom-to-image など)のいずれかにフォールバックできます。

次のステップ