javascript画布不绘制图像

时间:2014-02-20 16:02:20

标签: javascript android canvas cordova settimeout

我正在使用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>

1 个答案:

答案 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函数添加一个回调函数,该函数在绘制图像后调用代码中的下一步。这是因为如上所述,图像加载是异步的,如果您在加载图像之前尝试绘制任何其他内容,则图像将被绘制在顶部而不是