Skip to content

Instantly share code, notes, and snippets.

@Gaubee
Last active March 1, 2018 02:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gaubee/752196899eacc94cbd25d9ba47f04971 to your computer and use it in GitHub Desktop.
Save Gaubee/752196899eacc94cbd25d9ba47f04971 to your computer and use it in GitHub Desktop.
Capture DOM
domToImg.dom = document.body;
domToImg.download(location.protocol + "//" + location.host + "/build/main.css");
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\(\&quot;([\w\W]+?)\&quot;\)/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(&quot;" + canvas.toDataURL() + "&quot;)");
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