使用image.onload时Canvas图片加载/渲染顺序异常求助
问题:Canvas图片加载时序导致的图层显示异常
我尝试将一张图片加载到HTML Canvas上,再在该图片上方加载另一张图片,但各浏览器出现如下异常表现:
Chrome:
- 首次执行 - 仅显示背景图(backImage),但加载过程中有一瞬间字符图(charImage)在背景图后方可见。
- 刷新时 - 有时字符图显示在背景图上方,有时则相反,无规律可循。
- 注:将代码直接插入浏览器控制台时,表现符合预期(背景图在下方,字符图在上方)。
Firefox:
- 首次执行 - 仅显示背景图(backImage),但加载过程中有一瞬间字符图(charImage)在背景图后方可见。
- 刷新后 - 某次刷新后(及后续所有刷新),表现恢复符合预期(背景图在下方,字符图在上方)。
我了解到可使用.onload事件且已在代码中使用,但仍存在疑似时序问题。本人刚接触编程,恳请各位提供建议,谢谢!
// Create Canvas var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); canvas.width = 512; canvas.height = 480; document.body.appendChild(canvas); // Background Image var backImage = new Image(); backImage.onload = function(){ ctx.drawImage(backImage,0,0); }; backImage.src = "Images/Flowers.jpg"; // Character Image var charImage = new Image(); charImage.onload = function(){ ctx.drawImage(charImage,0,0,50,50); }; charImage.src = "Images/Butterfly.jpg";
解决方案:确保图片加载的时序和绘制顺序
问题核心是图片加载为异步操作——两张图的加载完成时间不确定,谁先加载完就先执行对应的onload绘制代码。如果字符图先加载完成,会先被绘制到画布上,之后背景图加载完成再绘制时就会把字符图盖住;反之则字符图显示在上方,这就是浏览器表现不稳定的原因。
以下两种方法可以解决这个问题:
方法1:嵌套加载,保证绘制顺序
将字符图的加载逻辑放到背景图的onload回调中,确保背景图先绘制完成,再加载并绘制字符图:
// Create Canvas var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); canvas.width = 512; canvas.height = 480; document.body.appendChild(canvas); // Background Image var backImage = new Image(); backImage.onload = function(){ ctx.drawImage(backImage,0,0); // 背景绘制完成后再加载字符图 var charImage = new Image(); charImage.onload = function(){ ctx.drawImage(charImage,0,0,50,50); }; charImage.src = "Images/Butterfly.jpg"; }; backImage.src = "Images/Flowers.jpg";
方法2:等待所有图片加载完成后统一绘制
适合需要加载多张图片的场景,用计数器记录已加载完成的图片数量,当所有图片都加载完成后,再按预设顺序绘制:
// Create Canvas var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); canvas.width = 512; canvas.height = 480; document.body.appendChild(canvas); var backImage = new Image(); var charImage = new Image(); var loadedImageCount = 0; // 通用加载完成回调 function onImageLoaded() { loadedImageCount++; // 两张图都加载完成后按顺序绘制 if (loadedImageCount === 2) { ctx.drawImage(backImage, 0, 0); ctx.drawImage(charImage, 0, 0, 50, 50); } } backImage.onload = onImageLoaded; charImage.onload = onImageLoaded; // 设置图片地址 backImage.src = "Images/Flowers.jpg"; charImage.src = "Images/Butterfly.jpg";
内容的提问来源于stack exchange,提问作者BrittanyL
相关产品推荐
相关产品推荐

