zoukankan      html  css  js  c++  java
  • html2canvas的踩坑之路

    html2canvas的踩坑之路

    前言

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

    html2canvas介绍

    html2canvas的详细介绍可以点击这里查看,其实简单来说就是通过canvasHTML生成的DOM节点绘制到画布上,再可以通过自己的需求转换成图片.所以官方文档也说了,最后生成的效果不是100%相同的,这一点大家要有心理准备,无论怎样,一点点小瑕疵是肯定有的。

    兼容性

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

    使用html2canvas

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

    踩坑过程

    生成的图片里面为什么缺失微信头像或其他图片?

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

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

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

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

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

    或者指定域名:

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

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

    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,
                 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;${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来设置字间距

  • 相关阅读:
    eclipse中的Invalid text string (xxx).
    在jsp文件中出现Unknown tag (c:out)
    eclipse 界面复原
    ecilpse 纠错插件
    Multiple annotations found at this line:- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    Port 8080 required by Tomcat v9.0 Server at localhost is already in use. The server may already be running in another process, or a system process may be using the port.
    调用第三方https接口
    调用第三方http接口
    创建带值枚举
    spring整合redis之Redis配置文件
  • 原文地址:https://www.cnblogs.com/zhangycun/p/9247707.html
Copyright © 2011-2022 走看看