javascript動畫、運動演算法詳細解釋與分析 (二、javascript動畫 時間精度問題)

來源:互聯網
上載者:User

三、時間精度問題

首先我們必須知道出現時間精度問題的原因。

如果你對javascript單線程機制不太熟悉,或者對setInterval、setTimeOut函數執行機制不太理解,希望你能先看一下這篇文章:How JavaScript Timers Work [Copy]。然後你可以看一下這篇文章http://icolin.org/javascript/settimeout-bug-in-ie-with-winxp.html。第一篇文章可以協助你理解javascript單線程機制以及setInterval、setTimeOut函數的執行機制,第二篇文章中 iColin 童鞋已經對時間精度問題出現的情況作了詳細的描述,他和我們在這裡的問題是一樣的,所以我就不再複述。最後一定要看 Omiga 的 再談JavaScript時鐘中的16ms精度問題 這篇文章。

(希望你確實看了那三篇文章,這樣你才能更加容易的理解下面的內容)

那麼現在相信你對問題出現的原因已經理解的差不多了,我在這裡再做一下小結:

javascript動畫在瀏覽器中啟動並執行過程中會產生時間誤差,誤差由系統內容,瀏覽器環境,程式運算時間,以及其他人為原因造成(我們這裡排除人為錯誤導致的誤差)。那麼系統內容包括電腦硬體、電腦作業系統,瀏覽器環境包括瀏覽器核心、javascript解釋引擎等,程式運算時間雖然有時可以忽略,但程式卻可能由於javascript的單線程機製造成時間延遲。所以如果想把時間精確到毫秒,那是很有難度的,jQuery也考慮到了這個問題,所以她採用了訊息佇列機制來盡量的消除這種誤差,不過效果差強人意。因為程式本身的時間精度就很難控制,所以如果使用程式本身來控制時間精度,那就好像拿油滅火。。。因為有很多不可抗力因素和外力因素影響。所以我們暫且將動畫時間精確到秒。

這裡對時間精度問題的討論就先到這裡,如果你有更好的解決方案,非常非常希望你能給予指導,非常非常感謝。

 

在這裡我們順便順便解釋一下上次遺留的 (這裡為什麼是以6px/30ms的速度等下解釋) 這個問題。

首先要說一下Tween演算法,我是從 cloudgamer 的 http://www.cnblogs.com/cloudgamer/archive/2009/01/06/tween.html這篇文章中看到了Tween演算法,進而在 robertpenner 的《Flash_MX編程與創意實現》中看到的非常細緻的講解。網址: http://www.robertpenner.com/easing/ 。如果想搞Flash創意和動畫的朋友推薦看這本書,我看了一部分,講得不錯,網上對這本書的評論也很好,我這裡有PDF中文版的,需要的跟我聯絡。

在Flash中,動畫時間長度都是以幀為單位來計算的。每幀時間長度*幀數就是動畫總時間。在我們javascript中,我們的幀時間長度實際上就是setInterval、setTimeOut的第二個參數。而幀數就是

   1:  Math.prototype.linearTween = function( t, b, c, d){
   2:       return t*c/d + b;
   3:  }

上面linear演算法中的d和t(d表示總幀數,t表示已經經過的幀數)。

所以如果你就像最開始那樣單純的認為t是時間,可能你就會陷入像我一樣的痛苦的迷茫中,半天不能自拔。我們再來複習一下這段代碼。

   1:  $ = function( id ){ return typeof id == "string"?document.getElementById(id):id }
   2:   
   3:  /* des:tween演算法。
   4:      t: 動畫已經執行的時間(實際上時執行多少次/幀數)
   5:      b: 起始位置
   6:      c: 終止位置
   7:      d: 從起始位置到終止位置的經過時間(實際上時執行多少次/幀數)*/
   8:  tween = {
   9:      linear : function( t, b, c, d){
  10:          return t*c/d + b;
  11:      }
  12:  }
  13:   
  14:  move={
  15:      moveType : function(mvTp){return  mvTp && typeof(mvTp)== ”string” && tween[mvTp] ? mvTp: "linear" },
  16:   
  17:      startMove : function( mvObj,mvTp,t,b,c,d ){ 
  18:          t ? t : t=0; b ? b : b = 0; c ? c : c =300; d ? d : d = 50; 
  19:          $(mvObj).style.position =="relative" || $(mvObj).style.position =="absolute" 
  20:              ? 1 : $(mvObj).style.position = "relative";
  21:          //每隔30毫秒重複執行改變元素位置的函數
  22:          mvTimer = setInterval(function(){
  23:          //判斷動畫已經執行的時間(次數/幀數)是否小於總時間,是的話繼續執行改變位置的函數,否則的話,清理該interval。
  24:              t <= d 
  25:                  ? function(){ $(mvObj).style.left = parseInt(tween[move.moveType(mvTp)](t,b,c,d))+"px"; t++;}() 
  26:                  : clearInterval(mvTimer); 
  27:          } ,30 ) 
  28:      }
  29:  }
  30:   
  31:  move.startMove("moveLinear");

在這裡我們動畫的幀數是d=50,經過幀數為t,當t<=d時,繼續執行動畫,每幀的時間間隔是30毫秒,該元素將從距離視窗左邊距為0的位置移動到距離視窗左邊距為300的位置(這裡忽略body的預設margin)。

今天先到這裡,下次將會接著分析Tween演算法,我將盡最大努力來經曆這個有意思的東西。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.