反复绘制将图像更新到画布上(Safari在加载期间将图像空白) [英] Drawing repeatedly updating images to the canvas (Safari blanks out image during loading)

查看:50
本文介绍了反复绘制将图像更新到画布上(Safari在加载期间将图像空白)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将图像绘制到画布的背景上。该图像每秒刷新一次,但是每隔0.5秒刷新一次画布的次数就更多了。我似乎遇到的问题是,在更新画布时Safari会闪烁,因为它似乎丢失了bgImg变量中的图像数据。 Firefox可以正常工作,并且不会发生闪烁。

I'm drawing an image onto the background of a canvas. This image refreshes every second, but the canvas needs to be redrawn more often than that, every 0.5 seconds. The problem I seem to be running into is that Safari flickers when updating the canvas because it appears to lose the image data from the bgImg variable. Firefox works as expected and no flicker occurs.

有人对如何避免这种情况有任何线索吗?我是否错过了一些明显的东西?

Does anyone have any clue as to how to avoid this? Am I missing something really obvious?

要测试此代码,只需将下面的整个代码粘贴到html文件中,然后使用浏览器加载即可。它应该做的是:

To test this code, simply paste the entire code below into an html file and load with your browser. What it should do is:


  • 创建画布

  • 每次加载一张图片第二

  • 以图像为背景,每500毫秒重画一次画布。

这里是代码:

<html>
<head>
<script type="text/javascript">
var bgImg = new Image();
var firstload = false;
var cv;
var ctx;

var updateBackground = function() {
    bgImg.onload = function() {
      firstload = true;
      console.log("image loaded. Dimensions are " + bgImg.width + "x" + bgImg.height);
    }
    bgImg.src = "http://mopra-ops.atnf.csiro.au/TOAD/temp.php?" + Math.random() * 10000000;
    setTimeout(updateBackground, 1000);
  }

  var initGraphics = function() {
    cv = document.getElementById("canvas");
    ctx = cv.getContext("2d");
    cv.width = cv.clientWidth;
    cv.height = cv.clientHeight;
    cv.top = 0;
    cv.left = 0;  
  }

  var drawStuff = function() {
    console.log("Draw called. firstload = " + firstload );
    ctx.clearRect(0, 0, cv.width, cv.height);
    if ( firstload == true) {
      console.log("Drawing image. Dimensions are " + bgImg.width + "x" + bgImg.height);
      try {
        ctx.drawImage(bgImg, 0, 0);                
      } catch(err) {
        console.log('Oops! Something bad happened: ' + err);
      }
    }
    setTimeout(drawStuff, 500);
  }

  window.onload = function() {
    initGraphics();
    setTimeout(updateBackground, 1000);
    setTimeout(drawStuff, 500);
    }
    </script>

    <style>
body    {
   background: #000000;
   font-family: Verdana, Arial, sans-serif;
   font-size: 10px;
   color: #cccccc;
   }

.maindisplay {
       position:absolute;
       top:    3%;
       left:   1%;
       height: 96%;
       width: 96%;
       text-align: left;
    border: 1px solid #cccccc;
}
       </style>
</head>
<body>
<div id="myspan" style="width: 50%">
<canvas id="canvas" class="maindisplay"></canvas>
</div>

</body>
</html>


推荐答案

您的问题是您正在绘制 bgImg 正在加载。 Webkit在加载新图像时不会缓存旧图像数据;设置新的 .src 后,它将擦除图像。

Your problem is that you are drawing bgImg while it's loading. Webkit does not cache the old image data while loading a new image; it wipes out the image as soon as a new .src is set.

您可以使用两个来解决此问题图片,使用最后一个有效加载的图片进行绘制,而下一个加载的图片进行绘制。

You can fix this by using two images, using the last-valid-loaded one for drawing while the next one is loading.

我在此处在线提供了一个示例: http://jsfiddle.net/3XW8q/2/

I've put an example of this online here: http://jsfiddle.net/3XW8q/2/

简化堆栈溢出后代:

var imgs=[new Image,new Image], validImage, imgIndex=0;

function initGraphics() {
  // Whenever an image loads, record it as the latest-valid image for drawing
  imgs[0].onload = imgs[1].onload = function(){ validImage = this; };
}

function loadNewImage(){
  // When it's time to load a new image, pick one you didn't last use
  var nextImage = imgs[imgIndex++ % imgs.length];
  nextImage.src = "..."+Math.random();
  setTimeout(loadNewImage, 2000);
}

function updateCanvas(){
  if (validImage){ // Wait for the first valid image to load
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    ctx.drawImage(validImage, 0, 0);
  }
  setTimeout(updateCanvas, 500);
}

这篇关于反复绘制将图像更新到画布上(Safari在加载期间将图像空白)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