如何在图像更改时将图像绘制到画布,而不是URI?

时间:2014-02-04 20:27:02

标签: javascript html5 image canvas

以下是我如何在画布上绘制图像的基本实现。

  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var imageObj = new Image();

  function drawImg(x, y) {
     imageObj.onload = function() {
       context.drawImage(imageObj, x, y);
     };
     imageObj.src = 'http://www.mysite.com/temp.jpg';
  }

我有一个服务器端图像渲染脚本,我将图像写入相同的文件位置,例如:“temp.jpg”。我正在使用Ajax在图像更改时提示浏览器,我运行该功能再次加载图像。但是,由于URL始终相同,因此加载的第一个图像将被缓存,并且永远不会重绘。

我找到了几种解决方案,但我不确定哪种方法效果最好,或者是真正的最佳解决方案。一些建议包括使用时间戳稍微操纵URL,我看到了一些对流的引用。

一些关键点:

  • 我不想清除画布,我希望最近的图像位于上一个图像的顶部,如果x,y坐标发生变化或图像尺寸不同,它应该是图层。< / LI>
  • 我真的不想为每个新图像更改图像文件名,这看起来有点过分。

谢谢。

编辑:

决定将我的github项目包含在我正在开发的socket.io版本中。我已经有大约5个不同的版本,但这是我主要追踪的版本。随意撕开它我确信在内存管理方面我有一些不好的做法。 https://github.com/Pwn9/tcp-io-bridge

3 个答案:

答案 0 :(得分:2)

IMO,最好的解决方案是添加时间戳(您可以添加一个随机值,只是为了确定)作为参数的图像。这避免了必须存储特定的变量计数器,并且非常容易实现。也许是这样的事情:

"?" + +new Date() + "_" + Math.random ()

您可能还想完全避免缓存,但如果您不将所有图像转换为canvas对象,则会出现问题,因为在大多数基于Webkit的浏览器中,如果在以下情况之间,则会禁用中间刷新图像缓存。页面缓存也被禁用..

[edit:]或者,换句话说,在基于Webkit的浏览器中,如果您使用Javascript重新加载某些内容并且标题显示“已过期”,则会重新请求该图像。在IE11和Firefox中,即使禁用了缓存,图像也会被缓存,直到页面刷新为止。

http://code.google.com/p/chromium/issues/detail?id=336292

答案 1 :(得分:1)

也许你可以大致这样做:

  var i = 0;

  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var imageObj = new Image();

  function drawImg(x, y) {
     imageObj.onload = function() {
       context.drawImage(imageObj, x, y);
     };
     imageObj.src = 'http://www.mysite.com/temp.jpg?' + i;
     i++;
  }

通过这种方式,您将获得以下网址列表:

这似乎会让Chrome发送网页请求,就好像你保持网址一样,根本不会发送网页请求。

我在Chrome中进行了测试,这确实会强制加载新图像。我还会将您的标题设置为不缓存该网址。

我正在测试其他一些浏览器。

答案 2 :(得分:1)

复杂表单页面存在缓存问题,其行为类似于小型单页面应用程序,我通常的解决方案是在响应上设置各种无缓存标头。这意味着您需要能够在Web服务器上配置它或在服务器端代码中进行配置。

这些是典型的跨浏览器标题:

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

有关服务器端代码示例,请参阅此答案: https://stackoverflow.com/a/2068407/2836187