詳解CSS動畫屬性關(guān)鍵幀keyframes全解析
大概有多久沒有更新專欄文章了。半年?下半年忙到起飛,或者毫不夸張的說是發(fā)射?僅有的一點個人時間,上半年貢獻給了Python,現(xiàn)在差不多已忘掉了七七八八(一首《涼涼》送給自己),下半年貢獻給了JavaScript,終于鼓起勇氣系統(tǒng)的開始學(xué)習(xí)JS了(換臺,梁靜茹《勇氣》走起)。本來想一直等等等,等到webapi學(xué)完后放個大招,svg+CSS動畫搭乘上JavaScript簡直如虎添翼長驅(qū)直入。但是,看掘金作者群里討論的風(fēng)生水起,突然感覺自己全然是陌生人(此處應(yīng)放蔡健雅?),所以,更一篇文章刷一下存在感。
這篇文章本來是寫的《SVG+CSS動畫》小冊中的一個小節(jié)選,小冊因為各種莫名的原因,擱淺了,擱淺……起航時間遙遙無期,但keyframes關(guān)鍵幀作為控制動畫在不同時間的狀態(tài)的重要元素,決定了七十二變的終極形態(tài),所以這次更新專欄拿它下手。至于小冊嘛,如果能發(fā)的話,里面再換成其他的案例就好,此為后話。
關(guān)鍵幀keyframes的基礎(chǔ)概念此處可省略,下面才是滿滿的干貨。
案例:一路向前永不停歇的圓
因為只是來解釋關(guān)鍵幀,所以只搞了一個簡易的僅水平位移的動效。因此,這篇文章得以脫離SVG單獨存在僅和CSS3動畫屬性相關(guān)。

這是一個努力從起點滾向終點的圓圈,整個路程為800px,但我在它的必經(jīng)之路的三處設(shè)置了三個驛站?,F(xiàn)在就要通過關(guān)鍵幀的定義讓圓圈在行進的路上進入驛站并稍作停頓。
1.先來一個最基礎(chǔ)的
CSS部分定義一個最基礎(chǔ)的位移動畫,4s完成,線性速度case-關(guān)鍵幀演示1-基礎(chǔ) 。
@keyframes move{
0%{transform:translateX(0)}
100%{transform:translateX(800px)}
}
.c_move{animation:move 4s linear both} /*both:運動結(jié)束后停留在終點*/
這個發(fā)揮作用主要是在定義了無限循環(huán)動畫時。

基礎(chǔ)的設(shè)置自然帶來毫無特色平淡無奇的基礎(chǔ)動效。
2.延遲開始
下面,我想讓圓圈在起點停留2s后再開始移動,第一反應(yīng)是用動畫屬性中的延遲 animation-delay ,把時間定義成2s,行不行?行,但這里用個更高級的方法。我們在定義關(guān)鍵幀時用了大量的百分比,這里百分比值代表的是 時間節(jié)點 ,也就是說 關(guān)鍵幀定義的是不同時間節(jié)點的狀態(tài)屬性。 下面再來看一張圖,這張圖一定不要和上面的路徑演示弄混了,這是一張動畫的時間軸的圖。

讓圓圈在起點停留2s那是表象說法,轉(zhuǎn)化成我們的動畫定義語言,就是在4s動畫周期內(nèi)前2s是沒有動畫效果的。所以,動畫規(guī)則我來這樣定義:
@keyframes move{
0%{transform:translateX(0)}
50%{transform:translateX(0px)}
100%{transform:translateX(800px)}
}
對照上面時間軸的分割來看,更容易理解一些,這樣就得到了在起點處停留2s后,在后面的2s完成整個動畫的動效。這里亦或用一種更簡單的寫法為 0%, 50%{transform:translateX(0)} ,屬性相同的可以合并在一起,用逗號分隔。 case-關(guān)鍵幀演示-延遲開始
3.提前結(jié)束
有了延遲開始的基礎(chǔ),提前結(jié)束是不是已經(jīng)可以類推出來了。為了區(qū)分一下,我讓動畫提前3s結(jié)束。照例先畫出時間軸的解析。

對應(yīng)關(guān)鍵幀的定義如下:
@keyframes move{
0%{transform:translateX(0)}
25%,100%{transform:translateX(800px)}
}
最終結(jié)果圓圈一定是4倍速度全力以赴加速完成旅程(畢竟要把原來4s的時間壓縮到1s完成),然后怡然自得的在終點等待整個動畫時間結(jié)束。 case-關(guān)鍵幀演示-提前結(jié)束
4.中途停留
那些已準(zhǔn)備妥當(dāng)?shù)捏A站,現(xiàn)在可以發(fā)揮作用了,我希望圓圈這樣運動:整個旅程中僅在第一個驛站(移動200px后)停留1s,稍作整頓。映射到時間軸上是什么樣子的呢?

