domToImg.dom = document.body;
domToImg.download(location.protocol + "//" + location.host + "/build/main.css");
Last active
March 1, 2018 02:58
-
-
Save Gaubee/752196899eacc94cbd25d9ba47f04971 to your computer and use it in GitHub Desktop.
Capture DOM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var domToImg = (function () { | |
// 转png需要的canvas对象及其上下文 | |
var canvas = document.createElement('canvas'); | |
var context = canvas.getContext('2d'); | |
// canvas绘制图片元素方法 | |
var draw = function (img) { | |
var width = img.width, height = img.height; | |
// canvas绘制 | |
canvas.width = width; | |
canvas.height = height; | |
// 画布清除 | |
context.clearRect(0, 0, width, height); | |
// 绘制图片到canvas | |
context.drawImage(img, 0, 0); | |
}; | |
// canvas画布绘制的原图片 | |
var img = new Image(); | |
// 回调 | |
var callback = function () { }; | |
// 图片回调 | |
img.onload = function () { | |
draw(this); | |
// 回调方法 | |
callback(); | |
}; | |
function deepCloneDom(dom) { | |
var cloneDom = dom.cloneNode(true); | |
deepLoopElement(dom, cloneDom); | |
return cloneDom; | |
} | |
function deepLoopElement(sourceEl, cloneEl) { | |
var sourceArr = sourceEl.childNodes; | |
var cloneArr = cloneEl.childNodes; | |
if (sourceArr.length !== cloneArr.length) { | |
throw new Error("ERROR DOM TREE"); | |
} | |
cloneStyle(sourceEl, cloneEl); | |
cloneArr.forEach((cloneNode, i) => { | |
if (cloneNode.nodeType === 1) { | |
var sourceNode = sourceArr[i] | |
cloneStyle(sourceNode, cloneNode); | |
if (cloneNode.childNodes.length) { | |
deepLoopElement(sourceNode, cloneNode); | |
} | |
} | |
}) | |
} | |
function cloneStyle(dom, cloneDom) { | |
cloneDom.style.cssText = getComputedStyle(dom).cssText; | |
} | |
var exports = { | |
dom: null, | |
// DOM变成svg,并作为图片显示 | |
dom2Svg: function (css_link?: string) { | |
var dom = this.dom; | |
if (!dom) { | |
return this; | |
} | |
// 复制DOM节点 | |
var cloneDom = deepCloneDom(dom);//.cloneNode(true); | |
cloneDom.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); | |
cloneDom.classList.remove('outline'); | |
// 如果有图片,变成base64 | |
var imgDom = null; | |
if (cloneDom.tagName.toLowerCase() == 'img') { | |
imgDom = cloneDom; | |
draw(imgDom); | |
imgDom.src = canvas.toDataURL(); | |
} else { | |
cloneDom.querySelectorAll('img').forEach((imgDom) => { | |
draw(imgDom); | |
imgDom.src = canvas.toDataURL(); | |
}); | |
} | |
// window["CD"] = cloneDom; | |
var outerHTML = new XMLSerializer().serializeToString(cloneDom).replace(/#/g, '%23').replace(/\n/g, '%0A') | |
const bgImageDownloadTasks: Promise<any>[] = outerHTML.match(/url\(\"([\w\W]+?)\"\)/g).map((fullUrl, i) => { | |
var imgurl = fullUrl.substring(10, fullUrl.length - 7); | |
console.log(i, "下载背景图片:", imgurl) | |
return new Promise((resolve) => { | |
var bgImg = new Image(); | |
bgImg.src = imgurl; | |
bgImg.onload = () => { | |
draw(bgImg); | |
outerHTML = outerHTML.replace(fullUrl, "url("" + canvas.toDataURL() + "")"); | |
console.log(i, "下载完成") | |
resolve(); | |
} | |
}); | |
}); | |
if (css_link) { | |
console.log("下载样式表", css_link) | |
bgImageDownloadTasks.push( | |
fetch(css_link) | |
.then(res => res.text()) | |
.then((css_text) => { | |
outerHTML += "<style>" + css_text + "</style>"; | |
console.log("下载样式表完成") | |
}) | |
) | |
} | |
Promise.all(bgImageDownloadTasks) | |
.then(() => { | |
// 图片地址显示为DOM转换的svg | |
img.src = 'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="' + dom.offsetWidth + '" height="' + dom.offsetHeight + '"><foreignObject x="0" y="0" width="100%" height="100%">' + | |
outerHTML + | |
// document.querySelector('style').outerHTML + | |
'</foreignObject></svg>'; | |
}) | |
return this; | |
}, | |
// 作为图片下载,JS前端下载可参考这篇文章: | |
// JS前端创建html或json文件并浏览器导出下载 - http://www.zhangxinxu.com/wordpress/?p=6252 | |
download: function (css_link?: string) { | |
// 创建隐藏的可下载链接 | |
var eleLink = document.createElement('a'); | |
// 下载图片文件名就按照时间戳来 | |
eleLink.download = 'zxx_png-' + (+new Date() + '').slice(1, 9) + '.png'; | |
eleLink.style.display = 'none'; | |
var start_time = new Date(); | |
// 触发图片onload是个异步过程,因此,需要在回调中处理 | |
callback = function () { | |
eleLink.href = canvas.toDataURL(); | |
var end_time = new Date(); | |
console.log('耗时:', end_time.valueOf() - start_time.valueOf()) | |
// 触发点击 | |
document.body.appendChild(eleLink); | |
eleLink.click(); | |
// 然后移除 | |
document.body.removeChild(eleLink); | |
}; | |
// dom变图片 | |
this.dom2Svg(css_link); | |
} | |
}; | |
return exports; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment