html2canvas的踩坑之路

html2canvas的踩坑之路

前言

早有耳闻这个html2canvas比较坑,但无奈于产品需求的压迫,必须实现html转图片的功能,自此走上了填坑之路,好在最后的效果还算使人满意,这才没有误了产品上线周期.css

html2canvas介绍

html2canvas的详细介绍能够点击这里查看,其实简单来讲就是经过canvasHTML生成的DOM节点绘制到画布上,再能够经过本身的需求转换成图片.因此官方文档也说了,最后生成的效果不是100%相同的,这一点你们要有心理准备,不管怎样,一点点小瑕疵是确定有的。html

兼容性

 

PS:微信浏览器使用也是没有问题的哦

 

使用html2canvas

使用也是十分简单,官网写的很清楚戳这里前端

踩坑过程

生成的图片里面为何缺失微信头像或其余图片?

其实涉及到的就是跨域问题,即使是canvas的画布中对于图片的域也是有要求的,那咱们应该怎么解决呢?node

  1. html2canvas配置项中配置 allowTaint:true 或 useCORS:true(两者不可共同使用)
  2. img标签增长 crossOrigin='anonymous'
  3. 图片服务器配置Access-Control-Allow-Origin 或使用代理

其中第三步是最重要的,不设置则前两步设置了也无效。git

服务器须要配置Access-Control-Allow-Origin信息,如PHP添加响应头信息,*通配符表示容许任意域名:github

header("Access-Control-Allow-Origin: *"); 

或者指定域名:web

header("Access-Control-Allow-Origin: www.zhangxinxu.com"); 

但若是不想麻烦后端的人员,那咱们前端怎么跨域呢? 那就可使用代理插件,如: html2canvas-proxy-nodejs 或者是 superagent,我是使用superagent,贴一下示例代码:canvas

const request = require('superagent') // 导入 const proxHost = 'https://thirdwx.qlogo.cn' // 指定跨域图片的地址 app.use('/proxy', function (req, res, next) { let urlPath = req.url console.log('urlPath', urlPath) urlPath = decodeURI(urlPath) if (!urlPath) { console.log('urlPath is null') return next() } console.log('proxy-request: /proxy->' + `${proxHost}${urlPath}`) const reqStream = request.get(`${proxHost}${urlPath}`) reqStream.on('error', function (err) { console.log('error', err) }) console.log('------reqStream----') return reqStream.pipe(res) }) 

那么最终我在页面中的图片的srchttps://thirdwx.qlogo.cn/xxx 要更改成/proxy/xxx 效果图以下:后端

 

 

2.生成的图片模糊不清且有锯齿瑕疵怎么办?

大部分找到的结果都是使用设备像素比去操做,但实际使用起来,仍是会有锯齿。 这个问题苦恼了我好久,而且找了好久的相关资料,总算是功夫不负有心人,让我找到了解决方案,在github里有大神已经提供了解决方案,能够点击这里,大神在源码的基础上增长两个配置项,scaledpi,推荐使用scale参数。跨域

源码位置:https://github.com/eKoopmans/html2canvas/tree/develop/dist

let imgHeight = window.document.querySelector('.content').offsetHeight // 获取DOM高度 let imgWidth = window.document.querySelector('.content').offsetWidth // 获取DOM宽度 let scale = window.devicePixelRatio // 获取设备像素比 html2canvas(window.document.querySelector('.content'), { useCORS: true, scale: scale, width: imgWidth, height: imgHeight }).then((canvas) => { window.document.querySelector('.content').remove() let elemImg = `<img src='${canvas.toDataURL('image/png')}' id='canvas-img' style='height: ${imgHeight}px;border-radius: 10px;width:${imgWidth}px'/>` window.document.querySelector('.container').innerHTML = elemImg }) 

最终生成出来的图片,是清晰而且最接近DOM的图片

3.生成的图片中若包含二维码,微信长按图片偶现没法识别?

 

这个问题主要出如今使用单页面框架(如VUE)的页面. 感谢  sundaypig提出的解决方案。 很简单,就是不使用路由切换,使用 window.location.href直接跳转刷新页面

 

location.href="www.abc.com/share/xxx" 

PS:这个问题能够解决全部页面中偶现二维码没法识别的状况

4.生成的图片中文字间距较大?

这个暂时没法完美解决,能够尝试用css属性:letter-spacing来设置字间距

相关文章
相关标签/搜索