大概有多久沒有更新專欄文章了。半年?下半年忙到起飛,或者絕不誇張的說是發射?僅有的一點我的時間,上半年貢獻給了Python,如今差很少已忘掉了七七八八(一首《涼涼》送給本身),下半年貢獻給了JavaScript,終於鼓起勇氣系統的開始學習JS了(換臺,梁靜茹《勇氣》走起)。原本想一直等等等,等到webapi學完後放個大招,svg+CSS動畫搭乘上JavaScript簡直如虎添翼長驅直入。可是,看掘金做者羣裏討論的風生水起,忽然感受本身全然是陌生人(此處應放蔡健雅?),因此,更一篇文章刷一下存在感。css
這篇文章原本是寫的《SVG+CSS動畫》小冊中的一個小節選,小冊由於各類莫名的緣由,擱淺了,擱淺……起航時間遙遙無期,但keyframes關鍵幀做爲控制動畫在不一樣時間的狀態的重要元素,決定了七十二變的終極形態,因此此次更新專欄拿它下手。至於小冊嘛,若是能發的話,裏面再換成其餘的案例就好,此爲後話。web
關鍵幀keyframes的基礎概念此處可省略,下面纔是滿滿的乾貨。api
由於只是來解釋關鍵幀,因此只搞了一個簡易的僅水平位移的動效。所以,這篇文章得以脫離SVG單獨存在僅和CSS3動畫屬性相關。瀏覽器
CSS部分定義一個最基礎的位移動畫,4s完成,線性速度case-關鍵幀演示1-基礎。svg
@keyframes move{
0%{transform:translateX(0)}
100%{transform:translateX(800px)}
}
.c_move{animation:move 4s linear both} /*both:運動結束後停留在終點*/
複製代碼
這個發揮做用主要是在定義了無限循環動畫時。學習
基礎的設置天然帶來毫無特點平淡無奇的基礎動效。動畫
下面,我想讓圓圈在起點停留2s後再開始移動,第一反應是用動畫屬性中的延遲animation-delay,把時間定義成2s,行不行?行,但這裏用個更高級的方法。咱們在定義關鍵幀時用了大量的百分比,這裏百分比值表明的是時間節點,也就是說關鍵幀定義的是不一樣時間節點的狀態屬性。 下面再來看一張圖,這張圖必定不要和上面的路徑演示弄混了,這是一張動畫的時間軸的圖。ui
@keyframes move{
0%{transform:translateX(0)}
50%{transform:translateX(0px)}
100%{transform:translateX(800px)}
}
複製代碼
對照上面時間軸的分割來看,更容易理解一些,這樣就獲得了在起點處停留2s後,在後面的2s完成整個動畫的動效。這裏亦或用一種更簡單的寫法爲0%, 50%{transform:translateX(0)}
,屬性相同的能夠合併在一塊兒,用逗號分隔。case-關鍵幀演示-延遲開始spa
有了延遲開始的基礎,提早結束是否是已經能夠類推出來了。爲了區分一下,我讓動畫提早3s結束。照例先畫出時間軸的解析。設計
@keyframes move{
0%{transform:translateX(0)}
25%,100%{transform:translateX(800px)}
}
複製代碼
最終結果圓圈必定是4倍速度盡心盡力加速完成旅程(畢竟要把原來4s的時間壓縮到1s完成),而後悠然自得的在終點等待整個動畫時間結束。case-關鍵幀演示-提早結束
那些已準備穩當的驛站,如今能夠發揮做用了,我但願圓圈這樣運動:整個旅程中僅在第一個驛站(移動200px後)停留1s,稍做整頓。映射到時間軸上是什麼樣子的呢?
@keyframes move{
0%{transform:translateX(0)}
18.75%, 43.75%{transform:translateX(200px)} /*對應停留的1s*/
100%{transform:translateX(800px)}
}
複製代碼
增長些難度,在中途任意點做停留已經不是什麼問題了,停留在一個點和多個點是相同的思路,如今,我讓圓圈跳躍式前進,進入第一個驛站後,停留1s,跨過第二個驛站,直接進入第三個驛站,停留1s,完成旅程。根據空間摺疊原理,200和600處發生了躍遷。分析時間軸:
@keyframes move{
0%{transform:translateX(0)}
25%,50%{transform:translateX(200px)}
50%,75%{transform:translateX(600px)}
100%{transform:translateX(800px)}
}
複製代碼
效果如何呢?
@keyframes move{
0%{transform:translateX(0)}
25%{transform:translateX(200px)}
50%,75%{transform:translateX(600px)} /*在位移600px後停留1s*/
100%{transform:translateX(800px)}
}
複製代碼
這就是爲何看上去是到達第一驛站後加速跑向第三個驛站,而後停留後再完成剩下的路程的緣由。如今遊戲愈來愈有意思了,或許咱們能夠試試騙過瀏覽器。既然一樣的時間點只容許定義一個屬性值,那若是我在緊鄰的旁邊增長一個時間點來定義,會發生什麼?
@keyframes move{
0%{transform:translateX(0)}
25%,50%{transform:translateX(200px)}
50.0001%,75%{transform:translateX(600px)}
100%{transform:translateX(800px)}
}
複製代碼
看上面出現的50.0001% 這個時間點,猜猜發生了什麼?這就是上面所謂的「騙過瀏覽器」的方法了。在50%→50.0001%這個區間,發生了400px(200→600)的位移變化。因此就獲得了下面這種效果:case-關鍵幀演示-躍遷
從原理上來說,這是一種視覺欺騙,在極短的時間內在兩個位置間發生位移,由於時間短到能夠忽略,因此會有一種跳躍的假象。
看完上面的幾種表明性實例,是否是對關鍵幀的定義有了一個全新的認識,你可能會以爲對於「延遲開始」和「提早結束」這兩種需求,是徹底能夠經過定義延遲時間以及動畫週期的時間來達到相同的效果的,可是,對於一個無限循環的動效而言,延遲開始永遠只做用一次,當動畫一旦開始進入周而復始的循環後,再也不支持這個屬性設置。所以,若是能夠的話,儘可能用關鍵幀的定義來完成。
對於關鍵幀,最重要的是時間節點,而最好的方法,就是粗略繪製一個時間軸,把事件按照順序依次映射到時間軸上。