一般在前端中,實現動畫的方案主要有6種:javascript
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
上面例子中,咱們設置的setInterval時間間隔是16ms。通常認爲人眼能辨識的流暢動畫爲每秒60幀,這裏16ms比(1000ms/60)幀略小一些,可是通常可仍爲該動畫是流暢的。
在不少移動端動畫性能優化時,通常使用16ms來進行節流處理連續觸發的瀏覽器事件。例如對touchmove、scroll事件進行節流等。經過這種方式減小持續事件的觸發頻率,能夠大大提高動畫的流暢性。css3
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 */ }
此種方式比較小衆,不易控制性能優化
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:設置對象狀態爲動畫結束或開始的狀態,結束時狀態優先
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來渲染控制動畫的執行。可用於實現較複雜動畫。
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的應用變得相對少了。
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調用。
複雜的動畫是經過一個個簡單的動畫組合實現的。基於兼容性問題,一般在項目中,通常在