html2canvas使用中遇到的BUG(svg截图不显示)

使用html2canvas中有很多bug,影响最深刻的就是svg不显示,那怎么解决它呢?

我也是在网上找到一位老哥的最优解!!


逻辑: 先获取到svg节点,把这个svg元素用canvas元素替代,截图完成后删除canvas元素。

附上代码参考,当然我这里的大屏里面可能有很多svg,所以我要遍历svg数组,你们可以不用这样。

 下面是我项目导出截图的全部代码 ↓↓↓

    handleBUILD() {
      this.$nextTick(() => {

          //Svgdom数组
          let svgNodesToRemove = [];
          // 获取到所有的SVG得到一个数组
          let svgElements = document.body.querySelectorAll('#content .avue-echart-            
          progress svg');
          console.log(svgElements,'获取到的svg---')
          // 遍历这个数组
          svgElements.forEach(function(item) {
            console.log(item,'svg数据---')
            let children = item.childNodes
            console.log(children,'svgElements foreach::children')
            // 处理 SVG子节点  children 透明度
            children.forEach(function(child) {
              //解决svg透明度问题
              child.style.opacity = 1;
            })
            //去除空白字符
            let svg = item.outerHTML.trim();
            // 创建一个 canvas DOM元素
            let canvas = document.createElement('canvas');
            //设置 canvas 元素的宽高
            canvas.width = item.getBoundingClientRect().width;
            canvas.height = item.getBoundingClientRect().height;
            // 将 SVG转化 成 canvas
            canvg(canvas, svg);
            //设置生成 canvas 元素的坐标  保证与原SVG坐标保持一致
            if (item.style.position) {
              canvas.style.position += item.style.position;
              canvas.style.left += item.style.left;
              canvas.style.top += item.style.top;
            }
            //添加到 你需要截图的DOM节点中
            item.parentNode.appendChild(canvas);
            // 删除这个元素
            svgNodesToRemove.push(canvas)
            item.style.display = "none"
          });

        html2canvas(document.querySelector(".canvas"), {
          useCORS: true,
          backgroundColor: null,
          allowTaint: true,
        }).then((canvas) => {
          if(this.contain.nav.length != 0){
            //截取所有组件所在的矩形画布
            var croppedCanvas = document.createElement('canvas');
            var croppedCtx = croppedCanvas.getContext('2d');
            let x = this.position.x * this.zoomFactor;
            let y = this.position.y * this.zoomFactor;
            let width = this.position.width * this.zoomFactor;
            let height = this.position.height * this.zoomFactor;
            console.log(x,y,width,height,'我是要截取的位置');

            let rate = 258/180
            if( width/height > rate){
              // console.log('宽比高长得多');
              let changedHeight,yChange
              changedHeight = width/rate
              yChange = (changedHeight-height)/2
              y = y - yChange
              if(y < 0){
                y = 0 
              }else if(y + changedHeight > this.contain.config.height){
                y = this.contain.config.height - changedHeight
              }
              height = changedHeight
            }
            if( width/height < rate){
              // console.log('宽比高短得多');
              let changedWidth,xChange
              changedWidth = height * rate
              xChange = (changedWidth-width)/2
              x = x - xChange
              if(x < 0){
                x = 0 
              }else if(x + changedWidth > this.contain.config.width){
                x = this.contain.config.width - changedWidth
              }
              width = changedWidth
            }

            croppedCanvas.width = width * this.zoomFactor;
            croppedCanvas.height = height * this.zoomFactor;
            croppedCtx.scale(this.zoomFactor, this.zoomFactor);
            console.log("x, y, width, height",x, y, width, height);
            croppedCtx.drawImage(canvas, x, y, width, height, 0, 0, width, height);
          }
          function dataURLtoFile(dataurl, filename) {
            var arr = dataurl.split(","),
              mime = arr[0].match(/:(.*?);/)[1],
              bstr = atob(arr[1]),
              n = bstr.length,
              u8arr = new Uint8Array(n);
            while (n--) {
              u8arr[n] = bstr.charCodeAt(n);
            }
            return new File([u8arr], filename, {
              type: mime,
            });
          }
          if(this.contain.nav.length != 0){
            var file = dataURLtoFile(
              croppedCanvas.toDataURL("image/jpeg", 0.92),
              new Date().getTime() + ".jpg"
            );
          }else{
            var file = dataURLtoFile(
              canvas.toDataURL("image/jpeg", 0.92),
              new Date().getTime() + ".jpg"
            );
          }

            // 截取完成后
            // 删除 canvas 元素
            document.querySelectorAll("#content .avue-echart-progress             
            canvas").forEach(item => {
              item.remove()
            })
            let svgElements = document.body.querySelectorAll('#content .avue-echart- 
            progress svg');
            console.log(svgElements,'隐藏svgElements后重新获取到的svg');
            svgElements.forEach(function(item){
              item.style.display = 'inline-block'
            })

          var formdata = new FormData();
          formdata.append("file", file);
          console.log("360");
          console.log(this.contain);
          console.log(this.contain.obj);
          axios
            .post(this.url + "/upload/img", formdata, {
              headers: {
                "Content-Type": "multipart/form-data",
              },
            })
            .then((res) => {
              const data = res.data.data;
              const url = data.baseUrl + "/" + data.url;
              const formdata = {
                backgroundUrl: url,
                category: this.$route.query.category,
                config: {
                  component: JSON.stringify(this.contain.nav),
                  createTime: this.contain.obj.config.createTime,
                  detail: JSON.stringify(this.contain.config),
                  id: this.contain.obj.config.id,
                  updateTime: this.contain.obj.config.updateTime,
                  version: this.visial.version,
                  visualId: this.contain.obj.config.id,
                },
                createTime: this.contain.obj.createTime,
                createUser: this.contain.obj.createUser,
                // currentVersion: '',
                id: this.contain.obj.id,
                isDeleted: this.contain.obj.isDeleted,
                password: this.contain.obj.password,
                status: this.contain.obj.status,
                title: this.contain.obj.title,
                updateTime: this.contain.obj.updateTime,
              };
              return new Promise((resolve, reject) => {
                console.log("这边有有一个接口请求-------------");
                console.log(updateComponent);
                updateComponent(formdata).then((res) => {
                  console.log("接口处理请求成功回来");
                  console.log(res);
                  let data = res && res.data;
                  if (data.code == 401) {
                    reject();
                  } else {
                    resolve();
                  }
                });
              });
            })
            .then(() => {})
            .catch(() => {
              // this.$message.error('模版例子不能修改')
              loading.close();
            });
        });
      });

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值