• html2canvas.js——HTML转Canvas工具


    概述:

    将HTML代码转化成Canvas,进而生成图片

    使用场景:

    动态生成海报的需求,html2canvas.js就是一款优秀的插件,它可以轻松地帮你将HTML代码转换成Canvas,进而生成可保存分享的图片

    使用:

    布局

    <div id="qianduanwz" ref='teamShare'>
      <img src="./images/qrcode.jpg" alt="" @load="qrcodeLoad" />
      <p>学习Web前端<br>关注前端微站</p>
    </div>
    

      

    <style>
      #qianduanwz{  900px; height: 383px; text-align: center; background: 
        url("./images/bg.jpg") no-repeat center;}
      #qianduanwz img{  200px; margin-top: 60px;}
      #qianduanwz p{ margin: 0; padding-top: 10px; font-size: 20px; color: #fff;}
    </style>
    

    转换Canvas并导出图片

        async creatImage() {
          const el = this.$refs.teamShare
          const options = {
            type: 'dataURL',
            useCORS: true,
            // backgroundColor: '#00a560',
          }
          this.output = await this.$html2canvas(el, options)  将元素和配置项传入
        },
    

    可能出现的问题及相应解决方案

    ① 图片模糊问题

    有时候我们会发现,导出的图片局部有些图片看起来没有原图那么清晰,这其实是因为你使用背景图片的原因。解决方法也很简单,就是直接使用<img>标签就好了(比如上面示例中的背景图最好是用<img>来替代)。

    ② 图片不显示问题
    有时你可能莫名其妙地发现有些图片并没有出现在导出的图片中,这基本上就是因为图片素材出现跨域,也就是说图片所在的域名与你项目所在域名不一致。这个问题的解决方案就是html2canvas使用时多加以下两个配置项就好了。
    allowTaint: true,
    useCORS: true 
    

      

    ③ PNG图片不透明问题

    有时你可能用到透明的PNG图片作为背景图,可是结果最后生成的图片却并不透明,这是因为html2canvas生成的canvas背景颜色默认为白色的缘故,所以导出的图片背景颜色当然也是白色。

    解决方案也是添加一个配置项就好(事实上经实验发现只要是非颜色类型的字符串都可以)。

    backgroundColor: "transparent"
    
    ④ 在iOS系统部分浏览器中,用<br>标签进行文字换行时,文本只显示第一行的问题
    这种现象并不是必现的,但确实存在这样的问题,这时解决问题的方式也很简单,就是不用<br>标签来换行,而是采用其他块级标签元素对需要进行换行的文字分别包裹即可。
    例如:
    想学习前端,<br>可关注微信公众号:前端微站  
    可写成:
    <ul>
        <li>想学习前端,</li>
        <li>可关注微信公众号:前端微站</li>
    </ul>
    

      

    重点总结

    ① 生成图片的HTML尽量使用<img>而不使用背景图
    ② { allowTaint: true, useCORS: true }可解决跨域图片不显示问题
    ③ { backgroundColor: "transparent" }可解决图片不透明问题
    

     

    html2canvas原理:

    一种是利用foreignObject,一种是纯canvas绘制

    1.foreignObject到canvas

    步骤:

      1.把要截图的dom克隆一份,过程中把getComputedStyle附上style

      2.放到svg的foreignObject中

      3.把svg序列化成img的src(SVG直接内联):

    img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(new XMLSerializer().serializeToString(svg));

      4.ctx.drawImage(img, ....)

    2.纯canvas

    步骤:

      1.把要截图的dom克隆一份,过程中把getComputedStyle附上style

      2.把克隆的dom转成类似VirtualDom的对象

      3.递归这个对象,根据父子关系、层叠关系来计算出一个renderQueue

      4.每个renderQueue Item都是一个虚拟dom对象,根据之前getComputedStyle得到的style信息,调用ctx的各种方法

    总结:

      性能:如果文本多,节点少,svg foreignObject的方式往往性能更高;文本少,节点多的时候,canvas反而性能更高

      准确性:纯canvas方式往往更准确的还原dom的表现;svg foreignObject在比较复杂的情况下会出现截图不准确的问题

    综上所述,建议使用纯canvas方式,但是注意要对文本进行限流!

    参考文章:https://juejin.im/entry/58b91491570c35006c4f7fdf

  • 相关阅读:
    JVM classloader
    面试整理
    工具配置链接
    IntelliJ IDEA 热部署
    IntelliJ IDEA 常用快捷键
    类文件结构
    判断对象存活的方法
    JVM 运行时数据区域
    vim编辑16进制
    阿里云yum源
  • 原文地址:https://www.cnblogs.com/jcxfighting/p/14087164.html
Copyright © 2020-2023  润新知