使用html2canvas遇到的哪些坑

2,780 阅读4分钟

大家好,我是王大傻。最近各家公司都在秀自己的APP年度报告,我有幸做了我们公司这块的内容,那么有了报告必定有分享环节,在分享海报时通过使用html2canvas插件遇到了一些问题,特此来总结一下

问题汇总

  1. html2canvas生成海报后清晰度问题
  2. html2canvas无法生成页面里面带canvas元素的html
  3. html2canvas对某些css属性不支持问题

image.png

html2canvas生成海报后清晰度问题

话不多说,先投图两张 更改前: image.png 更改后: image.png 可以明显的看出我们更改前后确实发生了质的变化 那么是怎么一回事呢? 答案是这样的:

  • 更改前我们采用了背景引入的方法,通过background-image引入了图片资源 因此导致我们转化为canvas时候就会不清晰
  • 更改后我们采用了image定位+层级的方法,直接通过img标签将图片引入,并通过定位将我们图片准确定位到我们的视图中,通过层级展示为具体的背景效果 那么有朋友可能会说了,即便这样还是会不清晰呀?那么我们应该怎样做呢?
  1. 首先呢,我们需要了解的是为什么会导致这种不清晰
  2. 根据查看源码分析,我们在html2canvas最后得到的是一个base64图片,而canvas生成base64图片那显然是用了canvas.toDataUrl,话不多说,看文档

image.png 根据MDN的介绍,我们可以知道,这个api最高的质量只能保证到0.92,那么这么来说,我们是不是可以将页面中的图片元素质量提高从而达到,生成的image也随之提高的效果,等同于我们用时间换取清晰度了,我们需要做的就是将页面图片提高,并且在生成前将待生成的html预先设置为2倍宽高,从而使得页面整体放大2倍,因为生成后的是按我们原来宽高决定的,所以生成后我们又可以通过transform scale属性去手动的放缩我们的图片,从而达到清晰效果。

html2canvas无法生成页面里面带canvas元素的html

生成前 image.png 生成后 image.png

image.png 通过生成后的两种显示我们可以看出来canvas并没有被准确的生成出来。 那我们又是怎么解决的呢

image.png

image.png 对,就是你想的那样。我们也是通过canvas的toDataUrl的API去将canvas生成图片并渲染在html文档里,为了避免视觉差,我们将这一步放在了html2canvas前去进行渲染,等生成之后我们原封不动的将canvas标签还原

image.png

html2canvas对某些css属性不支持问题

这点可以通过上面的canvas图片观察到,生成前我们的html里面是有带毛玻璃效果的,生成后却没有了,原因是我们有原来的background更替成为了img,所以没显示了,那么如何让生成后的页面同样也有毛玻璃呢,在此,大傻猜想是不是可以用一个元素定位到图片上进行局部的高斯模糊,最后因为时间问题没有具体实施出来,在此对html2canvas的文档也进行了一些阅读,发现确实没去支持这样的操作。

image.png 特此,插入一个小插曲

高斯模糊

我们知道,毛玻璃效果在我们日常中不常用到,但是用到时候该怎么去做呢,起初,我和大家想的一样,直接用filter:blur() 去实现模糊,但实际情况是

image.png 确实是模糊了,但是我们的文字却没有模糊,我们的背景同样也没有,因此我们对方案进行一些改进, 我们使用 backdrop-filter:blur() 属性。

image.png 那么他就有了我们期望的效果。是不是很神奇·····具体的实现以及两者差异我们可以通过MDN去了解明白,filter是针对当前的容器进行一个模糊化效果,而backdrop则是对层级以后的内容进行模糊效果,之后我们就可以更开心的使用毛玻璃效果了~~

image.png