2014-02-20 160 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