接着前文看《CSS權威指南》,本文整理一些CSS動畫的知識點,同時給出一些例子。css
在CSS動畫中咱們常常須要經過變形來達到一些奇妙的效果。使用 transform 首先要明確變形是基於笛卡爾座標系,也就是一般所說的 x/y/z html
translateX
、translateY
、translateZ
、translate
、translate3d
scaleX
、scaleY
、scaleZ
、scale
、scale3d( number, number, number )
rotateX
、rotateY
、rotateZ
、rotate
、rotate3d( number, number, number, angle)
skewX
、skewY
、skew
perspective( length )
transform-origin
、transform-style
、backface-visibility
在過渡或者動畫效果中,咱們可能須要使用貝塞爾曲線 cubic-bezier
來控制動畫的步調。咱們能夠在這裏 設置不一樣的曲線並預覽,或者在這裏 查看一些經常使用的曲線 html5
animation-name
:指定動畫的名稱animation-duration
:定義動畫的時長(ms | s)animation-iteration-count
:聲明動畫的迭代次數(number | infinite)animation-direction
:設置動畫播放的方向(normal | reverse | alternate | alternate-reverse)animation-delay
:延遲播放動畫animation-timing-function
:改變更畫的內部時序animation-play-state
:設置動畫的播放狀態(running | paused)animation-fill-mode
:動畫的填充模式,也就是動畫結束以後的狀態(normal | forwards | backwards | both),最終的顯示效果與 animation-direction
屬性有關animationstart
:動畫開始animationiteration
:每次迭代開始animationend
:動畫結束給不一樣對象賦予必定的延遲時間,每每能夠造成一些有趣的動畫效果。這裏咱們要區分兩種延遲:web
animation-delay: <time>
/*假設一個小球來回滾動,每次在兩邊時停留800ms再繼續滾動,咱們能夠由如下動畫控制*/
.ball {
width: 50px;
height: 50px;
border-radius: 50%;
background-color: orange;
animation: move 2000ms infinite alternate;/*alternate 設置來回滾動*/
}
@keyframes move {
0%,
40% {
transform: translateX(0);/*重複關鍵幀模擬延遲,2000ms × .4 = 800ms*/
}
60%,
100% {
transform: translateX(250px);/*重複關鍵幀模擬延遲,2000ms × .4 = 800ms*/
}
}
複製代碼
live demo若是animation-delay
的值爲負,並且絕對值比animation-duration
小,那麼動畫將當即開始而且從中間的關鍵幀開始播放。例如,一個動畫時長爲 10s
,延遲時間爲 -4s
,那麼若是 animation-timing-function
爲 linear
,則將從動畫的 40%
開始播放canvas
利用 box-shadow 能夠建立爲單個元素建立多個 border。例如,咱們能夠利用這個屬性爲一個 loading 動畫添加多個小的圓圈。瀏覽器
// 咱們經過變換box-shadow來交換正方形的位置
.spinner {
position: absolute;
/*border-radius: 50%; need width > 0 and height > 0*/
width: 0;
height: 0;
box-shadow:
-30px -30px 0 40px #a593e0,
-30px 30px 0 40px #e0e3da,
30px 30px 0 40px #fffff3,
30px -30px 0 40px #566270;
animation: spin 3000ms infinite alternate;
}
複製代碼
咱們注意到利用 box-shadow 屬性,全部「子元素」是綁定在「父元素」上且同時變化的。若是咱們不想引入多餘的 DOM 元素,同時又想「子元素」不與「父元素」同時進行變換,咱們能夠採用::after
和::before
來建立。
ide
講完了一些基礎知識,讓咱們進一步聊聊動畫渲染的性能。佈局
瀏覽器的工做原理,請看 How Browsers Work: Behind the scenes of modern web browsers,寫的很詳盡,值得一讀。 性能
瀏覽器處理的過程很簡單:計算元素的樣式(從新計算樣式),生成每一個元素的幾何形狀和位置(佈局),繪製圖層中的每一個像素(初始化繪圖而且進行繪圖)而且將圖層繪製到屏幕上(圖層的合成)現代瀏覽器一般有兩個主要的線程:① main thread;② compositor thread
合成線程會盡量響應用戶的鼠標鍵盤等消息事件。可能發生的狀況是,當頁面滾動須要更新視圖時,合成線程以每幀(60fps)請求更新位圖(刷新屏幕),但主線程上可能正進行復雜的腳本運算或者HTML元素繪製,致使合成線程沒法及時拿到位圖,這時合成線程會繪製空白。
GPU 可以很快地處理將位圖繪製到屏幕上的操做,還能很快處理將同一位圖經過變換再次繪製的操做,可是對於從內存中加載位圖的處理比較慢。比較一個過渡效果使用 height 和 transform 的兩個流程:
爲何有些動畫播放流暢,有些則顯得很卡頓呢?從上面的知識中,咱們或許會獲得一些啓發:現代瀏覽器在完成 position(位置), scale(比例縮放), rotation(旋轉) 和 opacity(透明度)這四種屬性的動畫時,消耗成本較低。
若是咱們使用 height 進行變換,瀏覽器可能在每幀須要請求主線程從新佈局、繪製和更新位圖,再將位圖從 CPU 傳給 GPU,這個過程可能致使卡頓,也就是咱們丟失了某些關鍵幀。
可是使用 height 的性能就必定比 transform 的性能差?不必定,可能的狀況是:① 繪製的位圖很小;② height 更新不會影響其餘元素的佈局等狀況;③ 元素是脫離正常流的;
咱們在使用 width、display、font-size、box-shadow、color 等可能引發重排或者重繪的屬性時,若是你不能清楚的知道本身在作什麼,咱們仍是建議使用推薦的操做避免糟糕的狀況出現。