2012-05-29 6 views
11

私は何かが足りないかもしれないが、流星の「魔法」がDOM要素に周りの結合データを公転しているようですし、ハンドルを経由して、テキストとHTMLの断片を更新:http://docs.meteor.com/#reactivityメテオ - 定期購読データでキャンバスを自動的に更新していますか?

書き込もうとしたときにこれは、しかし素晴らしいです

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

:キャンバスのようなJSコードを経由して移入されますので、<キャンバス>要素でライブデータを表示する流星アプリは、私は、とき、ライブデータの変更私のキャンバスを更新するために、「流星の道」を把握することはできませんHTMLテンプレート内のデータバックアップテキストではありません。

私は、Meteor.Collectionのデータを使用してキャンバスに描画しようとしています。

私の唯一の考えは、handlebar varsによって設定されたスクリプトタグのHTMLテンプレートにキャンバス描画のJSコードを埋め込むことでしたが、流星のイベントとデータバインディングコードはすでにクライアントサイドのJSなので、これは間違っています。

ライブデータの変更をリッスンする方法はありますか?HTML要素/テキストの代わりにJSを使用してキャンバスに描画されますか? トムの答えは以下の私は、反応性コンテキストで任意のコードの実行を許可するように見えるMeteor.depsを、気づく作っ: http://docs.meteor.com/#on_invalidate

私はいくつかの方法

アップデートで質問を明確にすることができます場合は私に知らせてください

これを試して、動作したらここで更新します。

+0

をこれがあなたが "スクリプトタグの埋め込み..."を意味するものかどうかは分かりません。 現在、私はキャンバスを含むテンプレートに{{drawCanvas}}を入れて、 "drawCanvas"という名前のTemplate.canvas.helperの一部である関数内のすべての描画を行います。この関数は何も返しません。レンダリングされますが、キャンバスを更新するように実行されます。それはあなたがすでに試みたことですか? Template.name.helperは、ReactiveDictやそれに応じて更新されるモデルに応じて自動的に反応します。 –

+0

このコメントの意味は、テンプレート内の文字列としてJSコードを動的に生成することでした。明らかに奇妙な)。私の答えは、実際に不条理な流星 – 7zark7

+0

で「正しい」方法と思われました。しかし、私の方法は大丈夫ですか?このアイデアは、何もしない非表示の{{drawCanvas}}を使用しているだけです。これは、反応的なデータが変更されたときに再実行されます(それによってキャンバスを再描画します)。 –

答えて

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() 
    }) 
} 
+1

これは動作します - ありがとう!私が個人的に探しているのは、起動時にのみ完全な再描画を行い、更新/追加/削除時にインクリメンタルな再描画を行うことです。スタートアップ/レンダリング時にのみこのようなことをする正しい方法はありますか?毎回更新する必要はありませんか? template.renderedの中にクエリを置くと、動作しないようです。 – semateos

+1

私が完全に再描画したのは、キャンバスが個々の図形の削除/更新をサポートしていないからです。 AFAIK、シェイプが重なっている場合は、キャンバス全体を再描画する必要があります。 – 7zark7

+0

@semateos Flash Display Listを模倣したPixi.jsのようなライブラリを使用することで、その動作を実現できます。 –

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 
}) 
+0

ありがとうございました、それを見ませんでした。私の特別な場合の1つの問題は、キャンバス全体を再描画する必要があることです(たとえば四角形を削除すると四角形を再描画する必要があります)。追加/削除/変更するだけでなく、クエリ結果全体が必要です。 – 7zark7

+0

確かに。私はあなたが持っているものは、それを行う正しい方法だと思います。私はMeteorがコンテキストを設定する簡単な方法を持っていた+と途中で無効化を扱うことを望みます。 –

関連する問題