HTML-in-Canvas: HTML コンテンツを Canvas に直接レンダリングする新しい API の提案
(github.com/WICG)- HTML-in-Canvasは、ウェブ上で
<canvas>要素内に** HTML 要素/コンテンツを直接描画できる新しい標準 API**を提案する WICG のプロジェクトです - 複雑なテキストレイアウト、アクセシビリティ、国際化、品質/パフォーマンスの問題を解決するために登場し、チャート・UI・ゲームメニューなどの様々な Canvas 活用ケースで HTML スタイリングを直接活用可能
drawElement、texElement2D、setHitTestRegionsなどの新規メソッドを通じて、HTML 要素を Canvas 2D または WebGL コンテキストにそのままレンダリングおよびテクスチャ化可能- インタラクション領域、アクセシビリティ改善、3D シーン内 2D UI、CSS/HTML ベースレイアウトなど、実務的なウェブアプリ開発者のニーズを反映
- 現在 Chrome Canary (138.0.7175.0 以上) では実験的フラグとして有効化可能で、主要なフィードバック・バグレポートを歓迎しています
概要と重要性
- HTML 要素を直接
<canvas>に描画できる新しい APIを提案 - 従来は複雑なレイアウトやテキスト、HTML ベースコンテンツを
<canvas>に簡単にレンダリングする方法がなく、アクセシビリティ・国際化・性能・品質面で制約があった - HTML-in-Canvasはこれらの補完策として、2D キャンバスおよび WebGL内で HTML レンダリングをサポートし、チャートツール、リッチテキストボックス、ゲーム UI など幅広い領域での適用性を高める
利用事例
- スタイルが適用されたテキストおよびレイアウトコンテンツをキャンバス内で表現
- 例: チャートの凡例、軸、リッチエディターのボックス、ゲーム内メニューなど
- アクセシビリティの強化
- 既存の Canvas で発生していた代替コンテンツと実際にレンダリングされた内容の不一致問題を解消
- 新しい API によりアクセシビリティ情報の同期調整が可能
- HTML と WebGL シェーダーの組み合わせ
- CSS フィルター効果を超えて、一般的な WebGL シェーダーとの HTML 統合ニーズに対応
- 3D コンテキスト内 HTML レンダリング
- ゲーム/サイトの 3D 領域にリッチな 2D コンテンツを挿入可能
提案 API と主な機能
<canvas layoutsubtree>属性で canvas の子 HTML 要素のレイアウトを有効化(ただし、基本的には視覚的にのみレンダリングし、ページ探索など UA アルゴリズムには公開されない)- CanvasRenderingContext2D.drawElement(element, x, y, options)
- canvas の子 HTML 要素を指定位置にレンダリング
options.allowReadbackで個人情報漏えい防止を制御(将来的に tainting ポリシーを適用)- dwidth/dheight パラメータで必要なサイズへリサイズ可能
- WebGLRenderingContext.texElement2D(...)
- 指定 HTML 要素を WebGL テクスチャとして直接描画し、3D シーンで活用
- setHitTestRegions
- 特定領域に描画された要素と Canvas イベント(ヒットテスト)を連携し、マウス/タッチイベントを自動的にリダイレクト
- fireOnEveryPaint オプション (ResizeObserver)
- HTML の変更/再配置時に canvas の再レンダリングタイミングを自動検出して再描画をトリガー
動作と制約
- drawElement 呼び出し時、canvas transform matrix (CTM) が反映され、要素の border box 内にのみ画像がクリップ
- canvas に描画された画像は静的(レンダリング後に要素が変わると再度 drawElement が必要)
- オフスクリーンまたは DOM に存在しない canvas は未サポート(技術的な制約)
- インタラクション要素(ボタン、フォームなど)は描画可能だが、自動的にインタラクティブになるわけではない
- クロスオリジン iframe、SVG foreignObject などは未サポート
- アクセシビリティ、セキュリティ・プライバシー(PII)に関する問題は継続的に議論中
デモ例
- complex-text サンプル: canvas 上に HTML スタイルのテキストやボックスなど複雑なレイアウトを drawElement で直接描画
- webGL サンプル: texElement2D で HTML コンテンツを WebGL テクスチャとして生成し、3D キューブにマッピング
- text-input サンプル: setHitTestRegions と fireOnEveryPaint を活用して入力フォームなどのインタラクティブ領域を表示
開発者トライアルと注意点
- Chrome Canary で
--enable-blink-features=CanvasDrawElementフラグを使って有効化 - canvas の内容が tainted されないため、個人情報の漏えいに注意が必須
- API と挙動は継続的に変化しており、大規模な HTML テストケースはまだ不足
- フィードバック歓迎: 互換性、レンダリング失敗事例、アクセシビリティ問題などを GitHub Issue で報告することを推奨
活用価値と展望
- チャート、データ可視化、in-canvas UI、3D ゲーム内 HUD/メニューなど、さまざまな分野でウェブの表現力と生産性を向上
- 従来は複雑だった HTML→Canvas 変換(スタイル、レイアウト、多言語対応、アクセシビリティ)を、標準 API で直接処理可能
- ウェブベースのグラフィックス、ゲーム、アプリ開発者にとって、強力な新技術として期待される
1件のコメント
Hacker Newsコメント
アクセシビリティと悪用への懸念は多いが、この議論には別の側面もあると思う。 最近、X(Twitter)で興味深いスレッドを見た。ウェブの進化において、フォントレンダリングとメトリクスがJSで使えないため90%の良い取り組みが実現できていないという話があった。 ウェブはテキストを表現するために設計されたプラットフォームなのに、テキストを詳細に扱う機能がないという指摘や、tldrawでテキスト測定を無理に実装しなければならないことが残念だという反応など、さまざまな意見があった(Twitterスレッド: https://x.com/_chenglou/status/1951481453046538493) ウェブはアプリケーション開発プラットフォームなので、誰にとっても簡単かつ強力に作ることが重要だ。 私はWeb APIはもう少しローレベルに下げるべきだと思っていて、キャンバス向けのフォント/テキストメトリクスAPIがあれば非常に良いと思う。 ただし同時に、ウェブエンジンのテキストレイアウトは非常に高性能なので、そういった機能がキャンバス内部でも使えるなら素晴らしい機能が生まれるはずだ。 私が何年も繰り返している例は「ページネーション付きリッチテキスト編集」で、contenteditableだけでは製品レベルの実装が不可能だったため、Google Docsが独自のレイアウトエンジンを作ったことだ。 この提案が採用されれば、contenteditableの強さと、ページ/印刷レイアウトの制御可能性を両方活かせるようになる。 この機能がブラウザに実装されることを望む
「ウェブで起きうる大部分の良いことは、フォントレンダリングとメトリクスにアクセスできないために不可能だ」という主張には疑問がある。 実際、代表的な革新的な事例が何か見てみたい。 今でもJSでフォントとメトリクス情報はかなり提供されており、必要な機能のほとんどは性能劣化を深刻化させずに回避できる。 さらに、HTML-in-Canvasが提供する部分で根本的な変化が起きるわけでもない
私もGoogle Docsのように、NutrientではHarfbuzzと独自のレイアウトエンジンをWASMベースで使っている。 デモ: https://document-authoring-demo.nutrient.io/ このAPIがプラットフォームとして公式提供されれば、開発はずっと簡単になる。 WASMのおかげで、本当に行き詰まる道ではない。 ElectricSQLで同期作業が進行中だと聞いたので、Oleksiiにもよろしく
「この機能がブラウザに実装されることを願う」という言葉に対して、世界で最も非効率なレイアウト/UIエンジンをキャンバスにまで拡張したい理由が分からない。 こうなると、逆に現在のように十分なAPIアクセス権がないという問題が固定化されるだけになる。 FigmaはDOMの限界を超えるために、ブラウザ内で別のブラウザを作る方式で動いている(参考: https://www.figma.com/blog/building-a-professional-design-tool-on-the-web/) contenteditableだけでは製品レベルの実装ができずGoogle Docsが独自エンジンを作ったから、新提案がリッチテキストレイアウトに実質的に役立つのは難しい
この機能は有用性が高いと思うが、HTMLの中にキャンバス、さらにその中にHTMLを入れる構造自体、どこか奇妙で違和感がある。 私の考えでは、キャンバスがブラウザで独立した第一級フォーマットになれば、より自然に扱えるようになる。 そうすればHTML中心のページにキャンバスを入れること、逆にキャンバス中心にHTML要素を含める構造も自然になるだろう。 もちろんこれは私見だ
君の言うことに全く違和感はない。 ちなみに、すでにHTMLはSVG内に、さらにHTML内にも入れられる。 もしキャンバスがページの最上位要素なら、ページのタイトルはどこに保存する? 結局、``タグを使うしかないので、例えば
実質的にキャンバスタグの中にコンテンツを入れられるようにすればシンプルに解決できる
キャンバス中心のウェブサイトは不便が多い システムサービス(自動補完、アクセシビリティなど)全体を使えず、プライバシーの問題もある。 例えばシステムのスペルチェック補正機能を使いにくく、システムのアクセシビリティも提供できないため、アプリごとに全く異なるUIアクセシビリティを直接実装する必要がある
君の言う構造ならFlashを発明したようなものだ。 ただし、FlashをWebに持ち込むことも大変だった
HTMLページにCanvasを置いて、その中のテキストにレイアウトやスタイルを追加したくなることはある。 とはいえ、ページ全体のレイアウト方式まで変更するのは不要に複雑な作業だ
以前、WASMのDOMアクセスに反対した人がいた。 だからこの方向性への進化は必然だと思う
いま私たちは、ブラウザ全体をWASMでコンパイルし、このブラウザをメインブラウザのキャンバス要素内で実行する時代に来ている
まるごとOSごと、IEすらWeb上で実行することも可能だ(例: https://copy.sh/v86/?profile=windows2000)
有名な「The Birth & Death of JavaScript」の前提と同じようなもの。 参考: https://www.destroyallsoftware.com/talks/the-birth-and-death-of-javascript
https://www.chromium.org/blink/blink-in-js/ のような試みもある
『サンドボックス化とセキュリティ』の問題で、このような構造が必須になる未来が来る可能性がある
参考として、https://trevorlinton.github.io でこのような環境を直接見ることができる
https://github.com/WICG/html-in-canvas/blob/main/security-privacy-questionnaire.md には、 『フィンガープリント(fingerprinting)収集のリスク』についてさらに追加すべきというTODOがある
SVGの
foreignObjectタグを活用すれば、すでにHTML-in-Canvasと似た結果を得られるはずだと思う。 例えば、https://github.com/zumerlab/snapdom のように、DOMをinlined styleでコピーしてSVGのforeignObjectに入れ、これをキャンバスにレンダリングするプロジェクトがあるforeignObjectをより簡単にキャンバスへ描画できるようにしたものに近い。 さらに、コンテンツが変わるたびにキャンバスを自動更新したり、インタラクティビティなど新しい機能もサポートしているもしかすると自分が間違っているのかもしれないが、純粋なJSだけでキャンバス上にHTMLをレンダリングするのは十分可能だと感じる。 キャンバスはHTMLではできないことを描くために使うもので、DOMを置き換えるための構造ではない
現在なら例えば
HTML要素がキャンバス上の全てより前にあるなら問題ないが、そうでない場合はHTML上にさらにキャンバスを敷いて対応しなければならず、zレイヤーごとに反復作業になる この変化で、ついにブラウザの「逆転したレンダリングレイヤースタック」を修正できると見ている。 すべてのブラウザレンダリングはユニバーサルキャンバスAPIの上に積み重ねるべきだ
すぐにHTML-in-Canvasでも再びキャンバスレンダリングをすることが必要になるのではないかと感じる
「Pimp My Ride」のミームが浮かぶほどだ。 「兄貴、HTMLが好きだって聞いたから、キャンバスにHTMLを入れて、HTMLの中にまたキャンバスを入れてあげた」みたいな感じ
次のようにbody要素にフラグをひとつ与えるのはどうだろうかと考える
これならページ全体がキャンバスと同じ描画サーフェスになり、普段どおりDOM要素をレンダリングできる。 内部的にDOMまでラスター化するプロセスを開いておけば、さらによいと思う。 アーキテクチャ上、DOMレンダリングとキャンバスレンダリングが完全に同等のレイヤーになる。 たとえば、ページ上の線を引くアクションがDOM要素のリフローを誘発したり、逆に無視したりするよう制御できる
スクリーンリーダーが全員同時に悲鳴を上げる場面が思い浮かぶ
この方法ならキャンバスが自動リサイズできるようになるかもしれない。もしそうならHTML合成の新時代を開くことになる。 iframeを超えることができる
僅かに違和感はあるが、この提案には賛成寄りだ。 何かを描画する際に、既存のHTML要素を再利用したくなる場面はよくある。 昔はそれをオフスクリーンでビットマップとしてレンダリングしてキャンバスにコピーしたり、
z-indexやposition absoluteで調整しようとしても、キャンバスが必ず視覚的に上書きしてしまう問題があった(最近はかなり改善されている)。 この方法が完璧な解決になるとは限らないかもしれないが、以前のこうした抜け道よりはかなり良いと思う。 まさにhtml2canvasのように、どうしてもそうすべき状況なら使える解決策だ