TypeScript圖形渲染實戰:2D架構設計與實現》 —3 動畫與Application類

      網友投稿 948 2022-05-30

      第2篇

      Canvas2D篇

      (? 第3章? 動畫與Application類

      (? 第4章? 使用Canvas2D繪圖

      第3章? 動畫與Application類

      本章將從程序實現的角度來了解一下動畫的原理,以及HTML 5提供的一些基礎且必要的方法。

      可以將動畫的相關功能都封裝到一個名為Application的類中,該類主要是作為應用程序的入口類。它能啟動或關閉動畫循環,抽象更新與重繪流程,提供事件分發和處理功能,并且具有一個允許以不同幀率運行的計時器。

      在開始本章內容前先聲明一下,本書所有的Demo以Chrome瀏覽器為主要測試環境,為簡單起見,本書并不關注各瀏覽器之間的兼容性。

      3.1? requestAnimationFrame方法與動畫

      從程序的角度來描述,筆者認為,動畫就是不間斷地、基于時間的更新與重繪。可以說這句話貫穿了本節要講的所有內容。

      3.1.1? HTML中不間斷的循環

      所謂不間斷的,是指動畫需要一個不停地重復循環機制,從程序實現的角度來說,一般有兩種選擇:

      一種是類似于while ( true ) { }之類的死循環,除非滿足退出死循環的條件,否則就一直不停地重復相同的行為。在Windows下的D3D / OpenGL開發中,經常使用這種模式來驅動動畫不斷運行。作為知識的延伸點,下面來看一段經典的Windows下基于C / C++語言的動畫循環演示代碼。若不感興趣可直接跳過。具體代碼如下:

      MSG msg ;

      ZeroMemory ( & msg , sizeof ( msg ) ) ;

      // 只有明確地收到WM_QUIT消息,才跳出while循環,退出應用程序

      // 否則一直循環重復相同的行為

      // Windows下經典的runLoop操作

      while ( msg . message != WM_QUIT )

      {

      《TypeScript圖形渲染實戰:2D架構設計與實現》 —3 動畫與Application類

      // 如果當前線程消息隊列中有消息,則取出該消息

      if ( PeekMessage ( & msg , NULL , 0U , 0U , PM_REMOVE ) ) {

      //將鍵盤的虛擬鍵消息轉換為WM_CHAR消息,并將WM_CHAR消息再次放入當前線程

      消息隊列中,下次還是可以被PeekMessage讀取并處理

      TranslateMessage ( & msg ) ;

      //將當前的WM_開頭的消息分發到Window 窗口過程處理回調函數中進行處理

      DispatchMessage ( & msg ) ;

      //上面的代碼實際就是處理鼠標、鍵盤、WM_PAINT,或者計時器等隊列消息

      } else {

      //如果當前線程消息隊列中(上面的代碼處理消息隊列)沒有消息可處理,就一直更新并重繪

      Update ( ) ; ?????????????????????????????????????????????? //更新

      Render ( ) ; ?????????????????????????????????????????????? //重繪

      }

      }

      另外一種是類似于定時器的回調,例如使用HTML DOM(Document Object Model,文檔對象模型)中Window對象的setTimeout、setInterval及requestAnimationFrame方法。關于setTimeout和setInterval的用法,請各位讀者自行查閱相關資料(在3.4節中將實現類似setTimeout和setInterval的功能)。下面主要來看一下requestAnimationFrame方法的用法。具體代碼如下:

      // start記錄的是第一次調用step函數的時間點,用于計算與第一次調用step函數的時間差,

      以毫秒為單位

      let start : number = 0 ;

      //lastTime記錄的是上一次調用step函數的時間點,用于計算兩幀之間的時間差,以毫秒為單位

      let lastTime : number = 0 ;

      // count用于記錄step函數運行的次數

      let count : number = 0 ;

      // step函數用于計算:

      // 1.獲取當前時間點與HTML程序啟動時的時間差 : timestamp

      // 2.獲取當前時間點與第一次調用step時的時間差 : elapsedMsec

      // 3.獲取當前時間點與上一次調用step時的時間差 : intervalMsec

      // step函數是作為requestAnimationFrame方法的回調函數使用的

      // 因此step函數的簽名必須是 ( timestamp : number ) => void

      function step ( timestamp : number ) : void? {

      // 第一次調用本函數時,設置start和lastTime為timestamp

      if ( ! start ) start = timestamp ;

      if ( ! lastTime ) lastTime = timestamp ;

      // 計算當前時間點與第一次調用step時間點的差

      let elapsedMsec : number = timestamp - start ;

      // 計算當前時間點與上一次調用step時間點的差(可以理解為兩幀之間的時間差)

      let intervalMsec : number = timestamp - lastTime ;

      // 記錄上一次的時間戳

      lastTime = timestamp ;

      // 計數器,用于記錄step函數被調用的次數

      count ++ ;

      console . log ( " " + count + " timestamp = " + timestamp ) ;

      console . log ( " " + count + " elapsedMsec = " + elapsedMsec ) ;

      console . log ( " " + count + " intervalMsec = " + intervalMsec) ;

      // 使用requestAnimationFrame調用step函數

      window . requestAnimationFrame ( step ) ;

      }

      // 使用requestAnimationFrame啟動step

      // 而step函數中又會調用requestAnimationFrame來回調step函數

      // 從而形成不間斷地遞歸調用,驅動動畫不停地運行

      window . requestAnimationFrame ( step ) ;

      上述代碼每次調用step函數會在瀏覽器的console控制臺窗口中輸出當前函數的調用次數,以及3個時間差的數值。Chrome瀏覽器中console控制臺窗口輸出的結果,如圖3.1所示。

      圖3.1? Chrome瀏覽器中的requestAnimationFrame輸出時間差

      渲染 架構設計 TypeScript

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:持續交付之如何選型代碼分支策略
      下一篇:零代碼美食分類模型開發
      相關文章
      亚洲精品乱码久久久久久蜜桃| 亚洲最大福利视频| 亚洲AV日韩综合一区尤物| 久久久久亚洲AV无码观看| 国产亚洲人成网站观看| 国外亚洲成AV人片在线观看| 亚洲AV日韩精品一区二区三区| 亚洲欧美日本韩国| 亚洲熟妇丰满xxxxx| 亚洲精品成a人在线观看夫| 国产 亚洲 中文在线 字幕| 亚洲人成日本在线观看| 亚洲蜜芽在线精品一区| 911精品国产亚洲日本美国韩国| 亚洲网址在线观看你懂的| 久久亚洲精品国产精品| 青青草原精品国产亚洲av| 自怕偷自怕亚洲精品| 亚洲福利电影在线观看| 亚洲国产精品免费在线观看| 亚洲色欲www综合网| 亚洲一卡2卡4卡5卡6卡在线99| 亚洲另类春色校园小说| 国产亚洲sss在线播放| 亚洲一本到无码av中文字幕| 亚洲国产精品久久久久秋霞小| 亚洲国产区男人本色| 亚洲色在线无码国产精品不卡| 亚洲动漫精品无码av天堂| 亚洲大尺度无码专区尤物| 亚洲人成精品久久久久| 国产亚洲综合视频| 成a人片亚洲日本久久| 国产精品亚洲专区无码牛牛| 亚洲成在人线aⅴ免费毛片| 亚洲黄色在线播放| 亚洲精品网站在线观看你懂的| 国产精品亚洲а∨无码播放| 国产亚洲精品成人a v小说| 亚洲人成无码网WWW| 亚洲男人第一无码aⅴ网站|