做爲一隻前端狗,咱們的使命就是在知足產品需求、實現交互設計的基礎上,將最好的體驗呈現給用戶爸爸們。在保證性能的同時,咱們一般會給頁面加一些動態效果,以加強頁面的表現力並提高頁面的交互體驗。故將前端實現動效的幾種經常使用方式整理成此篇小結,以求溫故而知新,若有不當還望多多指正。javascript
動畫是指由許多幀靜止的畫面,以必定的速度(如每秒16張)連續播放時,肉眼因視覺殘象產生錯覺,而誤覺得畫面活動的做品。-- 維基百科css
以上是維基百科上給出的動畫的定義。相信每個像我這樣有童年的孩子,應該都玩過手翻書,或者就算你的童年稍微暗淡一點,應該也看過動畫片吧...嗯嗯,並無跑題,其實這和咱們今天說起的動畫本質上是同樣的,只不過就是呈現方式或者說載體發生了改變。前端
簡單介紹幾個關於動畫的基本概念:java
幀:在動畫過程當中,每一幅靜止畫面即爲一「幀」; 幀率:即每秒鐘播放的靜止畫面的數量,單位是fps(Frame per second)或赫茲(Hz); 幀時長:即每一幅靜止畫面的停留時間,單位通常是ms(毫秒); 丟幀:在幀率固定的動畫中,某一幀的時長遠高於平均幀時長,致使其後續數幀被擠壓而丟失的現象;css3
咱們在顯示器上看到的動畫,每一幀變化都是系統繪製出來的(GPU或者CPU)。它的最高繪製頻率受限於顯示器的刷新頻率(而非顯卡,大多數是60Hz或者75Hz)。git
幀頻越高,屏幕上圖片閃爍感就越小,穩定性也就越高。人的眼睛不容易察覺75Hz以上刷新頻率帶來的閃爍感。github
一般咱們在前端實現動畫效果的幾種主要實現方式以下:web
- JavaScript:經過定時器(setTimeout 和 setIterval)來間隔來改變元素樣式,或者使用requestAnimationFrame;
- CSS3:transition 和 animation;
- HTML5:使用HTML5提供的繪圖方式(canvas、svg、webgl);
requestAnimationFrame
是瀏覽器用於定時循環操做的一個接口,相似於setTimeout
,主要用途是按幀對網頁進行重繪。canvas
設置這個API的目的是爲了讓各類網頁動畫效果(DOM動畫、Canvas動畫、SVG動畫、WebGL動畫)可以有一個統一的刷新機制,從而節省系統資源,提升系統性能,改善視覺效果。代碼中使用這個API,就是告訴瀏覽器但願執行一個動畫,讓瀏覽器在下一個動畫幀安排一次網頁重繪。瀏覽器
requestAnimationFrame
使用一個回調函數做爲參數,這個回調函數會在瀏覽器重繪以前調用,因爲功效只是一次性的,因此想實現連續的動效,須要遞歸調用,示例以下:
<div id="demo" style="position:absolute; width:100px; height:100px; background:#ccc; left:0; top:0;"></div>
<script>
var demo = document.getElementById('demo');
function render(){
demo.style.left = parseInt(demo.style.left) + 1 + 'px'; //每一幀向右移動1px
}
requestAnimationFrame(function(){
render();
//當超過300px後才中止
if(parseInt(demo.style.left) <= 300) requestAnimationFrame(arguments.callee);
});
</script>
複製代碼
cancelAnimationFrame方法用於取消重繪:
var requestID = requestAnimationFrame(repeatOften);
cancelAnimationFrame(requestID);
複製代碼
使用requestAnimationFrame
API的優點以下:
- 會把每一幀中的全部DOM操做集中起來,在一次重繪或迴流中就完成,而且重繪或迴流的時間間隔牢牢跟隨顯示器的刷新頻率(60 Hz或者75 Hz);
- 在隱藏或不可見的元素中,將不會進行重繪或迴流,這固然就意味着更少的的cpu,gpu和內存使用量;
目前,主要瀏覽器Firefox 23 / IE 10 / Chrome / Safari)都支持這個方法。能夠用下面的方法,檢查瀏覽器是否支持這個API。若是不支持,則自行模擬部署該方法。
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element){
window.setTimeout(callback, 1000 / 60);
};
})();
複製代碼
因此,能夠這麼說,requestAnimationFrame
就是一個性能優化版、專爲動畫量身打造的setTimeout
,不一樣的是requestAnimationFrame
不是本身指定回調函數運行的時間,而是跟着瀏覽器內建的刷新頻率來執行回調,這固然就能達到瀏覽器所能實現動畫的最佳效果了。
CSS 中的 transition 屬性容許塊級元素中的屬性在指定的時間內平滑的改變,簡單看下其語法規則:
transition: property duration timing-function delay;
複製代碼
具體屬性值介紹以下:
值 | 描述 |
---|---|
transition-property | 規定設置過渡效果的 CSS 屬性的名稱。(none / all / property) |
transition-duration | 規定完成過渡效果須要多少秒或毫秒。 |
transition-timing-function | 規定速度效果的速度曲線。(linear、ease、ease-in、ease-out、ease-in-out、cubic-bezier(n,n,n,n)) |
transition-delay | 定義過渡效果什麼時候開始。 |
相似的CSS還提供了一個Animation屬性,不過區別於Transition,Animation做用於元素自己而不是樣式屬性,可使用關鍵幀的概念,應該說能夠實現更自由的動畫效果。
animation: name duration timing-function delay iteration-count direction;
複製代碼
具體屬性值介紹以下:
值 | 描述 |
---|---|
animation-name | 規定須要綁定到選擇器的 keyframe 名稱。(keyframename、none) |
animation-duration | 規定完成動畫所花費的時間,以秒或毫秒計。 |
animation-timing-function | 規定動畫的速度曲線。(linear、ease、ease-in、ease-out、ease-in-out、cubic-bezier(n,n,n,n)) |
animation-delay | 規定在動畫開始以前的延遲。 |
animation-iteration-count | 規定動畫應該播放的次數。 |
animation-direction | 規定是否應該輪流反向播放動畫。 (normal、alternate) |
<canvas>
是HTML5新增的元素,做爲頁面圖形繪製的容器,可用於經過使用JavaScript中的腳原本繪製圖形。例如,它能夠用於繪製圖形,製做照片,建立動畫,甚至能夠進行實時視頻處理或渲染,Canvas具備以下特色:
- 依賴分辨率,基於位圖;
- 不支持事件處理器;
- 弱的文本渲染能力;
- 可以以 .png 或 .jpg 格式保存結果圖像;
- 最適合圖像密集型的遊戲,其中的許多對象會被頻繁重繪;
大多數 Canvas 繪圖 API 都沒有定義在
SVG是英文Scalable Vector Graphics的縮寫,意爲可縮放矢量圖形,用來定義用於網絡的基於矢量的圖形,其使用 XML 格式定義圖像,而且具備以下特色:
- 不依賴分辨率,基於矢量圖;
- 支持事件處理器;
- 最適合帶有大型渲染區域的應用程序(好比谷歌地圖);
- 複雜度高會減慢渲染速度(任何過分使用 DOM 的應用都不快);
- 不適合遊戲應用;
來看一個簡單的示例,用SVG畫了一個圓:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect x="50" y="20" rx="20" ry="20" width="150" height="150"
style="fill:red;stroke:black;stroke-width:5;opacity:0.5"/>
</svg>
複製代碼
SVG 代碼以 <svg>
元素開始,包括開啓標籤 <svg>
和關閉標籤 </svg>
。這是根元素。width 和 height 屬性可設置此 SVG 文檔的寬度和高度。version 屬性可定義所使用的 SVG 版本,xmlns 屬性可定義 SVG 命名空間。
SVG 的 <circle>
用來建立一個圓。cx 和 cy 屬性定義圓中心的 x 和 y 座標。若是忽略這兩個屬性,那麼圓點會被設置爲 (0, 0)。r屬性定義圓的半徑。
下面主要是介紹SVG中的幾個用於動畫的元素,它們分別是:
:一般放置到一個SVG圖像元素裏面,用來定義這個圖像元素的某個屬性的動畫變化過程;
:元素也是放置一個圖像元素裏面,它能夠引用一個事先定義好的動畫路徑,讓圖像元素按路徑定義的方式運動; :元素對圖形的運動和變換有更多的控制,它能夠指定圖形的變換、縮放、旋轉和扭曲等; :元素的用法在上面的例子裏出現過,它是一個輔助元素,經過它, <animateMotion>
等元素能夠引用一個外部的定義的<path>
。讓圖像元素按這個<path>
軌跡運動;
WebGL使得網頁在支持HTML <canvas>
標籤的瀏覽器中,不須要安裝任何插件,即可以使用基於 OpenGL ES 2.0 的 API 在 canvas 中進行3D渲染。 WebGL 程序由JavaScript的控制代碼,和在計算機的圖形處理單元(GPU)中執行的特效代碼(shader code,渲染代碼) 組成。
WebGL 本質上是基於光柵化的 API,而不是基於 3D 的 API。WebGL 只關注兩個方面,即投影矩陣的座標和投影矩陣的顏色。使用 WebGL 程序的任務就是實現具備投影矩陣座標和顏色的 WebGL 對象便可。可使用「着色器」來完成上述任務。頂點着色器能夠提供投影矩陣的座標,片斷着色器能夠提供投影矩陣的顏色。
因爲WebGL的體系比較龐大,三言兩語說不完,因此如下僅提供各類傳送門了(不準說我懶!!): WebGL 參考資料 WebGL API
Ani.js -- 基於CSS動畫的生命處理庫 Dynamics.js -- 建立具備物理運動效果動畫的js庫 Animate.css -- 齊全的CSS3動畫庫 Three.js -- 讓用戶經過javascript入手進入搭建webgl項目的類庫