這里,出現(xiàn)了一些看上去很奇怪的數(shù)字,需要解釋一下。先來明確一點,我們分析時間軸,最終要獲得是時間節(jié)點。針對我們的設(shè)計,停留1s,那運動的時間就是3s,而這3s的時間是分成兩部分的,第一部分是前200px,第二部分是后600px,因為是線性勻速,所以當(dāng)時間軸分成A+B+C三部分后,在A時間段跑完200px,在C時間段跑完600px,計算出A對應(yīng)的時間0.75s,C對應(yīng)的時間2.25s,B的時間是停留的時間1s,再換算成對應(yīng)的百分比,這就是最終中間兩個時間節(jié)點的計算方法。時間軸解析完成后,CSS部分的定義手到擒來:
@keyframes move{
0%{transform:translateX(0)}
18.75%, 43.75%{transform:translateX(200px)} /*對應(yīng)停留的1s*/
100%{transform:translateX(800px)}
}
5.像蟲洞一樣跳躍式前進
增加些難度,在中途任意點作停留已經(jīng)不是什么問題了,停留在一個點和多個點是相同的思路,現(xiàn)在,我讓圓圈跳躍式前進,進入第一個驛站后,停留1s,跨過第二個驛站,直接進入第三個驛站,停留1s,完成旅程。根據(jù)空間折疊原理,200和600處發(fā)生了躍遷。分析時間軸:

重點看紅色的部分,那里就是躍遷的時間點,在無時間變化的情況下位移了200px。按照時間軸的分析,CSS部分理論上是這樣的:
@keyframes move{
0%{transform:translateX(0)}
25%,50%{transform:translateX(200px)}
50%,75%{transform:translateX(600px)}
100%{transform:translateX(800px)}
}
效果如何呢?

完全和想象的不一樣,問題出在哪里呢?就是時間的50%節(jié)點處,瀏覽器可不知道你真實的想法,它只會以為你定義錯了,當(dāng)有兩個相同的50%的關(guān)鍵幀的不同屬性值定義時,會自動忽略第一個,而以最后一個有效值為準(zhǔn),所以上面的定義相當(dāng)于給瀏覽器傳達的訊息是這樣的:
@keyframes move{
0%{transform:translateX(0)}
25%{transform:translateX(200px)}
50%,75%{transform:translateX(600px)} /*在位移600px后停留1s*/
100%{transform:translateX(800px)}
}
這就是為什么看上去是到達第一驛站后加速跑向第三個驛站,然后停留后再完成剩下的路程的原因?,F(xiàn)在游戲越來越有意思了,或許我們可以試試 騙過瀏覽器 。既然同樣的時間點只允許定義一個屬性值,那如果我在緊鄰的旁邊增加一個時間點來定義,會發(fā)生什么?
@keyframes move{
0%{transform:translateX(0)}
25%,50%{transform:translateX(200px)}
50.0001%,75%{transform:translateX(600px)}
100%{transform:translateX(800px)}
}
看上面出現(xiàn)的**50.0001%**這個時間點,猜猜發(fā)生了什么?這就是上面所謂的“騙過瀏覽器”的方法了。在50%→50.0001%這個區(qū)間,發(fā)生了400px(200→600)的位移變化。所以就得到了下面這種效果:case-關(guān)鍵幀演示-躍遷

從原理上來講,這是一種視覺欺騙,在極短的時間內(nèi)在兩個位置間發(fā)生位移,因為時間短到可以忽略,所以會有一種跳躍的假象。
總結(jié)
看完上面的幾種代表性實例,是不是對關(guān)鍵幀的定義有了一個全新的認(rèn)識,你可能會覺得對于“延遲開始”和“提前結(jié)束”這兩種需求,是完全可以通過定義延遲時間以及動畫周期的時間來達到相同的效果的,但是,對于一個無限循環(huán)的動效而言,延遲開始永遠只作用一次,當(dāng)動畫一旦開始進入周而復(fù)始的循環(huán)后,不再支持這個屬性設(shè)置。因此,如果可以的話,盡量用關(guān)鍵幀的定義來完成。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
- 這篇文章主要介紹了CSS3 @keyframes簡單動畫實現(xiàn)的相關(guān)資料,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-24
CSS3中的@keyframes關(guān)鍵幀動畫的選擇器綁定
@keyframes可以幫助我們進行類似Flash中的關(guān)鍵幀動畫制作,這里我們來簡單討論一下CSS3中的@keyframes關(guān)鍵幀動畫的選擇器綁定,需要的朋友可以參考下2016-06-13@keyframes規(guī)則實現(xiàn)多重背景的CSS動畫
這篇文章主要介紹了@keyframes規(guī)則實現(xiàn)多重背景的CSS動畫,代碼中使用的是效果圖中顯示的素材,僅作為腳本示例在此便不提供下載了,需要的朋友可以參考下2015-08-05- CSS3新增動畫屬性“@keyframes”,從字面就可以看出其含義——關(guān)鍵幀,這與Flash中的含義一致。利用CSS3制作動畫效果其原理與Flash一樣,我們需要定義關(guān)鍵幀處的狀態(tài)效果,2014-09-02

快速解決css使用@keyframes加載圖片首次循環(huán)時出現(xiàn)白色間隙問題(閃屏)
這篇文章主要介紹了快速解決css使用@keyframes加載圖片首次循環(huán)時出現(xiàn)白色間隙問題(閃屏),本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以2020-02-25


