借助SVG forginObject实现DOM转图片实例页面
回到相关文章 »鼠标经过下面任意区域并点击:
长天
对网文潮流具有极敏锐嗅觉,有丰富写作指导经验。带出血红、猫腻、。。。。
代码:
CSS代码:
.outline {
outline: 2px solid red;
outline-offset: -2px;
}
HTML代码:
<div id="cmBox" class="c-m-box">
<div class="c-m-list">
<img src="0.jpg" alt="长天" class="c-m-img">
<div class="c-m-name">长天</div>
<div class="c-m-title">对网文潮流具有极敏锐嗅觉...</div>
</div>
</div>
JS代码:
// DOM转图片的方法
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();
};
var exports = {
dom: null,
// DOM变成svg,并作为图片显示
dom2Svg: function () {
var dom = this.dom;
if (!dom) {
return this;
}
// 复制DOM节点
var cloneDom = 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;
} else {
// 这里就假设一个图片,多图自己遍历转换下就好了
imgDom = cloneDom.querySelector('img');
}
if (imgDom) {
draw(imgDom);
imgDom.src = canvas.toDataURL();
}
var htmlSvg = '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%">'+
new XMLSerializer().serializeToString(cloneDom) +
document.querySelector('style').outerHTML +
'</foreignObject></svg>';
htmlSvg = htmlSvg.replace(/\n/g, '').replace(/\t/g, '').replace(/#/g, '%23');
// 图片地址显示为DOM转换的svg
img.src = htmlSvg;
return this;
},
// 作为图片下载,JS前端下载可参考这篇文章:
// JS前端创建html或json文件并浏览器导出下载 - http://www.zhangxinxu.com/wordpress/?p=6252
download: function () {
// 创建隐藏的可下载链接
var eleLink = document.createElement('a');
// 下载图片文件名就按照时间戳来
eleLink.download = 'zxx_png-' + (+new Date() + '').slice(1, 9) + '.png';
eleLink.style.display = 'none';
// 触发图片onload是个异步过程,因此,需要在回调中处理
callback = function () {
eleLink.href = canvas.toDataURL();
// 触发点击
document.body.appendChild(eleLink);
eleLink.click();
// 然后移除
document.body.removeChild(eleLink);
};
// dom变图片
this.dom2Svg();
}
};
return exports;
})();
// 实例页面的交互代码
var eleBox = document.getElementById('cmBox');
// hover outline
eleBox.addEventListener('mouseover', function (event) {
if (event.target !== this) {
event.target.classList.add('outline');
}
});
eleBox.addEventListener('mouseout', function (event) {
var eleOutline = eleBox.querySelector('.outline');
if (eleOutline) {
eleOutline.classList.remove('outline');
}
});
// 点击并下载图片
eleBox.addEventListener('click', function (event) {
var eleTarget = event.target;
if (eleTarget !== this) {
domToImg.dom = eleTarget;
domToImg.download();
}
});