首页 > 解决方案 > Canvas 的 fillRect 函数忽略等待

问题描述

我对fillRectcanvas 函数有疑问:我使用该setFillStyle函数将 设置fillStyle为 rgb 值或图像源。将使用图像的onload方法获取图像。因为我想确保下面的调用fillRect将使用 thisfillStyle我让它返回一个承诺,我将它的调用者设置为async和 awaiting setFillStyle

似乎fillRect忽略了await因为有时(当图像没有及时获取时)它#000000在整个画布上绘制颜色(这是默认值),而有时(当图像幸运地及时获取时)它绘制生成的模式图片。

async fillArea() {
  const { width, height } = this.context.canvas;
  await this.setFillStyle()
    .catch(({ src }) => console.error(`Failed to load image: ${src}`));
  this.context.fillRect(0, 0, width, height);
},
setFillStyle() {
  const { type, value = '', src = '', repeat = '' } = this.hideOptions;
  this.context.globalCompositeOperation = 'source-over';
  if (type === 'color') return this.context.fillStyle = value;
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve({ src });
    img.onerror = () => reject({ src });

    img.src = src;
    this.context.fillStyle = this.context.createPattern(img, repeat);
  });
},

我还尝试不使用async await并回退到.then不会导致不同行为的情况:

fillArea() {
  const { width, height } = this.context.canvas;
  this.setFillStyle()
    .catch(({ src }) => console.error(`Failed to load image: ${src}`))
    .then(() => this.context.fillRect(0, 0, width, height));
},

由于我无法解决这个问题,如何解决这个问题?

标签: javascriptcanvasasync-await

解决方案


这段代码的问题是我试图在实际获取图像之前创建模式。该createPattern函数默认使用#000000而不是图像来创建图案。

更正后的代码如下所示:

async fillArea() {
  const { width, height } = this.context.canvas;
  await this.setFillStyle()
    .catch(({ src }) => console.error(`Failed to load image: ${src}`));
  this.context.fillRect(0, 0, width, height);
},
setFillStyle() {
  const { type, value = '', src = '', repeat = '' } = this.hideOptions;
  this.context.globalCompositeOperation = 'source-over';
  if (type === 'color') return new Promise(resolve => resolve(this.context.fillStyle = value));
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => {
      this.context.fillStyle = this.context.createPattern(img, repeat);
      resolve(img);
    };
    img.onerror = () => reject({ src });
    img.src = src;
  });
},

推荐阅读