上一篇中咱們熟悉五種內置的緩動曲線和(三次)貝塞爾曲線,而且基於此完成了緩動效果.css
可是若是咱們想要實現逐幀動畫,基於貝塞爾曲線的調速函數就顯得有些無能爲力了,由於咱們並不須要幀與幀之間的過渡狀態
,就像上篇中所看到的,全部基於貝塞爾曲線的調速函數都會在關鍵幀之間進行插值運算,從而產平生滑的過渡效果。html
這個特性顯然很棒,平滑的效果確實是咱們使用css過渡和動畫所追求的。css3
可是在逐幀動畫的場景下,這種平滑的特性偏偏毀掉了咱們想要實現的逐幀動畫的效果.瀏覽器
咱們常常會看到一段卡通影片、一個複雜進度的提示框、一個小loading,
咱們不會單純的選擇一張GIF動畫勝任,由於它的侷限性和短板表現的很明顯.函數
寫在前面中提到,咱們不能基於貝塞爾曲線的調速函數完成咱們所須要的逐幀動畫,那麼採用什麼調速函數呢?字體
對,答案就是steps()
調速函數,與貝塞爾曲線迥然不一樣的是,steps()
會根據你指定的步進數量,把動畫分爲不少幀,並且整個動畫會在幀與幀之間硬切
,不會像貝塞爾曲線那樣作插值處理。動畫
經過上圖咱們能夠很明顯看出steps(8)、linear和ease的區別.網站
其實這種硬切效果是咱們極力避免的,所以咱們也不多聽到關於steps()
的討論。在CSS調速函數的世界裏,基於貝塞爾曲線
的調速函數就像是被人追捧的白天鵝,而steps()
則是旁人惟恐不及的醜小鴨。spa
其實無所謂好與很差,更多的是適合與不適合,咱們都崇拜的貝塞爾曲線在像小"loading"這樣的逐幀動畫中失敗了,而steps()
卻展現出咱們想要的效果.prototype
這個想法最初是Simurai在他的博客中推出http://simurai.com/blog/2012/12/03/step-animation,他使用steps()
實現拼合圖片的動畫效果.讓人印象深入
See the Pen Steps Animation by simurai (@simurai) on CodePen.
有時候,咱們但願一段爲本字符逐個顯示,模擬出一種打字的效果。這種效果在技術類網站中尤其常見,用等寬字體能夠營造出一種終端命令行的感受.
<h1>CSS is amazing!</h1>
@keyframes typing{ from{width:0} } h1{ width:7.7em; white-space:nowrap; overflow:hidden; animation:typing 8s; }
咱們想要模擬出一種打字效果,可是
咱們很天然的想到了使用steps()
來修復第一個問題,可是不幸的是,咱們所須要的步進數量是由字符的數量來決定的
CSS值與單位(第三版)
規範引入了一個新的單位,表示"0"字形的寬度。大多數場景下,咱們沒必要關心"0"字形的寬度到底有多寬,由於在等寬字體中,"0"字形的寬度和其餘全部字形的寬度是同樣的。所以,咱們若是使用ch單位來表示h1的寬度,那取值實際上就是字符的數量
:在上面的例子中就是15
@keyframes typing{ from{ width:0 } } @keyframes caret{ 50%{ border-color:transparent } } h1{ width:15ch; overflow:hidden; white-space:nowrap; border-right:0.5em solid; animation:typing 6s steps(15),caret 1s steps(1) infinite; }
可是咱們仍是有些疑問:
steps()
函數,這時候正是JavaScript的用武之地function $$(selector,context){ context = context||document; var elements = context.querySelector(selector); return Array.prototype.slice.call(elements); } $$('h1').forEach(function(h1){ var len = h1.textContent.length,s = h1.style; s.width = len + 'ch'; s.animationTimingFunction = "steps(" + len + "),steps(1)" })
這一篇主要基於steps()
函數和ch單位
,詳細的比較了steps()
調速函數和基於貝塞爾曲線調速函數的區別,雖然steps()
調速函數像是旁人惟恐不及的醜小鴨,可是它亦有其獨特的魅力。
參考資料