【切圖仔平常】淺談CSS3動畫之凌波微步--steps()

背景

一日敲代碼的我,獲得一個需求:寫一個10秒的倒計時。css

用JavaScript定時器麻溜寫完以後,剛好同事勇司機接完水。瞟了一眼,而後湊過來講,這個用CSS3也能夠寫,並且一行JavaScript都不用寫。前端

"一行JavaScript都不用寫,純CSS3就能夠寫。CSS3有這麼溜的操做!"git

''對呀!CSS3 animation當中有一個steps(),你上網查一下就知道了!"github

"漲姿式了!趕忙查閱一下!"web

animation-timing-function

CSS animation-timing-function屬性定義CSS動畫在每一動畫週期中執行的節奏。可能值爲一或多個timing function(數學函數)對於關鍵幀動畫來講,timing function做用於一個關鍵幀週期而非整個動畫週期,即從關鍵幀開始開始,到關鍵幀結束結束。 定義於一個關鍵幀區塊的緩動函數(animation timing function)應用到改關鍵幀; 另外,若該關鍵幀沒有定義緩動函數,則使用定義於整個動畫的緩動函數。 --MDN Web 文檔segmentfault

當看到這一長串的CSS3屬性,相信有部分童鞋們確定會陌生這個屬性。由於當時我第一眼看到也是一臉問號,表示只熟悉前面的animationbash

animation-timing-function其實不記得很正常,這個屬於animation的單獨一個屬性,就比如background-image這種css屬性你們不多單獨使用,爲了書寫代碼方便而更多使用background: url('test.png') center no-repeat;這種簡寫定義整個背景。網絡

同理在你們對於animation使用過程中,廣泛採用animation: move 5s infinite ease both;這種類簡寫定義整個動畫屬性。這樣的簡寫模式,簡潔、高效何樂不爲呢。函數

引用XXXschool網站截圖

借用XXXschool網站上給的使用方法,可是並無找到咱們想要的 steps()。因此讓咱們切換到MDN上面的看一下屬性介紹:工具

MDN語法相關參數

當我切換到MDN上面就能夠看到語法介紹上面有steps(),並且總體數量級別也不是一點差異,描述很是詳細。

PS: 固然可能這XXXschool上面更新可能比較慢一點,可是做爲日用簡單的查詢仍是能夠用,深刻研究探索仍是建議去MDN、W3.org相關網站上面查閱。

緩動函數與階梯函數

總的來講animation-timing-function基本就是分爲兩大類型函數:

一、緩動函數:

它描述了在一個過渡或動畫中一維數值的改變速度。這實質上讓你能夠本身定義一個加速度曲線,以便動畫的速度在動畫的過程當中能夠進行改變。緩動函數指定動畫效果在執行時的速度,使其看起來更加真實。

例如現實物體照着必定節奏移動,並非一開始就移動很快的。當咱們打開抽屜時,首先會讓它加速,而後慢下來。當某個東西往下掉時,首先是越掉越快,撞到地上後回彈,最終才又碰觸地板。

前端作過渡的動畫大部分都是採用的是這個緩動函數,比較書面一點稱呼就是:**立方貝塞爾曲線(cubic Bézier curves)**的子集

立方貝賽爾曲線

這裏就不繼續述說緩動函數了,若是各位小夥伴感興趣推薦兩個網站供小夥伴折騰:

緩動函數速查表 貝塞爾曲線在線生成工具

二、階梯函數

數學中,一個實數函數被稱爲階段函數(或者階梯函數),則它能夠被寫做:有限的間隔指標函數的線性組合。不正規的說法是,一個階段函數就是一個分段常值函數,只是含有的階段不少可是有限。 --wiki百科

圖片來自wiki百科

看完這些書面化的介紹,學渣的洪荒以內爆發了,搞一個steps()要這麼難搞?

steps()屬性

