2012-10-22 50 views
4

我正在尋找關於如何在動畫時保持客戶端同步的想法。我正在嘗試使用流星來構建基於瀏覽器的提詞器。我有基本的功能,我可以設置字體大小&滾動速度,但我還沒有想出一個可靠的方法來保持所有的客戶端在滾動開始後同步。如何讓流星客戶保持同步? (動畫)

到目前爲止,我已經嘗試了兩種方式,兩種都是工作,但都不是完美的。

我的第一個想法是在服務器上運行一個更新Collection的位置的間隔。這在局域網上運行良好,但是一旦我移動到互聯網,更新與客戶端觀察到的更新之間的滯後時間導致滾動停頓。下面是看起來像什麼代碼:

服務器:

if(Meteor.isServer){ 
    Meteor.methods({ 
     start_scroll: function(){ 
      interval = Meteor.setInterval(function() { 
       var _speed = Prompter.findOne({_var:"prompter_speed"})._val; 
       Prompter.update({_var:"prompter_y"}, {$inc:{_val:(-1*_speed/4)}}); 
      }, 30); 
     }, ... 
} 

客戶:

if(Meteor.isClient){ 
    Prompter.find({_var: "prompter_y"}).observe({ 
     changed: function(pos){ 
      $("#inner_scroll").css({top: pos._val}); 
     } 
    }); 
} 

上述版本的主要問題是,在觀察更新任何延遲會導致動畫口吃。所以,我決定在客戶端做動畫。以下是我想出了是:

服務器:

if(Meteor.isServer){ 
    Meteor.methods({ 
     start_move: function(){ 
      Prompter.update({_var:"prompter_move"},{$set:{_val:1}}); 
     }, ... 
} 

客戶:

if(Meteor.isClient){ 
    Prompter.find({_var: "prompter_move"}).observe({ 
     changed: function(obj){ 
      if(obj._val == 1){ 
       interval = Meteor.setInterval(function(){ 
        var cp = parseFloat($("#inner_scroll").css("top")); 
        var sp = parseInt(Session.get("_speed")); 
        var mv = cp + (-1 * sp)/4; 
        $("#inner_scroll").css("top", mv); 
       }, 30); 
      } 
      else{ 
       Meteor.clearInterval(interval); 
      } 
     } 
    }); 
} 

動畫是與此版本的客戶端上非常流暢,但(由於延遲觀察「開始」更新)客戶端可能不會同時啓動,因此不同步。我注意到的另一個問題是,一些較慢的客戶端(在CPU性能方面)使用該版本滾動較慢。

我在這個撓我的頭,有什麼建議嗎?

回答

5

我最終使用時間戳比較來保持一切同步。當服務器收到更新請求時,它會創建一個時間戳。時間戳與更新的數據一起傳遞,因此客戶可以將時間戳與「現在」進行比較並相應地進行調整。

仍然對其他建議開放,但這對我來說工作得很好。