移动端 html2canvas 踩坑记录

背景

最近在作的微信 html5 项目有个需求:页面包含 一张大的背景图片 + 一个用户的连接二维码图片 拼成一张图片,让用户长按保存的时候,能够把整个页面都保存起来,而不是只保存二维码。php

思考

1.先后端哪一个实现方法会更高效html

虽然图片均可以从后台获取,可是一来须要 等待二维码生成->添加到大图上->转换成一张图片->传输,是一个同步过程,耗时比较久;二来看到网上的评价,后台使用的库生成的图片偶尔会出错,修改起来也麻烦。所以决定在前端完成。前端

2.使用 svg 仍是 canvasvue

考虑到移动端对 html5 新特性支持得比较好以及高分辨率屏幕,使用 svg 看起来很适合------若是没看到前辈的踩坑文章的话,会是这样的~~html5

根据 https://www.jianshu.com/p/458... 所说,步骤是 html-->svg-->canvas-->img ,问题出在使用跨域图片的时候:canvas

clipboard.png

也便是 iphone 系列都被拒之门外 ...后端

所以决定用 html2canvas 库,完成 html-->canvas-->img 的转变。如下是踩坑心得。跨域


坑一

图片模糊微信

此为想不到的坑,浪费了不少时间在代码检查上...app

图片描述

问题: html2canvas 渲染背景图片 background-image 会不清晰。

解决方法:使用 Img 标签。

坑二

高分辨率下,文字模糊

此为预料中的状况,获取了设备像素比 window.devicePixelRatio 百分比伸展 canvas 画布便可......才怪......

而后发现这是 0.5 版本须要作的操做,1.0 版本的默认参数 scale 已经设置好了,但仍是不太清晰。

最后从同事处获得启发,最终解决方法是!!

一概设为 4 倍!即

html2canvas(ele, {
    sacle: 4
}).then((canvas) => {});

简单粗暴...虽然图片体积所以变大了...

坑三

IOS 下,几率性出现大图绘制不出来的状况

对于这个需求,本来的操做是在 img 标签里的 src 属性写上大图连接,在 activated() 里生成二维码再建立新的 img 标签附到大图里(用的 vue)。在 IOS 上,常常出现页面上只有背景颜色和二维码的图片的状况。

缘由: 大图还未下载完毕即开始了绘制。

解决方法: 给 img 添加 onload 事件,下载完毕再调用绘制方法。

坑四

html 元素的隐藏

由于是要让用户长按保存整个页面,因此用 html2canvas 将全部内容转成图片。而其并不能绘制隐藏的内容,所以须要先显示页面,在图片生成后再隐藏。在 vue 里就是 v-show 的值的变化过程。

问题: 页面会有闪烁,再显示图片

解决方法: 组件直接设为 v-show = false,html2canvas 添加参数 onclone ,生成一个复制的虚拟组件,设置为显示,便可获取进行绘制,且虚拟组件不会显示在页面上。

html2canvas(ele, {
    onclone(doc) {
        let e = doc.querySelector('#wrapper');
        e.style.display = 'block';
    }
}).then((canvas) => {});

其余坑

图片高度

问题: UI 只给了一张图片,宽度能够稍微拉伸,高度在全面屏下会不足以覆盖整个屏幕,漏出白底;强制设置为屏幕高度图片会失真。

解决方法: 让 UI 帮忙别把图片底部设计得五光十色,只保留一种颜色。而后将页面的背景颜色设为同种颜色便可。

二维码图片的位置定位

问题: 如何让二维码图片在不一样屏幕下都定位到正确的位置。

解决方法: 设为绝对定位,使用屏幕宽度做为基准设置 left、top 值。

.qr {
    width: 32vw;
    position: absolute;
    left: 16vw;
    top: 97vw;
}

图片跨域等

其余更多相似图片跨域等问题能够参考如下两篇文章:

http://www.php-master.com/pos...

https://www.jianshu.com/p/458...

相关文章
相关标签/搜索