Canvas fillRect函数忽略await问题求助:图片填充样式未生效
问题分析
你的问题核心在于在图片加载完成前就尝试创建填充图案(Pattern),这时候Canvas无法从尚未加载完成的Image对象生成有效的填充样式,导致后续fillRect只能使用默认的黑色。
具体来说,你的setFillStyle函数中,在调用img.src = src后立刻执行了this.context.createPattern(img, repeat)并赋值给fillStyle——但此时图片还在加载过程中,Image对象还没有可用的像素数据,所以生成的Pattern是无效的。只有当图片刚好被缓存、瞬间加载完成时,这个操作才碰巧能成功。
解决方案
要解决这个问题,你需要等到图片加载完成后,再创建Pattern并设置fillStyle,而不是提前设置。修改后的代码如下:
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') { this.context.fillStyle = value; return Promise.resolve(); // 保持统一的Promise返回格式 } return new Promise((resolve, reject) => { const img = new Image(); // 处理跨域图片(如果你的图片来自其他域名) img.crossOrigin = 'anonymous'; img.onload = () => { // 图片加载完成后再创建Pattern并设置fillStyle const pattern = this.context.createPattern(img, repeat); this.context.fillStyle = pattern; resolve({ src }); }; img.onerror = () => reject({ src }); img.src = src; }); }
关键修改点
- 颜色类型统一返回Promise:原本颜色分支直接返回赋值语句,现在改为
Promise.resolve(),确保setFillStyle始终返回Promise,避免async/await出现异常。 - 延迟创建Pattern:将
createPattern和fillStyle的赋值移到img.onload回调内,确保只有当图片完全加载、具备像素数据后,才生成有效的填充样式。 - 添加跨域处理:如果你的图片来自外部域名,需要设置
img.crossOrigin = 'anonymous',否则可能触发跨域错误导致图片加载失败(根据实际场景选择是否保留)。
额外注意事项
- 可以考虑给图片添加缓存逻辑,避免重复加载同一图片资源,提升性能。
- 如果需要处理多个图片加载的场景,可以使用
Promise.all()来批量处理,确保所有资源加载完成后再进行绘制操作。
内容的提问来源于stack exchange,提问作者SUBHUMAN
相关产品推荐
相关产品推荐

