在以往,咱們在網頁上製做動畫效果的時候,若是是用javascript實現,通常都是經過定時器和間隔來實現的,出現HTML5以後,咱們還能夠用CSS3 的transitions
和animations
很方便的實現動畫,這些技術手段在對於簡單的或者對流暢性要求不高的動畫不會有什麼問題,然而隨着用戶體驗的提升,咱們製做的動畫效果有了更高的要求,那麼對於比較複雜的並且具備較高流暢性的動畫效果,用以上的兩種方法就有點捉襟見肘了。對於質量較高的動畫效果的實現,咱們又不想用falsh,那怎麼辦呢?爲解決這個問題,瀏覽器提供了一個統一幀管理、提供監聽幀的API,即requestAnimationFrame
。咱們今天就是利用requestAnimationFrame()
函數來實現一個高質量旋轉風車的動畫效果。javascript
一:假如同時進行的n個動畫,函數會把本來須要n次reflow和repaint優化成1次,而後交給瀏覽器進行優化,這樣就實現了高質量的動畫效果。
二:若是瀏覽器的某個tab正在運行這樣一個動畫,而後你切到另外一個tab,或者乾脆最小化,總之就是你看不見它了,這時瀏覽器就會中止動畫。這將意味着更少的CPU和更少的內存消耗。html
調用requestAnimationFrame
函數,傳遞一個callback
參數,則在下一個動畫幀時,會調用callback
。java
//瀏覽器兼容處理 var requestAnimationFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60); }; })(); //如何使用 (function(){ render(); requestAnimationFrame(arguments.callee, element); })();
requestAnimationFrame函數是webkit私有api,不過基本除了opera,如今各個最新的瀏覽器也都開始支持了,這是個很讓人振奮的消息。另外在這裏注意說明一下,requestAnimationFrame函數只是一個作動畫的基礎API,即不基於DOM元素的style變化,也不基於canvas,或者WebGL。因此,具體的動畫細節須要咱們本身寫。更多的詳細說明介紹請看:requestAnimationFrame for smart animating
好了,咱們瞭解了requestAnimationFrame函數,那麼咱們接下來就學以至用,製做一個高質量旋轉風車動畫效果:jquery
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
(function() { var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; } ()); // 自定義動畫動做 var pinWheelArr36 = [ - 32, -302, -572, -841, -1112, -1381, -1651, -1921, -2191, -2461, -2732, -3002, -3272, -3542, -3812, -4082, -4352, -4621, -4891, -5161, -5431, -5702, -5972, -6242, -6512, -6782, -7053, -7322, -7592, -7861, -8132, -8402, -8672, -8941, -9211, -9482]; var pinWheel = $('#fengche') var pinCount = 0; var fps = 31; function spin() { setTimeout(function() { requestAnimationFrame(spin) if (pinCount > pinWheelArr36.length - 1) { pinCount = 0; }; pinWheel.css('background-position', pinWheelArr36[pinCount] + 'px top') pinCount++; }, 1000 / fps); }; spin();
<div style="background-position: -4621px top;" id="fengche"></div>
其實學習了requestAnimationFrame函數,只要咱們多加練習,運用到咱們的項目中去,相信必定能夠作出具備創意和高質量的動畫效果。我也是剛剛接觸到,若有錯誤的觀點,請指出,很是感激。ajax