前端實現動畫的6種方式詳解

前端實現動畫的6種方式詳解

1、總結

一句話總結:通常是css樣式改變加setInterval

 

 

2、【前端動畫】實現動畫的6種方式

一般在前端中,實現動畫的方案主要有6種:javascript

  • javascript直接實現;
  • SVG(可伸縮矢量圖形);
  • CSS3 transition;
  • CSS3 animation;
  • Canvas動畫;
  • requestAnimationFrame;

 

3、javascript 直接實現動畫(setInterval+css改變,setInterval+transform)

transform也能夠改變樣式css

其主要思想是經過setInterval或setTimeout方法的回調函數來持續調用改變某個元素的CSS樣式以達到元素樣式變化的效果。html

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <style type="text/css"> #rect { width: 200px; height: 200px; background: #ccc; } </style>
</head>
<body>
    <div id="rect"></div>
    <script> let elem = document.getElementById('rect'); let left = 0; let timer = setInterval(function(){ if(left<window.innerWidth-200){ elem.style.marginLeft = left+'px'; left ++; }else { clearInterval(timer); } },16); </script>
</body>
</html>

Jquery的animate()方法就是這種方式實現的。前端

存在的問題

javascript 實現動畫一般會致使頁面頻繁性重排重繪,消耗性能,通常應該在桌面端瀏覽器。在移動端上使用會有明顯的卡頓java

Tip:爲何是16ms

上面例子中,咱們設置的setInterval時間間隔是16ms。通常認爲人眼能辨識的流暢動畫爲每秒60幀,這裏16ms比(1000ms/60)幀略小一些,可是通常可仍爲該動畫是流暢的。
在不少移動端動畫性能優化時,通常使用16ms來進行節流處理連續觸發的瀏覽器事件。例如對touchmove、scroll事件進行節流等。經過這種方式減小持續事件的觸發頻率,能夠大大提高動畫的流暢性。css3

 

4、CSS3 transition(transform+transition)(純css)

transition是過分動畫。可是transition並不能實現獨立的動畫,只能在某個標籤元素樣式或狀態改變時進行平滑的動畫效果過渡,而不是立刻改變。web

注意

在移動端開發中,直接使用transition動畫會讓頁面變慢甚至卡頓。因此咱們一般添加transform:translate3D(0,0,0)或transform:translateZ(0)來開啓移動端動畫的GPU加速,讓動畫過程更加流暢。canvas

 

一、設置transition設置過渡,添加transform設置形狀,造成動畫效果,以下:瀏覽器

.divadd {
	 transition: All 0.4s ease-in-out;
         -webkit-transition: All 0.4s ease-in-out;
         -moz-transition: All 0.4s ease-in-out;
         -o-transition: All 0.4s ease-in-out;

	 transform:rotate(360deg);
	-ms-transform:rotate(360deg); /* IE 9 */
	-webkit-transform:rotate(360deg); /* Safari and Chrome */
}

  此種方式比較小衆,不易控制性能優化

 

5、CSS3 animation(animation屬性+@keyframes)(純css)

animation 算是真正意義上的CSS3動畫。經過對關鍵幀和循環次數的控制,頁面標籤元素會根據設定好的樣式改變進行平滑過渡。並且關鍵幀狀態的控制是經過百分比來控制的。

比較

CSS3最大的優點是擺脫了js的控制,而且能利用硬件加速以及實現複雜動畫效果。

 

二、添加animation屬性,設置動畫效果,以下:

.a1 {
	position: absolute;
	animation: a1 3s;
	opacity: 0
}
@keyframes a1 {
	0% {left: 10px;opacity: 0}
	30% {left: 60px;background-color: pink;font-size:23px;opacity: 1}
	90% {left: 100px;background-color: red;opacity: 1}
	100% {left: 10px;opacity: 0}
} 

 

以上百分比後的方括號內能夠添加各類屬性值,好比transform ratote、left。。。。。。添加left top等定位不要忘記設置position absolute

全部屬性有:

    animation-name: myfirst;  //動畫名稱,用於animation引用
    animation-duration: 5s;  //動畫時長,
    animation-timing-function: linear;
    animation-delay: 2s;
    animation-iteration-count: infinite;
    animation-direction: alternate;
    animation-play-state: running;
animation-fill-mode
設置動畫結束後的狀態
none:默認值。不設置對象動畫以外的狀態,DOM未進行動畫前狀態
forwards:設置對象狀態爲動畫結束時的狀態,100%或to時,當設置animation-direcdtion爲reverse時動畫結束後顯示爲keyframes第一幀
backwards:設置對象狀態爲動畫開始時的狀態,(測試顯示DOM未進行動畫前狀態)
both:設置對象狀態爲動畫結束或開始的狀態,結束時狀態優先


 

