簡単にjsを分析してウェブページのスクリーンショットの2種類の方式を実現します。
4790 ワード
Web端末のスクリーンショット(写真を生成する)は高周波の需要ではなく、資料も多くないので、調べても、CanvasとSVGの2つの実現案です。原理は大体似ています。本当の意味でのスクリーンショットではなく、DOMを画像に変換しますが、実現方法は全く違っています。
キャンバス実現
どうやってdomをcanvasの写真に変換しますか?もちろん少しずつキャンバスに描いていくのです。考えるのも面倒くさいです。githubの有名なカット図庫niklasvh/html 2 canvas(7 k+star)のソースコードを分析することによって、大体の考えを整理しました。は、対象テンプレートのすべてのDOMノードを再帰的に取り出し、1つのreder Listに充填し、最上位の要素/コンテンツを含むコンテナなどの情報を付加する 。は、z-indx postion froatなどのcss属性と要素の階層情報を通じてreder Listを並べ替えて、canvasのrenderQue を計算しました。はrenderQueを巡回して、cssスタイルをset FillSteyle識別可能なパラメータに変えて、nodeTypeによって呼応するcanvas方法を呼び出して、テキストのようにfillTextを呼び出して、画像drawImage、背景色のdivを設定してfillct Rectなど を呼び出します。で描いたcanvasをページ に充填します。
優先度の計算もcssからcanvasへの転換も、間違いなく大きなトラブルであり、特に実際のビジネスシーンにおいては、DOMモデルには複雑な様式とレイアウトが含まれており、html 2 canvasは20以上のjsを使ってこの層の転換を実現しており、複雑さが見られます。いっそのこと、私たちはもう一度車輪を作る必要はないです。
canvasを使うと柔軟性が高く、環境に依存してもブラウザがcanvasをサポートしてくれるだけでいいですが、著しい欠点があります。遅いです。その理由は当然、大量の計算と再帰的な呼び出しのために避けられない。ただし、httml 2 canvasコードにはPromiseが多く使われていますので、html 2 canvasは非同期操作をサポートしています。
制限:はドメインをまたぐことができません。 はiframe、flashなどのコンテンツをレンダリングできませんが、svg は現在サポートされています。
ちなみに、httml 2 canvasのホームページではまだ実験室の環境にあるとしていますが、14年からTwitterなどで生産環境に使われていますので、多くの制限がありますが、安定性はまだ保障されています。
canvasは複雑ですが、もっと簡単な方法がありますか?
もちろんあります。それはSVGです。
SVG実装
まず、svgはもともとベクトルパターンです。次に、svgはxmlで説明できる。次に、svgを記述するタグの中にforeignObjectタグがあります。このラベルは他の名前空間のxml(x)文書を読み込むことができます。つまり、svgを使うなら、私達はもうちょっとの遍歴、転換ノードを必要としません。複雑な要素優先度を計算しなくてもいいです。レンダリングするDOMを に捨てればいいです。あとはブラウザにレンダリングします。
考えを整理しましょう。まず、基本的なsvgモデルを宣言したいです。このモデルはいくつかの基礎的な説明情報が必要です。最も重要なのは、「foreignObject」というラベル です。レンダリングするDOMテンプレートをforeignObject に埋め込む。は、Blobを利用してsvg画像 を構築する。はURLを取り出して、 に割り当てます。
幸い、Christph Burgmerというニックネームのお兄さんがレジスターizeHTML.jsというライブラリを書いてくれました。一連のhack技術を通じて、いろいろな制限を回避してくれました。彼がどうやってできたのか気になります。簡単に言えば、rasterizeHTML.jsは私達の基礎の実現の上でこれらのhackをしました。は
のurlをdataURI に変えます。はバックグランドカラーをスタイリングから取り出し、urlを修正してスタイルテーブル を新たに挿入する。は、linkのスタイルをajax downを通して降りて を注入する。はソースコードをご参照ください。 もちろん、rasterizeHTML.jsは私達のためにすることができるのもただ資源の引用問題とブラウザーの互換性の問題を処理するだけであることができて、更に多くのSVGの制限は迂回することができないので、この倉庫の文書は正式に1ページの制限をリストして、人に読み終わった後に心の中が冷やせます。たとえば:クロスドメインリソースは をロードできません。、lazyloadなどのjsでロードされたリソースは をロードできません。内連結またはjs操作background-mageは をロードできません。 详见文档 これらの制限が避けられない原因は、レジスターizeHTML.jsの原理を考えると理解できます。rasterizeHTML.jsはすでに存在している静的リソースのみを処理することができますが、jsの動的生成はリアルタイムでは処理できません。
現在、raster izeHTML.jsはすでに知乎-意見フィードバック機能に使われています。
参照
ソースhttps://developer.mozilla.org/en-US/docs/Web/API/Canvas API/DrawingDObject sintoacanvas
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。
キャンバス実現
どうやってdomをcanvasの写真に変換しますか?もちろん少しずつキャンバスに描いていくのです。考えるのも面倒くさいです。githubの有名なカット図庫niklasvh/html 2 canvas(7 k+star)のソースコードを分析することによって、大体の考えを整理しました。
優先度の計算もcssからcanvasへの転換も、間違いなく大きなトラブルであり、特に実際のビジネスシーンにおいては、DOMモデルには複雑な様式とレイアウトが含まれており、html 2 canvasは20以上のjsを使ってこの層の転換を実現しており、複雑さが見られます。いっそのこと、私たちはもう一度車輪を作る必要はないです。
canvasを使うと柔軟性が高く、環境に依存してもブラウザがcanvasをサポートしてくれるだけでいいですが、著しい欠点があります。遅いです。その理由は当然、大量の計算と再帰的な呼び出しのために避けられない。ただし、httml 2 canvasコードにはPromiseが多く使われていますので、html 2 canvasは非同期操作をサポートしています。
制限:
ちなみに、httml 2 canvasのホームページではまだ実験室の環境にあるとしていますが、14年からTwitterなどで生産環境に使われていますので、多くの制限がありますが、安定性はまだ保障されています。
canvasは複雑ですが、もっと簡単な方法がありますか?
もちろんあります。それはSVGです。
SVG実装
まず、svgはもともとベクトルパターンです。次に、svgはxmlで説明できる。次に、svgを記述するタグの中にforeignObjectタグがあります。このラベルは他の名前空間のxml(x)文書を読み込むことができます。つまり、svgを使うなら、私達はもうちょっとの遍歴、転換ノードを必要としません。複雑な要素優先度を計算しなくてもいいです。レンダリングするDOMを
考えを整理しましょう。
<div id='text'>
<h1 style="background-color: #ccc;width: 200px;height: 200px;" >Hello World</h1>
</div>
// chrome
function html2Svg (domStr) {
//
var svgXML=
`<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
<foreignObject width="100%" height="100%">${generateXML(html)}</foreignObject>
</svg>`
// Blob svg
var svg = new Blob([svgXML], {type: 'image/svg+xml'})
// DOMURL.createObjectURL
var url = window.URL.createObjectURL(svg);
var img = new Image()
img.src = url
return img
}
// `foreignObject` XML ,
// DOM
function generateXML (domStr) {
var doc = document.implementation.createHTMLDocument('');
doc.write(html);
doc.documentElement.setAttribute('xmlns', doc.documentElement.namespaceURI);
doc = parseStyle(doc)
console.log(doc)
html = (new XMLSerializer).serializeToString(doc).replace('<!DOCTYPE html>','');
return html
}
この考え方で実現するのは非常に簡単で、複雑な計算と再帰性がなく、レンダリング速度は自然に前者より優れていると見られます。しかしsvgを使うには、多くの制限が必要です。一つの最も深刻な問題は、SVGが外部資源をロードできない、すなわちsvgの中で、それともcssの中の背景図であろうと、これらの資源は全部ロードできないということです。canvasを使って実現する時、私達はnodeの一つのnodeで描くので、資源の引用の問題が存在しません。しかしsvgを使って実現して、私達が文書をSVGに渡してもう一度レンダリングすることに相当して、これは私達にとって実は制御できないブラックボックスの操作で、SVGの制限を受けたのです。幸い、Christph Burgmerというニックネームのお兄さんがレジスターizeHTML.jsというライブラリを書いてくれました。一連のhack技術を通じて、いろいろな制限を回避してくれました。彼がどうやってできたのか気になります。簡単に言えば、rasterizeHTML.jsは私達の基礎の実現の上でこれらのhackをしました。
のurlをdataURI
現在、raster izeHTML.jsはすでに知乎-意見フィードバック機能に使われています。
参照
ソースhttps://developer.mozilla.org/en-US/docs/Web/API/Canvas API/DrawingDObject sintoacanvas
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。