pc端截屏踩坑记录(结合dom-to-image,html2canvas)

923 阅读1分钟

包含iframe,svg,video的处理 1.原图

image.png 2.截图

image.png 3.代码

  downloadImg=async ()=>{
    let svgElem = document.querySelectorAll("#canvasP svg");
    let videoElem=document.querySelectorAll("#canvasP video");
    let iframeElem=document.querySelectorAll("#canvasP iframe");
    //以下是对svg的处理
    svgElem.forEach((node,index)=>{
      let parentNode = node.parentNode;
      if(new XMLSerializer().serializeToString(node)){
        node.setAttribute('xmlns','http://www.w3.org/2000/svg')
        let img = new Image();
        let svghtml = new XMLSerializer().serializeToString(node);
        let imgsrc =`data:image/svg+xml;utf,${svghtml}`
        img.src=imgsrc;
        img.onload=function(){
          img.setAttribute('data-cover', 'svg');
          parentNode.removeChild(node);
          parentNode.appendChild(img);
        }
      }
    })
    //转换iframe
    this.changeIframe(iframeElem);
    setTimeout(async ()=>{
      //转换视频
      await this.changeVideo(videoElem);
      this.htmlToPng()
    },1500)
    // 还原视频
    function recoverCanvasToVideo(targetElem: { querySelectorAll: (arg0: string) => any; }, elems: any[] | NodeListOf<Element>) {
      let canvasElems = targetElem.querySelectorAll("canvas[data-cover='video']");
      if(!targetElem){
        throw new Error('must have targetElem param')
      }


      for(let i = 0; i < canvasElems.length; i++){
        let node = canvasElems[i], parentNode = node.parentNode;
        parentNode.removeChild(node);
        parentNode.appendChild(elems[i]);
      }
    }
    // 还原svg
    function recoverCanvasToSvg(targetElem: { querySelectorAll: (arg0: string) => any; }, elems: any[] | NodeListOf<Element>) {
      let canvasElems = targetElem.querySelectorAll("canvas[data-cover='svg']");
      if(!targetElem){
        throw new Error('must have targetElem param')
      }
      for(let i = 0; i < canvasElems.length; i++){
        let node = canvasElems[i], parentNode = node.parentNode;
        parentNode.removeChild(node);
        parentNode.appendChild(elems[i]);
      }
    }
    // 还原iframe
    function recoverCanvasToIframe(targetElem: { querySelectorAll: (arg0: string) => any; }, elems: any[] | NodeListOf<Element>) {
      let canvasElems = targetElem.querySelectorAll("img[data-cover='iframe']");
      if(!targetElem){
        throw new Error('must have targetElem param')
      }
      console.log(canvasElems)
      for(let i = 0; i < canvasElems.length; i++){
        let node = canvasElems[i], parentNode = node.parentNode;
        parentNode.removeChild(node);
        parentNode.appendChild(elems[i]);
      }
    }
    // @ts-ignore
    setTimeout(async ()=>{
      // @ts-ignore
      await recoverCanvasToIframe(document.querySelector('#canvasP'),iframeElem)  
        // @ts-ignore
      await recoverCanvasToVideo(document.querySelector('#canvasP'),videoElem)
      // @ts-ignore
      await recoverCanvasToSvg(document.querySelector('#canvasP'),svgElem)
    },2000)

  }
  htmlToPng=()=>{
    htmlToImage.toPng(document.querySelector('#canvasP'))
      .then(function (dataUrl) {
        let a = document.createElement('a');
        a.setAttribute('href', dataUrl);  //toDataUrl:将canvas画布信息转化为base64格式图片
        a.setAttribute('download', 'downImg');  //这个是必须的,否则会报错
        a.setAttribute('target', '_self');
        a.click()
      })
      .catch(function (error) {
        console.error('oops, something went wrong!', error);
      })
  }
  changeVideo= (videoElem: NodeListOf<Element>)=>{
    videoElem.forEach((node: CanvasImageSource, index: any)=>{
      let canvas = document.createElement("canvas");
      let ctx = canvas.getContext('2d');
      const img=new Image();
      img.src='require(/images/test.png)';
      ctx.drawImage(node, 0, 0, '100%', '100%');
      canvas.setAttribute('data-cover', 'video');
      node.parentNode.appendChild(canvas)
      node.parentNode.removeChild(node)
    })
  }
  changeIframe=(elem: CanvasImageSource[])=>{
    elem.forEach(async (node: CanvasImageSource, index: any)=>{
      let parentNode = node.parentNode;
      const img=new Image();
      await html2canvas(node.contentWindow.document.querySelector('#root'),{foreignObjectRendering:true,allowTaint:true,useCORS:true}).then(canvas => {
        const src = canvas.toDataURL('image/png');
        img.src=src;
        img.setAttribute('data-cover', 'iframe');
        parentNode.appendChild(img)
        parentNode.removeChild(node);
      })
    })
  }