11

我可能遗漏了一些东西,但似乎 Meteor 的“魔法”围绕着将数据绑定到 DOM 元素,并通过把手更新文本和 HTML 片段:http: //docs.meteor.com/#reactivity

这很棒,但是,当尝试编写一个在 <canvas> 元素中显示实时数据的流星应用程序时,我无法弄清楚当实时数据更改时更新我的​​画布的“流星方式”,因为画布是通过 JS 填充的代码如:

var g = canvas.getContext('2d')
g.fillRect(x, y, w, h)

而不是 HTML 模板中的数据支持文本。

我正在尝试使用 Meteor.Collection 中的数据在画布上绘图。

我唯一的想法是将画布绘图 JS 代码嵌入 HTML 模板中由把手变量填充的脚本标记中,但这似乎是错误的,因为流星的事件和数据绑定代码已经是客户端 JS。

是否有某种方法可以监听实时数据更改,从而触发通过 JS 而不是 HTML 元素/文本在画布上绘图?

如果我能以某种方式澄清这个问题,请告诉我

更新: Tom 在下面的回答让我注意到 Meteor.deps,它看起来允许在反应式上下文中执行任意代码:http: //docs.meteor.com/#on_invalidate

如果可行,我将尝试并在此处更新。

4

3 回答 3

7

也许您的问题的答案是使用Collection.observehttp://docs.meteor.com/#observe)并在各种回调中触发相关的重绘代码。

例如,类似:

Rectangles.observe({
  added: function(rect) {
    var g = canvas.getContext('2d');
    g.fillRect(rect.x, rect.y, rect.w, rect.h);
  },
  // etc
})
于 2012-05-29T07:12:02.823 回答
5

这有效:

var Shapes = new Meteor.Collection('shapes')

if (Meteor.is_client) {
  // Function that redraws the entire canvas from shapes in Meteor.Collection
  function drawShapes() {
    var shapes = Shapes.find({})
    shapes.forEach(function(shape) {
      // draw each on canvas
    })
  }

  var startUpdateListener = function() {
    // Function called each time 'Shapes' is updated.
    var redrawCanvas = function() {
      var context = new Meteor.deps.Context()
      context.on_invalidate(redrawCanvas) // Ensures this is recalled for each update
      context.run(function() {
        drawShapes()
      })
    }
    redrawCanvas()
  }

  Meteor.startup(function() {
    startUpdateListener()
  })
}
于 2012-05-29T17:10:07.330 回答
1

我在更新画布时遇到了一些麻烦,所以我创建了这个简单的游戏演示: https ://github.com/randompast/Meteor-SimpleGame

于 2014-11-30T16:00:32.683 回答