2014-02-20 58 views
0

我正在为使用cordova的android开发混合javascript应用程序。
在下面的代码中,我使用了两种在画布上绘制图像的方法:使用setTimeout和不使用。
Android设备上的以下代码(用cordova包裹)不​​会对func1做出反应,但会对func2做出反应。第二次点击func1最后在画布上绘制图像。 这是完全奇怪的。javascript canvas不绘制图像

我认为它与Android设备的性能有关,因为在我的台式电脑上这两个功能都能正常工作。

为什么会发生这种情况?如何避免使用setTimeout?

<html style="background: white;"> 
<head> 
</head> 
<body> 
<button onclick="func1()">render img2 func1</button> 
<button onclick="func2()">render img2 func2</button><br /> 
<canvas id="canv">canv</canvas> 

<script> 
    var img = new Image(); 
    var canvas = document.getElementById('canv'); 
    canvas.width = 100; 
    canvas.height = 100; 
    var ctx = canvas.getContext("2d"); 

    function setSrc() { 
     img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAASUlEQVRo3u3PAQ0AIAwDsIGC+TcLLkhOWgddSU6Ga5udT4iIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi8cQEjUgGTmE6z3QAAAABJRU5ErkJggg==" 
    }; 

    function drawImg() { 
     ctx.drawImage(img, 0, 0, canvas.width, canvas.height); 
    }; 

function func1() { 
    setSrc(); 
    drawImg(); 
}; 

function func2() { 
    setSrc(); 
    setTimeout(function() { 
     drawImg(); 
    }, 500); 
}; 

</script> 
</body> 
</html> 

回答

1

这并不奇怪,因为图像加载是异步的。您正试图在加载之前绘制图像。在第二次单击图像已加载,因此它将被绘制。

你需要使用一个回调机制,以使这项工作:

function setSrc(callback) { 
    img.onload = callback; /// when image is loaded this will be called 
    img.src = 'data: ...snipped...'; 
}; 

function drawImg() { 
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height); 
}; 

然后稍微修改你的函数:

function func1() { 
    setSrc(drawImg); /// drawImg is now callback function for setSrc. 
}; 

注意:如果需要,例如绘制在上面的东西你必须从回调函数中继续你的代码。例如,为drawImg函数添加一个回调函数,在绘制图像后调用代码中的下一步。这是因为如上所述,图像加载是异步的,如果您在图像加载之前尝试绘制任何其他图像,图像将被绘制在顶部而不是

+0

令人惊叹! thx,男人! – 31415926