vue2 使用 html2Canvas 和 canvg 生成图片案例

一、安装插件

npm install html2canvas

npm install canvg

html2canvas 将页面保存在canvas进行图片保存 

canvg 将页面中的svg转化为canvas

1、关于canvg

1.1 启动canvg引擎

  • new Canvg(...)
  • Canvg.from(...)
  • Canvg.fromString(...)

from和fromString的区别是from需要传入的是svg本身,而fromString需要传入的是svg的字符串形式。这三种方式都可以传入三个参数,第一个参数是canvas画布的绘制上下文,第二个是需要绘制的svg,第三个是自定义配置选项,可以用于控制画布的渲染结果。

1.2 canvg启动渲染的方法有两种:renderstart

区别是当需要绘制的svg是动态图时,render只会绘制第一帧的内容,也就是说绘制出来的图像是静态的,而start是会将svg的内容以及动效全部都绘制出来,也就是说图片是动态的形式。

二、引入插件

import html2canvas from 'html2canvas';

import { Canvg } from 'canvg'

三、使用

<div class="svg-box">

    <svg class='svg' width="100%" height="100%" viewBox="0 0 200 200" ref="svg">
              
       <!-- 外圈圆 -->
       <circle cx="100" cy="100" r="90" stroke="#dcdcdc" stroke-width="10" fill="none" />

       <!-- 内圈圆,虚线用于展示进度 -->
       <circle cx="100" cy="100" r="90" stroke="#ff0000" stroke-width="10" fill="none" :stroke-dasharray="Math.PI*45 +','+ 2*Math.PI*90" :stroke-dashoffset="0" stroke-linecap="round" transform="rotate(-90,100,100)"></circle>
              
    </svg>
            
</div>
this.$nextTick(async () => {
      
      const parentNode = this.$refs.svg.parentNode;
      const svg = this.$refs.svg.outerHTML.trim();
    
      let canvasDom = document.createElement('canvas')
      let ctx = canvasDom.getContext('2d')
      canvasDom.setAttribute('width', this.$refs.svg.clientWidth+'px')
      canvasDom.setAttribute('height', this.$refs.svg.clientHeight+'px')
      canvasDom.setAttribute('style', 'display:block;')

      document.body.appendChild(canvasDom)

      const v = Canvg.fromString(ctx, svg);
      await v.render();
    
      parentNode.removeChild(this.$refs.svg);
      parentNode.appendChild(canvasDom);


      html2canvas(this.$refs.imgDom, {
            useCORS: true // 允许CORS跨域
      }).then((canvas) => {
        this.imgUrl = canvas.toDataURL("image/png")
        
        // 触发图片下载
        const aElem = document.createElement('a')
        document.body.appendChild(aElem)
        aElem.href = this.imgUrl
        // 设置下载标题
        aElem.download = "chart.jpg"
        aElem.click()
        document.body.removeChild(aElem)
      });
      
})

四、兼容问题

1.背景图片模糊
解决方案:使用img标签来实现background-image的效果

2.图片无法渲染
在img标签内加入crossorigin=‘anonymous’(crossorigin='anonymous’可以触发带跨域请求头Origin的HTTP请求)并给html2canvas设置allowTaint: true配置

3.跨域加载的图片会污染canvas,进而导致canvas无法导出数据

解决方案1:给html2canvas设置useCORS:true加载跨域图像的配置,并且保证给每个图片添加添加crossOrigin="anonymous"属性


解决方案2:将文件读入到blob文件对象,然后用URL.createObjectURL()方法转换成img src可用的地址,然后再转canvas


注意:读入blob文件时保证要设置的img标签内的src为空,在读入文件完成后在调用生成图片函数 

// 将文件读入到blob文件在转img的方法
function getImage ( url ) {
    const xhr = new XMLHttpRequest();
    xhr.open('get', url, true);
    xhr.responseType = 'blob';
    xhr.onload = function () {
        if (this.status == 200) {
            this.imgUrl =  URL.createObjectURL(this.response);
        }
    };
    xhr.send();
    
}

let urltest = '跨域图片链接'

getImage(urltest,'test-img')

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值