I might be missing something, but it seems that Meteor's "magic" revolves around binding data to DOM elements, and updating text and HTML fragments via handlebars: http://docs.meteor.com/#reactivity
This is great, however, when trying to write a meteor app that displays live data in a <canvas> element, I cannot figure out the "meteor way" to update my canvas when the live data changes, since the canvas is populated via JS code like:
var g = canvas.getContext('2d')
g.fillRect(x, y, w, h)
and not data-backed text in the HTML template.
I am trying to draw on the canvas using data from a Meteor.Collection.
My only thought was to embed canvas-drawing JS code in the HTML template in a script tag populated by handlebar vars, but this seems wrong since meteor's events and data-binding code is already client-side JS.
Is there some way listen for live data changes, which triggers drawing on the canvas via JS instead of HTML elements/text?
Please let me know if I can clarify the question in some way
Update: Tom's answer below made me notice Meteor.deps, which look to allow executing arbitrary code in a reactive context: http://docs.meteor.com/#on_invalidate
I will try this out and update here if it works.
Perhaps the answer to your question is to use Collection.observe
(http://docs.meteor.com/#observe) and trigger the relevant redrawing code in the various callbacks.
For instance, something like:
Rectangles.observe({
added: function(rect) {
var g = canvas.getContext('2d');
g.fillRect(rect.x, rect.y, rect.w, rect.h);
},
// etc
})
This works:
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()
})
}
I had some trouble with updating the canvas so I created this simple game demo: https://github.com/randompast/Meteor-SimpleGame
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With