2011-08-11 127 views
9

我正在玩HTML5中的canvas元素,我注意到了一个奇怪的行为。在初始加载时,我显示的图像不显示。但是,当我刷新浏览器时,它会适当地显示。我使用过IE9和Chrome。两者表现一致。 JavaScript代码如下所示:为什么图像不显示在载入中,而是在刷新时显示?

window.onload = load; 
function load() { 
    var canvas = document.getElementById("canvas"); 
    var context = canvas.getContext("2d"); 
    context.fillRect(0, 0, 640, 400); 
    var image = new Image(); 
    image.src = "Images/smiley.png"; 
    context.drawImage(image, 50, 50); 
} 

矩形正确绘制两次,它的笑脸,只显示在浏览器中刷新。

我正在学习HTML5和JavaScript的过程。我确信我只是在做一些愚蠢的事情,但我无法弄清楚。

回答

17

图像异步加载,所以只有刷新后加载足够早,因为它被缓存。通常在您致电drawImage时尚未加载。使用onload

var image = new Image(); 
image.src = "Images/smiley.png"; 
image.onload = function() { 
    context.drawImage(image, 50, 50); 
}; 
+0

谢谢。我知道这很简单。 –

3

这事与我,以及(仅针对IE9对我来说)反正,我发现了一个简单的解决方案。

将画布的背景设置为您希望显示的初始图像。

var canvas = document.getElementById("canvas"); 
canvas.style.background="url('image.png')"; 

这应该工作!

+0

我刚刚意识到的pimvdb可能是一个更好的方法。 – Jacob

0

其实,即使只是用image.onload = function() {},你仍然会碰到的问题。请使用这种技术(根本不是我所说的),而是将其移至页面的底部。

举个例子,我有一个使用画布来显示个人资料照片(URI存储到数据库),并打印到画布上,然后覆盖标志社交网站。

<section id="content"> 
    <article id="personalbox" > 
     <h2>Hi! My name is {profile_name}</h2> 
     <a id="friendbutton" href=""><img src="views/default/images/friend.png" width="12" height="12" /><span>Add {profile_name} as a friend?</span></a> 
     <video id="profilevideo" width="240" height="144">DEBUG: Video is not supported.</video> 
     <canvas id="profilecanvas" width="240" height="144" >DEBUG: Canvas is not supported.</canvas> 
     <a id="gallerytextlink" href="gallery.html" >Click to visit {profile_name} Gallery</a> 
     <table id="profileinfotable1"> 

...

</section> 

<script type="text/javascript"> 
    function init() { 
    var cvs = document.getElementById("profilecanvas"); 
    var ctx = cvs.getContext("2d"); 
    var img = new Image(); 
    img.src = "uploads/profile/{profile_photo}"; 
    img.onload = function() { 
     // Ignore. I was playing with the photo. 
     ctx.drawImage(img, 42, 32, 186, 130, cvs.width/2 - (186-42)/2, cvs.height/2 - (130-32)/2, 186-42, 130-32); 
     drawLogo(cvs,ctx); 
    } 
    } 

    function drawLogo(cvs,ctx) { 
    var logo   = "Enter Logo Here."; 
    ctx.fillStyle  = "rgba(36,36,36,0.6)";   
    ctx.strokeStyle = "rgba(255,255,255,0.3)"; 
    ctx.font   = "bold italic 6pt Serif"; 
    ctx.textAlign  = "left"; 
    ctx.textBaseline = "middle" ; 

    ctx.save(); 
    ctx.strokeText(logo, 4, cvs.height-11); 
    ctx.strokeText(logo, 6, cvs.height-11); 
    ctx.strokeText(logo, 4, cvs.height-9); 
    ctx.strokeText(logo, 6, cvs.height-9); 
    ctx.fillText(logo, 5, cvs.height-10); 
    ctx.restore(); 
    } 

    window.onload = init; 
</script> 

理想的情况下,这将一路底部的结束</body>标记之前,但我把它更高,因为我的模板系统。很显然,这会在canvas元素被拖拽到屏幕上并准备好接收输入之后给图像加载时间。

我不能依赖设置画布的背景,而且我也不想与刷新相抗衡。无论出于何种原因,只包括img.onload = function() {}的脚本是不够的。把它调低一点,为自己节省头痛。