前言
顾名思义,html2canvas 就是将 html 元素转化为 canvas 画布,之后再将 canvas 导出图片。本文就将如题所示的功能奉上。
一、属性介绍
1、scrollX: 类型 number,默认值不清楚。解决 div 元素太大超出屏幕宽度,导致生成的 canvas 显示不全的问题。
2、scrollY: 类型 number,默认值不清楚。解决 div 元素太大超出屏幕高度,导致生成的 canvas 显示不全的问题。
3、dpi: 类型 number,默认值不清楚,像素点数。决定图片像素大小或清晰度。
4、backgroundColor: 类型 string,默认 #fff,生成 canvas 的背景色,如果想要透明的效果,直接赋值为 null。透明背景在微信内打开可能会有黑边,下述代码会讲到如何处理黑边问题。
5、allowTaint: 类型 boolean,默认 false,设置是否允许跨域。需要注意的是,前端即便设置为 ture 也不能跨域,需要后端设置 header 才能跨域(需要后端在response 的 header 中带上 Access-Control-Allow-Credentials 属性。同时前端的 Image 也要设置 crossOrigin 属性为 Anonymous)。
6、height: 类型 number,默认null,生成 canvas 的高度。一般不用此属性,因为有时画布比较大,会超出显示范围,此属性会带来很大的局限性。
7、width: 类型 number,默认 null,生成 canvas 的宽度。一般不用此属性,同 height。
8、letterRendering: 类型boolean,默认 false,在设置了字间距的时候有用。
9、logging: 类型 boolean,默认 false,输出调试信息。
10、proxy: 类型 string,默认 undefined,代理地址。可以解决跨域问题,但只能解决一个域名,如有多个域名跨域,则不适用。
11、taintTest: 类型 boolean,默认 true,在渲染前是否检查图片。
12、timeout: 类型 number,默认 0,图片加载延迟时间。
13、useCORS: 类型 boolean,默认 false,解决跨域问题,一般赋值为 ture (可以结合第5条)。
二、h5标签元素
提示: 下面的代码可以看出,contianer 内包含了很多的内容。接下来就把这些内容转化成 canvas。
注意: 如果你的标签内用到了很多的远程资源,尽可能的避免跨域问题。当然,也可以和后端一起配合来解决这个问题。
<div id="contianer">
<img src="./top.png" />
<div>
<img src="./title.png" />
<span>卧龙先生</span>
<div>
<img src="./qrcode.png" />
</div>
</div>
</div>
三、生成canvas,下载、复制图片
提示: 生成 canvas 和导出图片的时候,有一个压缩的过程,会消耗一些时间,所以要打开调试面板,看一下日志文件。
1、生成 canvas。下述 callBack 函数会在第2条和第3条被调用。
callBack() {
const targetDom = document.getElementById('contianer');
html2canvas(targetDom, {
useCORS: true,
allowTaint: true,
scrollX: 0,
scrollY: 0,
backgroundColor: null,
dpi: window.devicePixelRatio * 2,
}).then(canvas => {
// 注释1
console.log('>>>> 生成canvas成功 >>>>');
});
}
2、下载图片。比如我们点击“下载图片”按钮调用第1条的 callBack 函数,之后在 注释1 的位置,敲上下述代码即可下载到本地。
const dom = document.createElement('a');
dom.href = canvas.toDataURL('image/png');
dom.download = '图片名称.png';
dom.click();
3、一键复制图片。比如我们点击“一键复制”按钮,可以将数据写入到剪切板,再粘贴到目标区域。依旧是调用第1条的 callback 函数,之后在 注释1 的位置,敲上下述代码即可实现复制、粘贴功能。
( 注意:ClipboardItem 是系统函数,如何正确调用需要根据自己的开发语言做调整)
canvas.toBlob(blob => navigator.clipboard.write(
[new window.ClipboardItem({[blob.type]: blob})]
))
四、处理黑边问题
1、出现黑边的常见情况:
(1) 设备配置不同。比如你在 mac 上是好的,但在 windows 上就有黑边;在钉钉上是好的,但在微信内就有黑边;在 chrome 浏览器是好的,但在搜狗浏览器就有黑边。
(2) 适配问题。有时生成 canvas 的宽高会多出几个像素,这几个多出来的像素就可能会变成黑边。
2、解决办法:
不管哪种原因造成的黑边,几乎都跟背景透明有关,所有我们来个简单易懂的处理方式。在不影响主体内容的情况下,我们可以将透明的部分全部设置为白色。我们可以在下载或复制前,将 canvas 的图片属性的 data 重置一下。下述代码依然写在 注释1 的位置。
let context = canvas.getContext('2d')
let image = context.getImageData(0, 0, canvas.width, canvas.height)
for(var i = 0; i < image.data.length; i += 4) {
// 当该像素是透明的,则设置成白色
if(image.data[i + 3] == 0) {
image.data[i] = 255
image.data[i + 1] = 255
image.data[i + 2] = 255
image.data[i + 3] = 255
}
}
context.putImageData(image, 0, 0);
// 之后,在此处继续写上第三部分的第2或第3条代码
后语
技术无止境,我对 html2canvas 的了解也只是冰山一角,希望对你有所帮助。