为什么图片在页面加载时不显示,但刷新后会显示?

11

我正在使用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。我相信我只是做了些愚蠢的事情,但我想不出来。

3个回答

19

图片会异步加载,所以只有在刷新后它才能很早地加载,因为它已被缓存。通常在调用drawImage时它还没有被加载。使用onload

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

谢谢。我知道这是一件简单的事情。 - John Kraft

3

我也遇到过这个问题(只在IE9上),不过我找到了一个简单的解决方案。

将画布的背景设置为你想要显示的初始图像即可。

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

应该可以运行!


我刚意识到可能有更好的方法。 - Jacob

1
实际上,即使只是使用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> 标签前的最底部,但由于我的模板系统,我将其放在了更高的位置。显然,这样做可以让图片在画布元素被绘制到屏幕上并准备好接收输入后再加载。

我不能依赖设置画布的背景,也不想处理刷新问题。由于某种原因,仅仅包含带有 img.onload = function() {} 的脚本是不够的。将其移到较低的位置,可以避免头痛的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接