我正在使用cordova为Android开发混合javascript应用程序
在下面的代码中,我使用了两种在画布上绘制图像的方法:使用setTimeout
而不使用
Android设备上的以下代码(用cordova包装)不会对func1
做出反应,但会对func2
作出反应。第二次点击func1
最终在画布上绘制图像。
这完全是奇怪的。
我认为它与Android设备性能有关,因为在我的桌面PC上,两个功能都可以正常工作。
为什么会这样?如何避免使用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>
答案 0 :(得分: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函数添加一个回调函数,该函数在绘制图像后调用代码中的下一步。这是因为如上所述,图像加载是异步的,如果您在加载图像之前尝试绘制任何其他内容,则图像将被绘制在顶部而不是