我正在将图像加载到我的albImg数组中。
在我的循环中我然后这样做:
for(var j = 1; j < albImg.length; j++){
if(albImg[j].complete == true && albImg[j].width > 0){
loadedimages++;
}
}
确保我的所有图片都已加载。 然后我调用我的flipImg()函数:
if(loadedimages == albImg.length-1){
flipImg();
}
然后我翻转图像和
ctx2.save();
ctx2.scale(-1, 1);
for (var i = RszSpriteCount; i < sprites.length; i++) {
ctx2.drawImage(albImg[sprites[i][0]], sprites[i][1], sprites[i][2], sprites[i][3], sprites[i][4], 0 - (sprites[i][1] + sprites[i][3]), sprites[i][2], sprites[i][3], sprites[i][4]);
}
ctx2.restore();
var flipSz = albImg.length;
albImg[flipSz] = new Image();
albImg[flipSz].src = cnv2.toDataURL();
这是我的问题开始的地方。
我创建的新图像 - albImg [5] - 在加载之前无法显示。 但它的创建好像已经加载了一样。
也就是说:
albImg [5] .width已经设置(到750)才能显示它。 albImg [5] .complete设置为true,然后才能显示它。 albImg [5] .onload = ctx.drawImage(albImg [5],0,0);将尝试在加载之前绘制图像。
如何在显示之前检查我的翻转图像是否真的已加载?在Javascript?
(由于我没有使用jQuery的情况)
请帮忙。
答案 0 :(得分:2)
您的主要错误在于如何设置onload
事件处理程序:
albImg[5].onload = ctx.drawImage(albImg[5], 0, 0)
会将drawImage()
(undefined
)的返回值设置为onload
侦听器。
你想要的是
albImg[5].onload = e => ctx.drawImage(albImg[5], 0, 0);
或
albImg[5].onload = function(){ ctx.drawImage(this, 0, 0) };
对于设置为true的complete
和width
属性,这是因为虽然图像的加载总是异步,但在您的情况下,图像可能已经是HTTP缓存。
由于HTTP加载和javascript执行不在同一个线程上执行,因此可能在浏览器返回其属性之前实际加载了Image。
但即便如此,onload事件也会触发(最好在src
之前设置它。)
var cacher = new Image();
cacher.onload = function(){
var img = new Image();
img.onload = function(){
console.log('"onload" fires asynchronously even when cached');
};
img.src = c.toDataURL();
console.log('cached : ', img.complete, img.naturalWidth);
}
cacher.src = c.toDataURL();
console.log('before cache :', cacher.complete, cacher.naturalWidth);
<canvas id="c"></canvas>
因此,在处理新图像(不是html标记中的图像)时,请始终只听取其onload
事件。
现在,由于您在问题中提供的信息很少,您似乎甚至不需要这些图像,也不需要处理任何加载(当然除了精灵),因为您可以直接和同步拨打ctx.drawImage(CanvasElement, x, y)
。
const ctx = c.getContext('2d');
ctx.moveTo(0, 0);
ctx.lineTo(300, 75);
ctx.lineTo(0, 150);
ctx.fillStyle = 'rgba(120,120,30, .35)';
ctx.fill();
const flipped = c.cloneNode(); // create an offscreen canvas
const f_ctx = flipped.getContext('2d');
f_ctx.setTransform(-1, 0,0,1, c.width, 0);// flip it
f_ctx.drawImage(c,0,0);// draw the original image
// now draw this flipped version on the original one just like an Image.
ctx.drawImage(flipped, 0,0);
// again in 3s
setTimeout(()=>ctx.drawImage(flipped, 150,0), 3000);
<canvas id="c"></canvas>