html2canvas图片模糊解决方案
html2canvas官方的配置介绍
ViewPort布局方案
页面采用ViewPort
方案,解决iOS上的1px的边框问题,采用这个方案,在iOS上渲染出来的Dom会自动乘以devicePixelRatio
,因此iOS上的Canvas相当于被直接放大了,没有出现模糊的情况。
var viewport = document.querySelector("meta[name=viewport]");
var deviceRatio = window.devicePixelRatio || 1;
var scale = 1.0/deviceRatio;
viewport.setAttribute('content', 'width=device-width,initial-scale='+scale + ', maximum-scale='+scale+', minimum-scale='+ scale +', user-scalable=no');
发现#id
锚点异常,是因为CSS的属性text-size-adjust
在作怪,导致,关掉即可。
-webkit-text-size-adjust: 100%;
安卓也想采用ViewPort方案,发现会引入更多的问题,首先是text-size-adjust
导致的布局异常问题,可以通过关闭所有设备上的text-size-adjust
解决
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
但是依旧会发现在某些设备上有布局问题,还有因为这个text-size-adjust
导致的闪动问题,以及滑动卡顿问题(devicePixelRatio
太大了导致原始dom的尺寸太大渲染不流畅)。找了一圈后发现手淘的使用Flexible实现手淘H5页面的终端适配在安卓上的这个值始终认为是0,看来是不好走通了。
其中initial-dpr会把dpr强制设置为给定的值。如果手动设置了dpr之后,不管设备是多少的dpr,都会强制认为其dpr是你设置的值。在此不建议手动强制设置dpr,因为在Flexible中,只对iOS设备进行dpr的判断,对于Android系列,始终认为其dpr为1。
到这里iOS不用任何配置直接使用Html2Canvas
就可以画出清晰的图了。
安卓还需要另外适配。
图片模糊问题
html2canvas
一开始用的最新版本,发现dom在屏幕之外的部分始终无法绘制,调了半天最后换了个版本(往下降了一个版本)直接就好了。目前项目中使用的是1.0.0-alpha.12
。
"html2canvas": "^1.0.0-alpha.12"
- 设置html2canvas的选项
const html2canvasOpts = {
backgroundColor: null,
useCORS: $fn.isDev(),
allowTaint: $fn.isDev(),
scale: window.devicePixelRatio || 1,
ignoreElements: (element) => {
if(element.className.indexOf('no-share-element') > -1){
return true;
}
return false;
},
copyStyles: true,
removeContainer: true
}
主要是scale
,需要引入devicePixelRatio
,即可保证canvas清晰。
- 不要使用
background-image:url()
属性,实验发现用这个属性渲染出来的图片都很糊,用img标签就好了。
其他问题
跨域问题
由于涉及到外源图片,目前是通过后台写了一个接口做图片下载后pipe()来解决的,在开发环境的时候直接打开跨域和允许污染Canvas的属性
useCORS: $fn.isDev(), //允许跨域
allowTaint: $fn.isDev(), //允许污染画布
这样在开发环境只能看到Canvas却无法调用canvas.toDataURL("image/png");
函数。
正式环境将所有的图片替换成接口调用,使之同源
if(!isDev()){
coverUrl = '/api/fetchImage?src='+encodeURIComponent(coverUrl);
}
接口层代码,express侧
//使用http或者https或者request库直接请求,然后直接
response.pipe(res)
注意需要白名单和各种过滤规则,否则就是典型的ssrf了。