前端實現動畫
通常在前端中,實現動畫的方案主要有6種:
- CSS3 transition;
- CSS3 animation;
- javascript直接實現;
- SVG(可伸縮矢量圖形);
- Canvas動畫;
- requestAnimationFrame;
首先,我們來搭一個基本結構框架:
<style> div { position: relative; background: #999; width: 50px; height: 50px; } .animat{ } </style> <body> <div class="animat"></div> </body>
CSS3 transition
transition是過度動畫。但是transition只能在某個標簽元素樣式或狀態改變時進行平滑的動畫效果過渡,而不是馬上改變。
transition是漸變的意思,就是某個屬性 從一個值逐漸變成另一個值,比如width:從50px,到200px
基本表達式 transition: transition-property transition-duration transition-timing-function transition-delay
- transition-property :需要做緩動的屬性,默認值為all,就表示所有可以緩動的屬性都做緩動動畫
- transition-duration : 整個緩動動畫的持續時間,比如1s 就是1秒
- transition-timing-function : 緩動動畫的呈現速度方式,默認值為ease,即 先慢再快再慢,還有linear(勻速)等其他方式
- transition-delay : 延遲執行動畫時間
示例
.animat{ transition:width 2s; -moz-transition:width 2s; /* Firefox 4 */ -webkit-transition:width 2s; /* Safari and Chrome*/ -o-transition:width 2s; /* Opera */ } .animat:hover{ width:300px; }
完整代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> div { width:100px; height:100px; background:red; position:absolute; } } .animat{ transition:width 2s; -moz-transition:width 2s; /* Firefox 4 */ -webkit-transition:width 2s; /* Safari and Chrome */ -o-transition:width 2s; /* Opera */ } .animat:hover{ width:300px; } </style> </head> <body> <div class=‘animat‘></div> </body> </html>
這個動畫呈現效果是:當鼠標移動到div上的時候,執行width 改變動畫。
很多其他的一些屬性也可以,比如left,opacity 等等,這裏不做贅述。
CSS3 animation
語法:
animation: name duration timing-function delay iteration-count direction;
name:keyframe的名稱,也就是定義了關鍵幀的動畫的名稱,這個名稱用來區別不同的動畫。
duration:完成動畫所需要的時間(2s 或者 2000ms)
timing-function:完成動畫的速度曲線
delay:動畫開始之前的延遲
iteration-count:動畫播放次數
direction:是否輪流反向播放動畫(normal:正常順序播放,alternate下一次反向播放)如果把動畫設置為只播放一次,則該屬性沒有效果。
使用animation屬性制作動畫可以更加靈活的設置動畫幀,通過不同keyframe(動畫幀)的設置,實現很多優雅的效果,keyframe中的百分數是動畫完成總時間的比例。
animation是設置總的動畫效果,而keyframe中設置上相應的動畫名字,然後在keyframe中設置具體的動畫效果。當然由於是css3的屬性,仍然需要註意它的兼容性,加上必須的前綴。
keyframes
包含兩部分,第一個是使用animation屬性,第二部分是:用@keyframes定義動畫
示例
.animat{ animation: testAni 2s infinite alternate; } /*infinite表示動畫一直循環播放*/ /*alternate表示動畫下一次反向播放*/ @keyframes testAni { 0% { width:100px; } 30% { width:200px; } 100% { width: 500px; } }
0% 表示最開始,30%,表示整個動畫時間的30%, 100% 表示結束,
中括號裏面就是需要呈現動畫的屬性。
註:動畫優化:1)因為動畫改變的太頻繁,所以我們最好用position:absolute或fixed的方式把元素脫離文檔流,避免頻繁重繪;
2) 如果是定位屬性:比如left,top等等,可以用transform:translate()的方式來替代,這樣性能更好.
註:transition適合於一次性的呈現動畫,animation適合多次 或者需要控制中間過程的動畫.
javascript 直接實現動畫
其主要思想是通過setInterval或setTimeout方法的回調函數來持續調用改變某個元素的CSS樣式以達到元素樣式變化的效果。
示例
<body> <div id="animat"></div> <script> let elem = document.getElementById(‘animat‘); let left = 1; //獲取某個元素的寬度:obj.offsetWidth; console.log(elem.offsetWidth); let timer = setInterval(function(){ let elemWidth=elem.offsetWidth; if(elemWidth<500){ //設置某個元素的寬度:obj.style.width; elem.style.width=elemWidth+left+‘px‘; left ++; }else { clearInterval(timer); } },16); </script> </body>
Jquery的animate()方法就是這種方式實現的。
存在的問題
javascript 實現動畫通常會導致頁面頻繁性重排重繪,消耗性能,一般應該在桌面端瀏覽器。在移動端上使用會有明顯的卡頓。
前端實現動畫