Метеор - автоматическое обновление холста с подписанными данными?
Мне может быть что-то не хватает, но кажется, что "волшебство" Метеор вращается вокруг привязки данных к элементам DOM и обновляет фрагменты текста и HTML через дескрипторы: http://docs.meteor.com/#reactivity
Это замечательно, однако, когда вы пытаетесь написать приложение метеорита, которое отображает данные в реальном времени на <canvas> элемент, я не могу понять "метеорный путь" для обновления моего холста, когда текущие данные изменяются, поскольку полотно заполняется с помощью JS-кода, например:
var g = canvas.getContext('2d')
g.fillRect(x, y, w, h)
а не текст с поддержкой данных в шаблоне HTML.
Я пытаюсь использовать холст, используя данные из Meteor.Collection.
Моя единственная мысль заключалась в том, чтобы внедрить JS-код canvas-рисунка в шаблон HTML в теге script, заполненном символами руля, но это кажется неправильным, поскольку события meteor и код привязки данных уже являются клиентской JS.
Есть ли способ прослушивания живых изменений данных, который запускает рисование на холсте через JS вместо HTML-элементов/текста?
Пожалуйста, дайте мне знать, если я каким-то образом проясню вопрос.
Update:
Том ответил ниже, заметив Meteor.deps, которые хотят выполнить произвольный код в реактивном контексте:
http://docs.meteor.com/#on_invalidate
Я попробую это и обновит здесь, если это сработает.
Ответы
Ответ 1
Это работает:
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()
})
}
Ответ 2
Возможно, ответ на ваш вопрос - использовать Collection.observe
(http://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
})
Ответ 3
У меня возникли проблемы с обновлением холста, поэтому я создал эту простую игровую демонстрацию:
https://github.com/randompast/Meteor-SimpleGame