drawImage 绘制多张图片时层次顺序错乱

668 阅读1分钟

drawImage 绘制多张图片时层次顺序错乱

项目场景:

  • canvas绘制结果页分享图片

问题描述:

  • 目前需要使用 drawImage() 绘制多张图片

  • 在 canvas 中是没有 z-index 这个属性的,只有绘制早的图片会显示在底层,绘制的图片显示在顶层。

downImage(ctx, img, x, y, w, h, canvas) {
   let bgImg = new Image()
   bgImg.src = img
  img.onload = function () {
    //  绘制图片
    ctx.save()
    ctx.drawImage(bgImg, x, y, w, h)
    ctx.restore()
    _this.shareUrl = canvas.toDataURL('image/jpeg')
  };
}

根据上述代码,可以绘制多张图片在 canvas 标签当中,但是显示的层级会错乱。

原因分析:

  • 因为 img.onload 属于异步加载了,所以哪张图片加载快就绘制顺序靠前。

解决方案:

  • 在这个时候里,我们可以通过 Promise 对象返回一个同步的回调函数,让图片按顺序进行绘制。
downImage(ctx, img, x, y, w, h, canvas) {
  return new Promise((resolve) => {
    let bgImg = new Image()
    bgImg.src = img
    let _this = this
    bgImg.onload = function () {
      //  绘制图片
      ctx.save()
      ctx.drawImage(bgImg, x, y, w, h)
      ctx.restore()
      _this.shareUrl = canvas.toDataURL('image/jpeg')
      resolve(true)
    }
  })
}

解决图片跨域问题:

  • 本地图片绘制时正常,线上图片就报错 Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported 解决方法
  • 图片设置 :crossOrigin属性
downImage(ctx, img, x, y, w, h, canvas) {
  return new Promise((resolve) => {
    let bgImg = new Image()
    bgImg.src = img
    let _this = this
    // 增加`crossOrigin`属性
    bgImg.setAttribute('crossorigin', 'anonymous')
    bgImg.onload = function () {
      //  绘制图片
      ctx.save()
      ctx.drawImage(bgImg, x, y, w, h)
      ctx.restore()
      _this.shareUrl = canvas.toDataURL('image/jpeg')
      resolve(true)
    }
  })
}