JavaScript動畫知多少?

  今天,小學生以本身淺薄的見地,在前輩大能的基礎上寫這篇文章,但願給你們打開一扇窺探JavaScript(如下簡稱JS)動畫的窗戶。css

JS如何製造出動畫效果?html

  結合瀏覽器提供的 setInterval 或 setTimeout API,高頻改變DOM元素的一些屬性,便可創造一個肉眼可見的動畫效果。一個看起來很是流暢的JS動畫除了須要良好的變換算法外,與其執行宿主也是非不開的。程序寫得再好,若是瀏覽器過於老舊,電腦CPU性能低下,也會出現卡頓,甚至卡死。css3

  執行一個動畫函數對於瀏覽器來講是個苦差,設置動畫一幀爲多長時間才能既流暢又不損耗性能呢?瀏覽器不會傻到進行一個DOM操做,就去渲染一次頁面。它會把一個週期內全部的DOM操做整合起來,統一進行一次渲染。這個週期大約在16.7ms左右,不一樣瀏覽器間會有幾毫秒的差別。SetTimeout的第二個參數設置爲1000/60是比較合乎情理的作法。不過了解過SetTimeout運行機制的都會清楚,這個時間並不可靠,其根據實際狀況會有些許甚至至關大的延遲。那麼有沒有這樣一個API?我不想知道你瀏覽器到底多久渲染一次,反正你渲染的時候給個人動畫執行一幀就好了。答案是有,requestAnimationFrame,可讓函數隨着瀏覽器渲染執行,而且執行時機是可靠的。注意,這個方法在如今瀏覽器及IE10+才被支持。web

  如今能夠封裝起一個簡單的requestAnimationFrame,下面的例子中將會使用到它。算法

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

  更加詳細的封裝能夠在張鑫旭的博客中看到:張鑫旭:requestAnimFrame。下面讓咱們繼續。瀏覽器

動畫函數的編寫app

  有了requestAnimationFrame,下面該考慮一下如何讓寫動畫函數了。通常來講咱們會給出一個毫秒級的during值,限制這個動畫必需要在這個時間內完成。下面以實現一個小球從離頁面左側100px處勻速運動到800px處爲例,編寫一個動畫函數:戳我查看DEMOide

            var ele = document.getElementById("block");
            var start = Date.now();//獲取動畫開始的時間。
            var during = 1000; //此動畫要在1秒內執行完。
            var p=0;//動畫完成度 從0-1;
            requestAnimationFrame(function f(){
                if(p>=1){ ele.style.left="800px";}//若是發現動畫已經執行完,將元素置到終點。
                else{
                    p=(Date.now()-start)/during;
                    ele.style.left=100+700*p+"px"; //從100px開始,勻速向右移動,共移動700px;
                    requestAnimationFrame(f);
                }
            })

  上面函數中有一個關鍵變量:p,即percentage,咱們能夠稱它爲動畫的完成度,它是根據當前時間計算得出的,而且從動畫開始後,會從0~1勻速漸變。當其爲1時,表示整個動畫執行完畢。在這個函數中,讓p乘以要運動的長度700,便會獲得一個0-700勻速變化的值,將其加上開始的100,即可模擬小球從100px處勻速移動到800px處。wordpress

  設想一下,假如上面紅色標出的運動方程改成「ele.style.left=100+700*p*p+"px"」呢?p以二次方漸增,小球向右移動的速度會愈來愈快。是的,稍加修改即可實現一個勻加速運動的小球。函數

  下面,咱們就是要針對p來作文章。

Tween算法及緩動效果

   下面我將列舉一些經常使用的緩動算法,根據這些算法去修改上面勻速運動函數的運動方程,便可實現很讚的動畫效果。

  1. 2次方緩動:  p*p
  2. 3次方緩動:  p*p*p
  3. 4次方緩動:  p*p*p*p
  4. 5次方緩動:  p*p*p*p*p
  5. 正弦曲線緩動:  Math.sin(p*Math.PI/2)
  6. 指數曲線緩動:  Math.pow(2,10*(p-1))
  7. 圓形曲線緩動:  Math.sqrt(1-(p-1)*(p-1))
  8. 超範圍三次方:  p*p*(2.70158*p-1.70158)

  驗證一下吧,好比我如今想實現一個小球向右運動,有一個向左蓄力的動畫,我只要把第一個demo的運動方程改成「ele.style.left=100+700*p*p*(2.70158*p-1.70158)+"px"」就好了,看看效果吧:戳我查看DEMO

  其實,每種緩動算法均可以進化爲三種緩動方式,分別爲ease-in(先慢後快),ease-out(先快後慢),ease-in-out(先慢後快再慢)。

  以2次方緩動爲例,它自己就是一個勻加速的過程,因此ease-in就是p*p。其ease-out爲-(p*(p-2))。關於緩動方式,像陽光同樣在他的博客中有更加詳細的解釋:JavaScript動畫、運動算法詳細解釋與分析

  接下來要放大招了,關於緩動的整合DEMO,戳我吧

JS動畫能夠作什麼?

  除了上面的緩動效果,利用常見的數學公式還能夠實現一些週期性運動效果,例如小球勻速圓周運動,小球勻速簡諧振動等,若是感興趣請猛戳DEMO

  那麼JS動畫能夠作什麼呢?這就須要發揮咱們的我的想象力了,上面的DEMO大部分都在操控單一的屬性,好比left,讓DOM元素髮生位移。事實上在運動方程中,元素的任何style均可以被漸變。試想一下,設置一個DOM元素的opacity從0~1進行2次方緩動,即是一個簡單的jQuery fadeOut函數;讓一個DOM元素高度從無到有,即是一個簡單的jQuery slideDown函數。更加不要忘記的是,在動畫過程當中不只僅能夠操做一項屬性,這爲動畫帶來了無限的可能性,事情變得愈來愈有趣了:DEMO:一個從小到大變化的球

  再試想一下,使用CSS3屬性,例如box-shadow,transform,做出的效果必將會更加絢麗。

總結

  上面提到使用CSS3屬性,其實若是這個瀏覽器支持CSS3屬性的話,其實能夠考慮徹底使用CSS3實現一個動畫。CSS3自有Animation動畫屬性,能夠簡單快捷地實現酷炫的動畫效果,而且能夠啓用GPU加速。美中不足的是僅現代瀏覽器支持,而JS實現動畫勝在能夠兼容低版本瀏覽器。

  做者於2015年6月19號增長)上面將JavaScript動畫與CSS3動畫的比較並非特別嚴謹,更嚴謹的說法請移步個人博客:實現了一個百度首頁的彩蛋——CSS3Animation簡介

  動畫僅僅是JS操做DOM魅力之冰山一角,而數學與計算機老是能碰撞出耀眼的火花。繼續學習JS吧,這是一門神奇的語言,同時也應該瞭解一些數學知識,每每可以爲解決事情帶來捷徑。

  (完)

相關文章
相關標籤/搜索