teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

ソリューションを思いついたのでサンプルコードを追加

2017/11/26 02:20

投稿

defghi1977
defghi1977

スコア4756

answer CHANGED
@@ -1,12 +1,58 @@
1
- 出来せん.
1
+ 追記)後日条件付きながら解決策を思いついたため, 記事後半にサンプルを追記しした.
2
2
 
3
+ ---
4
+ (基本的に)出来ません.
5
+
3
6
  まず, html2canvasは**WEBページキャプチャツールではありません**. HTMLDOMの**レンダラ**です. つまりスタイル情報等を元に`canvas`要素上に**HTMLを描いている**のです.
4
7
 
5
8
  また, スタイル情報を現在表示している`window.document`を頂点とするDOMツリーから取得するため, html2canvasに渡す`element`はこのDOMツリーに配置されている必要があります.
6
9
 
7
- 従って, 現在表示していないURLのWEBページをhtml2canvasで画像化することは出来ません. また, Ajaxなどを用いてWEBページ情報をDOMツリーとして入手して, それを`canvas`上に描くためには`window.document`にそのDOMツリーを所属させなければならず, スクリプトやスタイル設定が競合する可能性が高ことから正しく動作することはないでしょう.
10
+ 従って, 現在表示していないURLのWEBページ, もはオリジンが異なるためにそもそもHTMLDOMにアクセス出来ないURLWEBペhtml2canvasを用て画像化することは出来ません.
8
11
 
12
+ なお, 単にWEBページのスクリーンショットを撮るだけであれば, WEBブラウザの開発ツールに相応の機能があるため, そちらを使ったほうが良いでしょう.
13
+ また, ヘッドレスChromeを用いてコマンドラインから目的のURLのWEBページを画像化する方法もあります.
14
+
9
15
  ---
16
+ なお, 同一オリジンのWEBページであれば`iframe`要素に当該ページを読み込んだ後, html2canvasを後付で実行することで間接的に"キャプチャ"画像を取得することは可能です.
17
+ (が, html2canvasのレンダリング性能を鑑みるとある程度妥協が必要です)
10
18
 
19
+ ```JavaScript
20
+ "use strict";
21
+ //キャプチャのトリガ
22
+ out.onclick = e => {
23
+ //目的のURLをiframeに読み込む
11
- なお, 単にWEBページのスクリーンショットを撮るだけであれば, WEBブラウザの開発ツールに相応の機能があるため, そちらを使ったほうが良いでしょう.
24
+ const iframe = document.createElement("iframe");
25
+ document.body.appendChild(iframe);
26
+ iframe.onload = e => {
27
+ const iwin = iframe.contentWindow;
28
+ //メインウインドウにキャプチャ結果を渡すコールバックの定義
29
+ iwin.__callback = function(id){
30
+ iframe.remove();
31
+ const canvas = document.createElement("canvas");
32
+ canvas.width = id.width;
33
+ canvas.height = id.height;
12
- また, ヘッドレスChromeを用いてコマンドラインから目的のURLのWEBページを画像化する方法もあります.
34
+ canvas.getContext("2d").putImageData(id, 0, 0);
35
+ document.body.appendChild(canvas);
36
+ };
37
+ //iframe内にhtml2canvasによるキャプチャ機構を挿入する
38
+ const doc = iwin.document;
39
+ const script = doc.createElement("script");
40
+ script.textContent = `
41
+ "use strict";
42
+ {
43
+ const script = document.createElement("script");
44
+ script.src = "html2canvas.min.js";
45
+ script.onload = e => {
46
+ html2canvas(document.body, {
47
+ onrendered: canvas => window.__callback(canvas.getContext("2d").getImageData(0,0,canvas.width,canvas.height)),
48
+ width: 200,
49
+ height: 300
50
+ });
51
+ }
52
+ document.head.appendChild(script);
53
+ }`;
54
+ doc.head.appendChild(script);
55
+ };
56
+ iframe.src = "target.htm";
57
+ };
58
+ ```