前端要实现dom截图的功能,现在比较常用的是使用以下两个库
- dom-to-image 使用svg技术实现
- html2canvas 使用canvas技术实现
如果想自己写一个dom截图的可以参考
- dom-pointer 代码比较简单,非常适合拿来研究
- rasterizeHTML.js 目前rasterizeHTML.js已经被用于知乎-意见反馈功能。
两种截图方式
-
SVG 效率高
dom-to-image库主要使用的是SVG实现方式,简单来说就是先把DOM转换为SVG然后再把SVG转换为图片。 -
Canvas
html2canvas的内部实现相对dom-to-image来说要复杂一些, 基本原理是读取DOM元素的信息,基于这些信息去构建截图,并呈现在canvas画布中。
以上两种常见的npm库,对应着两种常见的实现原理。实现前端截图,一般是使用图形API重新绘制页面生成图片,基本就是SVG(dom-to-image)和Canvas(html2canvas)两种实现方案,两种方案目标相同,即把DOM转为图片,下面我们来分别看看这两类方案。
dom-to-image
个人认为这个库比较好用
<script src="https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js"></script>
vue实现
import domtoimage from "dom-to-image";
// dom截图
domShot(dom) {
domtoimage
.toPng(dom, { quality: 0.92 })
.then((dataUrl) => {
//保存图片
let saveFile = (data, filename) => {
let img = new Image();
img.src = data;
img.onload = () => {
// 缩放图片
const dataUrl = this.scalcImage(img);
this.download(dataUrl, filename);
};
};
saveFile(dataUrl, this.getFilename());
});
},
// 下载图片
download(dataUrl, filename) {
var blob_ = this.data_to_blob(dataUrl); // 转换为 blob
var link = document.createElement("a");
link.setAttribute("href", window.URL.createObjectURL(blob_));
link.setAttribute("download", filename);
link.click();
},
// 缩放图片到0.8
scalcImage(img) {
var canvas = document.createElement("canvas"); // 创建canvas元素
var scale = 0.8;
var width = img.width * scale; // 确保canvas的尺寸和图片一样
var height = img.height * scale;
canvas.width = width;
canvas.height = height;
canvas.getContext("2d").drawImage(img, 0, 0, width, height); // 将图片绘制到canvas中
const dataUrl = canvas.toDataURL("image/png"); // 转换图片为dataURL
return dataUrl;
},
// 获得文件名
getFilename() {
//获取年月日作为文件名
const timers = new Date();
const fullYear = timers.getFullYear();
const month = timers.getMonth() + 1;
const date = timers.getDate();
const randoms = Math.random() + "";
//年月日加上随机数
let numberFileName =
fullYear + "" + month + date + randoms.slice(3, 10);
return numberFileName + '.png'
}
html2canvas
<script type="text/javascript" src="http://html2canvas.hertzen.com/dist/html2canvas.js"></script>
import html2canvas from 'html2canvas';
html2canvas(dom).then((canvas) => {
this.download(canvas.toDataURL("image/png"), this.getFilename())
})
相关配置