吃包辣條壓壓驚,查找資料繼續翻閱文檔。幾番查找,大體整理以下:

首先緩動函數就像一我的走路同樣,一樣的一段路。他能夠迅速的走過去,也能夠快速的跑過去,也能夠跑一半的距離而後再走過去。因此不管如何控制咱們選用那一種運動方式,移動到始終都是靠這我的雙腿一步步移動完成的。

而階梯函數就像一個失去雙腿,可是卻意外得到瞬間移動的人。他能夠瞬間移動終點,他也能夠瞬間移動一半距離,而後再瞬移到終點。因此階梯函數着重控制的分幾回瞬移完成。

是否是有那麼一點感受,不像剛纔那個看到函數那麼的頭疼了!

基本語法:steps(<integer>[, [ start | end ] ]?)

參數一:integer中文意思就是整數,由此說明第一個參數是整數。主要用來指定函數間隔的數量,且必須是正整數(大於0)。 參數二: 可選 ,接受 startend 兩個值,指定在每一個間隔的起點或是終點發生階躍變化,默認爲 end

Keyword values : start-stepend-step 另外相信記憶力比較好的童鞋,這個時候會注意到上述兩個關鍵詞。 step-start等同於steps(1,start),動畫分紅1步,動畫執行時爲開始左側端點的部分爲開始; step-end等同於steps(1,end):動畫分紅一步,動畫執行時以結尾端點爲開始,默認值爲end

這時借用W3.org文檔提供的圖表來看,對比wiki的圖表來看,結合個人說明此時小夥伴們的思路應該會更加清晰。

圖片來自w3.org

動畫卡通人物:

扯了半天的理論,沒有實際的案例估計小夥伴們也記不住這些東西,那麼先來一個栗子!

敲黑板,趕忙麻溜的回神

各大網站大體逛了一下,發現SegmentFault網站上有位哥們翻譯國外寫teps()裏面插入的案例不錯,其中一個例子用來幫助整理和學習很是的不錯。

傳送門:【譯】css動畫裏的steps()用法詳解

以下一幅圖是由10個小可愛卡通人物組成的,那麼咱們的任務就是讓這個卡通人物動起來。

雪碧動畫圖

思路分析:

整幅圖是由10個相同大小的矩形組成,每個矩形都剛好完整包裹卡通人物,一個標準完美的雪碧圖。接下來就將這個雪碧圖做爲背景插入展現的DIV盒模型當中。(PS:這個DIV盒模型與小矩形的寬高同樣)

以後經過background-position去控制雪碧圖位置定位,例如、0s顯示默認第一個動做,而後100ms以後,background-position,瞬間改版了X軸方向,顯示的第二個動做,而後又過了100ms,又展現第三張圖片。依次類推,利用人眼的視覺暫留從而造成動畫的效果。

視覺暫留(Persistence of vision)   現象是光對視網膜所產生的視覺在光中止做用後,仍保留一段時間的現象,其具體應用是電影的拍攝和放映。緣由是由視神經的反應速度形成的。是動畫、電影等視覺媒體造成和傳播的根據。視覺其實是靠眼睛的晶狀體成像,感光細胞感光,而且將光信號轉換爲神經電流,傳回大腦引發人體視覺。感光細胞的感光是靠一些感光色素,感光色素的造成是須要必定時間的,這就造成了視覺暫停的機理。 --摘自網絡

因此拋開重複的兼容代碼,10行左右代碼的就能實現一個動畫。

.hi {
    width: 50px;
    height: 72px;   // 矩形的寬高
    background-image: url("http://s.cdpn.io/79/sprite-steps.png"); 
    animation: play .8s steps(10) infinite;  // 分10步完成0到-500px完成並沒有限重複
}
@keyframes play {
   from { background-position:    0px; }
     to { background-position: -500px; }
}
複製代碼

最終效果圖:

招手小人.gif

僅僅是代碼上就應該比JavaScript要簡潔的多,是否是感受開啓了新的世界大門!

