表題のことについてちょっと調べていて、だいたい以下のようなアプローチに分類できそう、と思ってきたのでメモです。
SVGの <foreignObject>
にHTMLを突っ込む
SVGには <foreignObject>
という要素があり、SVG以外の要素を描画することができる。ここにHTMLを丸ごと突っ込んだ上でSVGを画像化する、というアプローチ。
html-to-imageというライブラリがこの方針で実装されている。単にforeignObjectに突っ込むだけだと、画像やフォントがうまく使われないので埋め込む、ということをやっていそう*1。
SafariではforeignObjectの制約が強いためうまく動かない、ということがhtml-to-imageのREADMEに書いてある。Safariをターゲットとしないならこのアプローチでうまくいきそう。
レンダラーを再実装する
ブラウザのレンダラーと同様に、任意のDOM要素を画像化する部分を実装してしまおう、というアプローチ。この方法は実行環境によらずうまく動く可能性が高いものの、ブラウザと全く同じ描画結果になる保証はない。
html2canvas は、DOM要素を受け取って独自実装のレンダラーでcanvasに画像として書き出している。
vercel/satoriは、DOMのサブセットとスタイルを受け取ってSVGに変換 (ベクタ画像化) している。
画面キャプチャAPIを使う
画面キャプチャAPIを使って、ブラウザの画面を映し、それを画像化することができそう? ただし画像キャプチャAPI自体はモバイル端末には対応していない。
既存の画像生成アプリケーションをWASMにコンパイルしてブラウザ上で動かす
ぜんぜん調査できていないけど、たしかにそういう手法もありそう!!