html2canvas实现下载或复制功能

前言

顾名思义,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 才能跨域(需要后端在responseheader 中带上 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 的了解也只是冰山一角,希望对你有所帮助。

猜你喜欢

转载自blog.csdn.net/HYNN12/article/details/115391854
今日推荐