需求:將頁面中DIV內容塊(包含svg流程節點)生成圖片並直接下載到用戶本地,並且不影響之前的svg圖使用
實現:
1、安裝依賴
cnpm install --save html2canvas cnpm install --save canvg@2.0.0-beta.1 canvas@^2 jsdom@^13 xmldom@^0
2、引入依賴
import html2canvas from "html2canvas"; import canvg from "canvg";
3、代碼實現
html部分
<div id="tree-containner"> <div id="tree">... 這里需要生成圖片的內容 <svg></svg></div> </div>
js部分
主要是兩個問題
- SVG無法顯示: 借助canvg將svg轉canvas
- 不能影響原有的元素顯示:上一步會改變原有的dom結構導致svg的拖動特性不能在使用,因此用一個中間元素來做圖片導出。
handleGenerator() {
// 最外層的容器
const treeContainnerElem = document.getElementById('tree-containner')
// 要導出div
const treeElem = document.getElementById("tree")
// 從要導出的div克隆的臨時div
const tempElem = treeElem.cloneNode(true)
tempElem.id = 'temp-tree'
tempElem.className = 'fff'
tempElem.style.width = treeElem.clientWidth + 'px'
tempElem.style.height = treeElem.clientHeight + 'px'
treeContainnerElem.appendChild(tempElem)
// 在臨時div上將svg都轉換成canvas,並刪除原有的svg節點
const svgElem = tempElem.querySelectorAll("svg");
svgElem.forEach((node) => {
var parentNode = node.parentNode;
var svg = node.outerHTML.trim();
var canvas = document.createElement("canvas");
canvg(canvas, svg);
canvas.style.zIndex = 9
if (node.style.position) {
canvas.style.position += node.style.position;
canvas.style.left += node.style.left;
canvas.style.top += node.style.top;
}
parentNode.removeChild(node);
parentNode.appendChild(canvas);
});
html2canvas(tempElem, {
useCORS: true // 允許CORS跨域
}).then(canvas => {
// 圖片觸發下載
const img = canvas.toDataURL("image/jpeg").replace("data:image/jpeg;base64,", "");
const finalImageSrc = "data:image/jpeg;base64," + img;
const aElem = document.createElement('a')
document.body.appendChild(aElem)
aElem.href = finalImageSrc
// 設置下載標題
aElem.download = "chart.jpg"
aElem.click()
document.body.removeChild(aElem)
treeContainnerElem.removeChild(tempElem)
})
}