6、Canvas動畫(setInterval+canvas)

canvas做爲H5新增元素,是藉助Web API來實現動畫的。

示例

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> *{ margin:0; padding:0; } </style> </head> <body> <canvas id="canvas" width="700" height="550"></canvas> <script type="text/javascript"> let canvas = document.getElementById("canvas"); let ctx = canvas.getContext("2d"); let left = 0; let timer = setInterval(function(){ ctx.clearRect(0,0,700,550); ctx.beginPath(); ctx.fillStyle = "#ccc"; ctx.fillRect(left,0,100,100); ctx.stroke(); if(left>700){ clearInterval(timer); } left += 1; },16); </script> </body> </html>

註釋:經過getContext()獲取元素的繪製對象,經過clearRect不斷清空畫布並在新的位置上使用fillStyle繪製新矩形內容實現頁面動畫效果。

比較

Canvas主要優點是能夠應對頁面中多個動畫元素渲染較慢的狀況,徹底經過javascript來渲染控制動畫的執行。可用於實現較複雜動畫。

 

 

7、SVG(svg標籤+animate標籤)

SVG動畫由SVG元素內部的元素屬性控制,通常經過一下幾個元素控制:

  • : 用於控制動畫延時
  • :對屬性的連續改變進行控制
  • :顏色變化,但用就能控制
  • :控制如縮放、旋轉等幾何變化
  • :控制SVG內元素的移動路徑

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style> *{ margin:0; padding:0; } </style>
</head>
<body>
    <svg id="box" width="800" height="400" xmlns="http://www.w3.org/2000/svg" version="1.1">
        <rect x="" y="" width="100" height="100" fill="rgb(255,0,0);" stroke="" stroke-width="">
            <set attributeName="x" attributeType="XML" to="100" begin="4s"/>
            <animate attributeName="x" attributeType="XML" begin="0s" dur="4s" from="0" to="300"/>
            <animate attributeName="y" attributeType="XML" begin="0s" dur="4s" from="0" to="0"/>
            <animateTransform attributeName="transform" begin="0s" dur="4s" type="scale" from="1" to="2" repeatCount="1" />
            <animateMotion path="M10,80 q100,120 120,20 q140,-50 160,0" begin="0s" dur="4s" repeatCount="1" />

        </rect>     
    </svg>  

</body>
</html>

這裏推薦一個在sublime text3中使用svg提示插件:svg snippet。

比較

SVG的一大優點是含有較爲豐富的動畫功能,原生繪製各類圖形、濾鏡和動畫,而且能被js調用。html是對dom的渲染,那麼svg就是對圖形的渲染
可是,另外一方面元素較多且複雜的動畫使用svg渲染會比較慢,並且SVG格式的動畫繪製方式必須讓內容嵌入到HTML中使用。CSS3的出現讓svg的應用變得相對少了。

 

 

8、requestAnimationFrame(相似setInterval)

requestAnimationFrame是另外一種Web API,原理與setTimeout和setInterval相似,都是經過javascript持續循環的方法調用來觸發動畫動做。可是requestAnimationFrame是瀏覽器針對動畫專門優化造成的APi,在性能上比另二者要好。

一般,咱們將執行動畫的每一步傳到requestAnimationFrame中,在每次執行完後進行異步回調來連續觸發動畫效果。

示例

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css"> * { margin:0; padding:0; } div { width: 200px; height: 200px; background-color: #ccc; } </style>
</head>
<body>
    <div id="rect"></div>
    <script type="text/javascript"> window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; let elem = document.getElementById("rect"); let left = 0; //自動執行持續性回調 requestAnimationFrame(step); //持續該改變元素位置 function step() { if(left<window.innerWidth-200){ left+=1; elem.style.marginLeft = left+"px"; requestAnimationFrame(step); } } </script>
</body>
</html>

咱們注意到,requestAnimationFrame只是將回調的方法傳入到自身的參數中執行,而不是經過setInterval調用。

 

9、總結

複雜的動畫是經過一個個簡單的動畫組合實現的。基於兼容性問題,一般在項目中,通常在

  • 桌面端瀏覽器推薦使用javascript直接實現動畫或SVG方式;
  • 移動端能夠考慮使用CSS3 transition、CSS3 animation、Canvas或requestAnimationFrame方式**。
相關文章
相關標籤/搜索