世界を動かす技術を、日本語で。

HTML-in-Canvasの技術

2025年8月3日原文(github.com)

概要

HTML-in-Canvasは、 HTMLコンテンツをCanvas上に描画 するための新しいAPI提案。 主な目的は、 アクセシビリティや国際化、パフォーマンスの向上。 drawElementやtexElement2Dなどの 新メソッドを追加 し、2D/3D描画やヒットテストを実現。 開発者トライアル はChrome Canaryで利用可能。 既知の制限やフィードバック募集ポイントも明記。

HTML-in-Canvas:新しいCanvas描画API提案

  • HTMLコンテンツをCanvasへ直接描画 可能にする新APIの提案
  • Canvas 2D および WebGL 両方に対応
  • アクセシビリティや国際化、描画品質の向上 を主な目的
  • 複雑なレイアウトやスタイル付きテキスト の描画ニーズに対応
  • アクセシビリティ改善 :Canvasのフォールバック内容と描画内容が一致
  • WebGLシェーダーとHTML要素の合成 が可能
  • 3Dコンテキスト内でのHTMLレンダリング を実現

主なAPIと仕様

  • layoutsubtree属性 :Canvas内の子要素にレイアウトを許可
    • 直接の子要素がスタッキングコンテキスト・コンテインメントブロックとなる
    • 子孫要素は描画やヒットテスト対象外、UAアルゴリズムからも除外
  • drawElement(element, x, y, options) :要素とそのサブツリーを2D Canvasへ描画
    • layoutsubtree指定時のみ有効
    • オプションでプライバシー保護 (allowReadback)
    • dwidth, dheight指定でリサイズ描画 も可能
  • texElement2D(target, level, internalformat, format, type, element) :要素をWebGLテクスチャへ描画
    • layoutsubtree指定時のみ有効
  • setHitTestRegions([{element, rect}, ...]) :Canvas上の要素ごとにヒットテスト領域を設定
    • マウスやタッチイベントを自動的に描画要素へ転送

追加仕様と動作詳細

  • getBoundingClientRect()は空矩形 (layoutsubtree未指定時)
  • drawElementはCanvasのCTMを考慮
  • 描画画像は静的 :要素変更時は再描画が必要
  • fireOnEveryPaint オプション(ResizeObserverOptionsで追加)
    • DOM状態変化時にCanvas再描画通知
  • Canvasの子孫要素はアクセシビリティ情報提供のフォールバック扱い
  • Offscreen canvasやDOM未接続canvasは非対応

セキュリティ・プライバシー

  • allowReadbackオプション :個人情報漏洩防止に利用
  • WebGL描画時はPII含む内容は常に未描画
  • DevTrial利用時は情報漏洩に要注意

デモ・利用例

  • drawElementの基本デモ :青枠がCanvas、黒枠が描画要素
  • texElement2Dのデモ :HTML内容でCubeの面をテクスチャリング
  • three.js拡張による応用デモ
  • setHitTestRegionsとfireOnEveryPaintのデモ :Canvas内で<input>のインタラクション例

開発者トライアル情報

  • Chrome Canary v138.0.7175.0以降 --enable-blink-features=CanvasDrawElement オプションで有効化
  • APIは開発中 :仕様変更の可能性あり
  • どんなHTMLも描画できる保証はない
  • インタラクティブ要素も描画できるが、直接の操作性は自動付与されない
  • 既知の制限
    • クロスオリジンiframeは描画不可
    • SVG foreignObjectは未対応

フィードバック募集

  • どのコンテンツが描画可能か/失敗するか

  • 重要な失敗モードや優先修正点

  • Canvasレンダリングコンテキストごとの不足サポート

  • アクセシビリティとの相互作用や改善案

    • バグ報告や設計提案は GitHub Issue で受付

その他参考資料

  • Security and Privacy Questionnaire
  • 追加ドキュメントや詳細仕様 へのリンク案内

Hackerたちの意見

もうすぐHTML-in-Canvasの中でCanvasレンダリングが必要になるね。

ネストされたキャンバスが同じアプローチを使っていれば、もう動くはずだよ。ただ、サイクルにはならないけどね。サイクルキャンバスを動かすには、親キャンバスを手動でネストされたキャンバスに描く必要がある。

https://github.com/WICG/html-in-canvas/blob/main/security-pr... > TODO: フィンガープリンティングのリスクについて詳しく書く

テキストの中で探してみたけど、追加すべき欠けてる部分だね(「TODO: Don't be evil」にも関連するかも)。

すぐに「Pimp My Ride」の雰囲気を感じたよ。Yo dawg、HTMLが好きって聞いたから、HTMLをキャンバスの中に、さらにそのHTMLの中に入れたんだ。

今やるべきことは、ブラウザをWASMにコンパイルして、そのブラウザをメインブラウザのキャンバス要素内で動かすことだけだね…

IEを使ったOS全体はどう? https://copy.sh/v86/?profile=windows2000

https://www.chromium.org/blink/blink-in-js/

https://trevorlinton.github.io

それが「JavaScriptの誕生と死」の前提なんだよね。[1]: https://www.destroyallsoftware.com/talks/the-birth-and-death...

それから、「サンドボックスとセキュリティの理由で」、これが必須になるんだろうね。

これはすごく便利かもしれないけど、私にとってはHTMLの中のキャンバスってなんか呪われてる感じがする。私の意見では、キャンバスはウェブブラウザのための一級フォーマットであるべきだから、HTMLの中に入る必要はないと思う。そうすれば、HTML優先のページにキャンバス要素を入れるか、キャンバス優先のページにHTML要素を入れるかを選べるようになる。でも、私が何を知ってるっていうんだろう。

Hacker Newsで議論の続きを見る