canvas繪圖之跨域報錯問題


  首先說下需求,一張海報圖片於一張前端生成的二維碼繪制出一幅海報來,二維碼生成的本質就是一張canvas,此時我們可以利用toDataURL方法將這張二維碼轉成base64 

接着創建一個img標簽  讓其src等於這個base64,接着海報和二維碼就放在了兩張圖片中了,到了這步大家是不是覺得大功告成了可以美滋滋的畫圖了,豈不知一波坑就此襲來了~~~

  第一個錯如下。。。。

  Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

  什么意思呢  其實由於同源策略的原因canvas被污染了,無法使用toDataURL去導出canvas的數據 

 

  此時有的小伙伴可能想到了,去設置跨域屬性img.setAttribute("crossOrigin",'anonymous');這個屬性吧,然后興高采烈的去嘗試發現還不行~~~~

 

 

所以這時候就要找你服務端小哥哥了,問下你們服務器是否設置被允許訪問了

 

 

 

到了這里大家肯定覺得終於行了,然后一試。。。。滿屏紅的跨域報錯信息又出來了。。。。此時來自一枚程序員無聲的吶喊掙扎中~~~

  多次掙扎后終於找到解決方案 src屬性后面拼接一個時間戳就可以了!!!

內心反復不相信,多次嘗試后還真是這么狗就能出來~~~

 

function drawRoundRectPath(cxt, width, height, radius) {
  cxt.beginPath(0);
  //從右下角順時針繪制,弧度從0到1/2PI  
  cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
  //矩形下邊線  
  cxt.lineTo(radius, height);
  //左下角圓弧,弧度從1/2PI到PI  
  cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
  //矩形左邊線  
  cxt.lineTo(0, radius);
  //左上角圓弧,弧度從PI到3/2PI  
  cxt.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
  //上邊線  
  cxt.lineTo(width - radius, 0);
  //右上角圓弧  
  cxt.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);
  //右邊線  
  cxt.lineTo(width, height - radius);
  cxt.closePath();
}

function fillRoundRect(cxt, x, y, width, height, radius, fillColor) {
  //圓的直徑必然要小於矩形的寬高          
  if (2 * radius > width || 2 * radius > height) { return false; }
  cxt.save();
  cxt.translate(x, y);
  //繪制圓角矩形的各個邊  
  drawRoundRectPath(cxt, width, height, radius);
  cxt.fillStyle = fillColor || "#000"; //若是給定了值就用給定的值否則給予默認值  
  cxt.fill();
  cxt.restore();
}


const canvasQr = (posterCanvas, qrCanvas, poster, qrCodeCanvas, setImgW) => {//下載圖片地址和圖片名
  return new Promise((resolve, reject) => {
    try {
      const posterCtx = posterCanvas.getContext('2d');
      const qrCtx = qrCanvas.getContext('2d');
      const img1: any = new Image();
      const img2: any = new Image();
      const newimg1: any = new Image();
      img1.setAttribute('crossorigin', 'anonymous')
      img1.src = poster + "?" + new Date().getTime();
      img1.onload = () => {
        setImgW({
          width: img1.width,
          height: img1.height
        })
        qrCtx.drawImage(img1, 0, 0, img1.width, img1.height);
        newimg1.src = qrCanvas.toDataURL();
        newimg1.onload = () => {
          posterCtx.drawImage(qrCanvas, 0, 0, img1.width, img1.height);
          //帶圓角的白色矩形
          fillRoundRect(posterCtx, img1.width - (img1.width / 3) - 18, img1.height - (img1.width / 3) - 40, (img1.width / 3), (img1.width / 3), 20, '#fff');
          img2.src = qrCodeCanvas.toDataURL();
          img2.onload = () => {
            posterCtx.drawImage(img2, img1.width - (img1.width / 3) - 8, img1.height - (img1.width / 3) - 30, (img1.width / 3) - 20, (img1.width / 3) - 20);
            resolve(posterCanvas.toDataURL())
          };
        }
      }
    } catch (error) {
      reject("error")
    }

  })

}

export default canvasQr

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM