Vue 中使用html2canvas实现截图并解决svg元素偏移的问题

一:下载依赖

yarn add html2canvas
yarn add canvg@2.0.0-beta.1 canvas@^2 jsdom@^13 xmldom@^0.6.0

二:文件中引入

import html2canvas from 'html2canvas'
import canvg from 'canvg'

三:截图的方法

// 截图
    infoScreenshot () {
      setTimeout( ()=> {
        let refId = this.$refs.printMe
        this.infoSvg(refId)
        const options = {
          type: 'dataURL',
          useCORS: true,
        }
        html2canvas(refId, options).then((canvas) => {
          let base64ImgSrc = canvas.toDataURL('image/png')
          //this.imgSrcUrl = base64ImgSrc
          let type = "image/png";
          this.dialog1Data.fileList = this.base64ToBlob(base64ImgSrc, type)
        })
      }, 100)
    },

    // 转换
    base64ToBlob (urlData, type) {
      let arr = urlData.split(',');
      let mime = arr[0].match(/:(.*?);/)[1] || type;
      // 去掉url的头,并转化为byte
      let bytes = window.atob(arr[1]);
      // 处理异常,将ascii码小于0的转换为大于0
      let ab = new ArrayBuffer(bytes.length);
      // 生成视图(直接针对内存):8位无符号整数,长度1个字节
      let ia = new Uint8Array(ab);
      for (let i = 0; i < bytes.length; i++) {
        ia[i] = bytes.charCodeAt(i);
      }
      return new File([ab], this.downloadName + getCurrentDateTime() + ".png", {
        type: mime
      });
    },

四:处理svg元素偏移的问题

// SVG处理
    infoSvg (refId) {
      let svgDom = Array.from(refId.getElementsByTagName('svg'))
      svgDom.forEach( function (node) {
        //获取svg的父节点
        let parentNode = node.parentNode;
        //获取svg的html代码
        let svg = node.outerHTML.trim();
        //创建一个<canvas>,用于放置转换后的元素
        let canvas = document.createElement('canvas');
        //将svg元素转换为canvas元素
        canvg(canvas, svg);
        //设置新canvas元素的位置
        canvas.style.transform = node.style.transform
        //删除svg元素
        parentNode.removeChild(node);
        //增加canvas元素
        parentNode.appendChild(canvas);
        setTimeout(function () {
          //删除canvas元素
          parentNode.removeChild(canvas);
          //增加svg元素
          parentNode.appendChild(node);
        },500)
      })
    }

五:时间处理(非必要,可去除)

Date.prototype.DateFormat = function (fmt) {
  var o = {
    'M+': this.getMonth() + 1, // 月份
    'd+': this.getDate(), // 日
    'h+': this.getHours(), // 小时
    'm+': this.getMinutes(), // 分
    's+': this.getSeconds(), // 秒
    'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
    'S': this.getMilliseconds() // 毫秒
  };
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
  }
  for (var k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
  }
  return fmt;
}

function getCurrentDateTime(fmt) {
  if (fmt == null || fmt == '') {
    fmt = 'yyyy-MM-dd hh:mm:ss';
  }
  return new Date().DateFormat(fmt)
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值