javascript - 使用 Canvas 在 promise 内裁剪图像不起作用

标签 javascript canvas promise es6-promise

我正在尝试使用 Canvas 裁剪多个图像,并且我想在裁剪完所有图像后运行一些其他功能。

这是我 promise 的裁剪图像功能

const checkImage = url => {
  return new Promise(resolve => {
    const workingURL = url;
    const canvas = document.createElement('canvas');
    canvas.width = 200;
    canvas.height = 200;
    const ctx = canvas.getContext('2d');  
    img = new Image();
    img.setAttribute('crossOrigin', '');
    img.onload = function(){
      var w = img.width;
      var h = img.height;

      var rw = 200;
      var rh = 200;

      if (w > h) {
        var ar = (w / h).toFixed(2);
        var dar = (200/h);
        rw = Math.floor(w * dar);
      } else if (h > w) {
        var ar = (h / w).toFixed(2);
        var dar = (200/w);
        rh = Math.floor(h * dar);
      }

      var sx = 200 / 2 - rw / 2;
      var sy = 200 / 2 - rh / 2;
      console.log(sx, sy, rw, rh);
      console.log(img);
      ctx.drawImage(img,sx,sy, rw , rh);
      var s = canvas.toDataURL();
      console.log('done cropping ', url, s);
      resolve({url: workingURL, res: s});
    }
    img.onerror = (err) => {
      console.log('onload error ',err);
      resolve({url: workingURL, res: false});
    };
    img.src = url;
  });
}

现在我需要调用几个图像,因此我对每个图像调用 Promise

cropImageForGIFFn = () => {
  const needCropImgs = [
    {
      "src": "https://s3.amazonaws.com/tech-turing/event-images/ydgPwb28ThtgeATC8/img-Hrc7otKvJZTg6D5Rp.png",
    },
    {
      "src": "https://s3.amazonaws.com/tech-turing/event-images/ydgPwb28ThtgeATC8/img-ZAnRMDHfAGz2Xe9oX.png",
    },
  ];
  const needCropImgsLen = needCropImgs.length;
  let resolvedPromises = 0;

  needCropImgs.forEach(function (imgInfo) {      
    checkImage(imgInfo.src).then((info) => {
      console.log('promise resolved');
      console.log(info);

      resolvedPromises += 1;
      if (resolvedPromises === 1) {
        document.getElementById('img1').src = info.res;
      }

       if (resolvedPromises === 2) {
        document.getElementById('img2').src = info.res;
      }
      console.log({resolvedPromises});
      if (resolvedPromises >= needCropImgsLen) {
        console.log('all are resolved');
      }
    });
  });
};

我正在检查所有 promise 是否已解决,然后调用其他函数。

如果我将多个图像发送到我的 Promise 函数,如果我只发送一个图像,则第一个图像将变为透明,然后一切正常。

如果我评论任何图像,则裁剪效果很好。

我在这里创建了Codepen https://codepen.io/sasikanth1/pen/rQjxXL

尝试注释 needCropImgs 的数组值之一,然后图像将正常显示。

最佳答案

错别字
您在 img 声明之前忘记了 constletvar

   img = new Image();
 // ^- scope leak

这意味着所有异步回调中的 img 变量将引用最新声明的 Image()。如果最后一个图像没有在其他图像之前加载,这确实可能会导致一些透明的结果。

因此,只需添加此关键字即可。

关于javascript - 使用 Canvas 在 promise 内裁剪图像不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53277556/

相关文章:

javascript - Laravel 和 jquery 中删除文件的问题

javascript - 正则表达式捕获组适用于 Javascript 和 regex101,但不适用于 sed

javascript - 我可以在 Canvas 中放置一个 HTML 按钮吗?

javascript - 如何在 Jade 中做复杂的条件或正则表达式

javascript - 表单包含某些文本时出现表单错误消息

javascript - ZoneAwarePromise 已在 Meteor 上被覆盖

javascript - 正确使用 async 和 wait

reactjs - 使用 React Native + Redux 获取数据不起作用

javascript - Canvas 。 AngularJS。添加文本和图像

javascript - 用数学旋转矩形