倒計時案例:

理論 + demo 都看了一遍,那麼就開始解決實際工做需求:用steps()函數敲一個倒計時demo出來。

平常需求

思考點:

經過需求來看,這個10秒倒計時須要控制到10ms的級別.第四位數,每10ms變化一次。而後第三位數每間隔100ms變化一次,第二位數字每間隔1s變化一次,第一位數字不去作變化。

理清楚思路以後就好辦了,接下來code部分了。

在敲代碼以前,先作好一張等比距離的雪碧圖:

需求雪碧圖

PS:由於以前的需求是作成的一張白色透明圖片,而文章背景顏色比較淡。因此臨時截了一個黑色背景圖做爲參考

HTML代碼:

<div class="time">
        <div class="s10 num"></div>
        <div class="s0 num"></div>
        <div class="spot">:</div>
        <div class="ms0 num"></div>
        <div class="ms10 num"></div>
</div>
複製代碼

CSS代碼:

.time {
	/*display: none;*/
	position: absolute;
	top: 2.05rem;
	left: 4.73rem;
	width: 3.22rem;
	height: 0.57rem;
	transform: scale(2);
}

.num {
	position: absolute;
	top: 0.2rem;
	width: 0.28rem;
	height: 0.37rem;
	background: url(img/timeNum.png) no-repeat center;
	background-size: cover;
	background-position: 0 0;
}

.spot {
	position: absolute;
	top: 0.06rem;
	left: 1.70rem;
	color: #fff;
	font-size: 24px;
	line-height: 0.57rem;
}

.s10 {
	left: 0.9rem;
}

.s0 {
	left: 1.25rem;
	-webkit-animation: sMove 10s steps(10, start);
}

.ms0 {
	left: 2rem;
	-webkit-animation: sMove 1s  steps(10, start) infinite;
}

.ms10 {
	left: 2.3rem;
	-webkit-animation: sMove 100ms steps(10, start) infinite ;
}

@-webkit-keyframes sMove {
	0% {
		background-position: -2.80rem 0;
	}
	100% {
		background-position: 0 0;
	}
}
複製代碼

最終效果圖:

Css3倒計時.gif

經過代碼能夠看到除去CSS代碼當中同樣基本的樣式部分。s0ms0ms10這三個元素基本的animation部分基本都是同樣,只是完成的時間以及和循環的次數不同。是否是感受難以想象,這麼簡單飄逸就搞定了?沒錯,就是那麼飄逸!

完成時間差別: 由於雪碧圖有10個數字,一次只是展現1/10,因此要分10步才能完成一張圖的循環。那麼如同以前的思路分析ms10走一步須要10ms,走完一個循環10步就須要100ms,ms0就須要1s走完一個循環,s0就須要10s才能走完一個循環。

循環次數 有小夥伴ms10ms0可能會問,爲何不給定相應的循環次數,而是給無限循環呢。固然給你固定的參數也是能夠,我之因此給這個無限循環次數,是由於我偷懶不想算他們的循環次數。

我更習慣給s0加一個監聽事件webkitAnimationEnd,由於s0沒有指定循環次數因此默認值爲循環一次,當s0動畫執行完畢以後,我只須要監聽webkitAnimationEnd便開始下一段程序。

小結:

好了!以上就是鄙人對於CSS3動畫當中steps()一點簡單理解,權當拋了一下磚頭引大神們的玉。後續如何用steps()玩出各類花樣就看各位看官本身了!

原創文章,文筆有限,才疏學淺,文中如有不正之處,再次再次再次歡迎各位啪啪的打臉賜教。(有句話說的好,重要的詞得說三遍。)

PS:對於裏面完整blogDemo代碼感興趣的,能夠從本人github上閱覽。 源碼demo傳送門地址

我的敲鼓

我是車大棒,我爲我本身插眼。

相關文章
相關標籤/搜索