2015-09-25 92 views
3

我意識到一個畫布不能直接呈現HTML。但是,似乎有潛在的解決方法。我不需要HTML來完美渲染,但我至少想要呈現HTML的圖像。如何製作HTML5 canvas顯示HTML?

爲此,我試圖將HTML轉換爲SVG。這適用於非常基本的HTML,但有許多用例(如包括在HTML圖像)打破:

var c = document.getElementById("myCanvas"); 
var ctx = c.getContext("2d"); 
var img = new Image(); 

var data = '<svg xmlns="http://www.w3.org/2000/svg" width="' + screen.width + '" height="' + screen.height + '">' + 
      '<foreignObject width="100%" height="100%">' + 
      '<div xmlns="http://www.w3.org/1999/xhtml">' + 
      document.body.innerHTML + 
      '</div></foreignObject></svg>' 

var svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'}); 
var url = DOMURL.createObjectURL(svg); 

img.onload = function() { 
    ctx.drawImage(img,0,0,c.width,c.height); 
    DOMURL.revokeObjectURL(url); 
} 
img.src = url; 

有越來越HTML畫布上正確顯示的更簡單的方法?

+1

「SVG圖像不允許加載任何外部資源,例如,甚至似乎是來自同一域的。」 https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Drawing_DOM_objects_into_a_canvas嘗試http://cburgmer.github.io/rasterizeHTML.js/ –

+1

http://html2canvas.hertzen.com/ – dandavis

+1

看看dandavis的鏈接 - 它適用於html,風格簡單。如果你需要在更多樣式密集的頁面上工作,你可以在你的服務器上加載一個無頭瀏覽器,然後把html + css傳遞到服務器瀏覽器來創建一個圖像。我可以推薦PhantomJS:http://phantomjs.org/ – markE

回答

1

您可能會創建一個基本的遞歸函數,以便下降到使用開關或事件處理程序對象來處理某些元素的元素的子元素<。我這裏展示了前者:

var canvas = document.getElementById('canvas'); 
 
var ctx = canvas.getContext('2d'); 
 

 
ctx.clearRect(0, 0, canvas.width, canvas.height); 
 

 
var y = 50; //Set to largest text 
 
var offset = 25; 
 

 
(function descend(parent){ 
 
    for(var i = 0; i < parent.childNodes.length; i++){ 
 
    var child = parent.childNodes[i]; 
 
    
 
    var name = child.tagName; 
 
    var val = child.innerHTML; 
 
    
 
    if(child.hasChildNodes()) descend(child); 
 
    
 
    switch(name){ 
 
     case 'H1': 
 
     ctx.font = "normal 48px Arial"; 
 
     y += 25; 
 
     ctx.fillText(val, offset, y); 
 
     y += 25; 
 
     break; 
 
     case 'H2': 
 
     ctx.font = "normal 36px Arial"; 
 
     y += 20; 
 
     ctx.fillText(val, offset, y); 
 
     y += 20; 
 
     break; 
 
     case 'H3': 
 
     ctx.font = "normal 24px Arial"; 
 
     y += 12; 
 
     ctx.fillText(val, offset, y); 
 
     y += 12; 
 
     break; 
 
     default: 
 
     break; 
 
    } 
 
    } 
 
})(canvas);
<canvas id="canvas" width="300" height="300"><h1>H1</h1><h2>H2</h2><h3>H3</h3></canvas>

這個代碼利用功能下降到元素的元素樹和處理不同的渲染技術的某些元素。這看起來有點過分,但如果你正在尋找一種有效的方法來實現這一目標,這種方法的工作原理。特別是隨着渲染的靈活性,這是您選擇如何渲染哪些元素的能力,所以如果您想渲染所有<範圍內的紅色,出於某種原因,您可以這樣做。我提供的功能是非常基本的,只能渲染< - < - <h3>,當你開始在裏面混合它們時,它會有一點「渲染干擾」。但它很好地展示了這個概念,我想你可能會覺得它很有效。

雖然張貼在評論的想法肯定是令人欽佩的,如果你正在尋找的靈活性,或者寧願在渲染控制,這可能是你正在尋找的解決方案。

注意:我會說代碼不會檢測元素的DOM中的更新<畫布>;你需要一個突變觀察者。您可能還希望將代碼放入加載頁面時運行的函數中,以便JavaScript運行時可以實際找到您的元素。

0

潛在的解決方案:

該腳本可以讓你把網頁或它的 部分的 「截圖」,直接在用戶的瀏覽器。該屏幕截圖基於DOM ,因此它可能不是100%準確的真實表示,因爲其 沒有製作實際屏幕截圖,而是根據頁面上提供的信息構建屏幕截圖。

DOM到圖像是可以把任意的DOM節點到 矢量(SVG)或柵格(PNG)圖像,用JavaScript編寫的庫。