當(dāng)多個動畫同時運行,我們想他們錯開一點。這時可以用 animation-delay ,但你不一定想用戶訪問頁面時,他們要等待延遲看到某些元素不動的情況。
這時,將 animation-delay 設(shè)置成一個負(fù)數(shù),它就會跳過幾秒直接進入動畫,因此顯示器顯示時所有的動畫都是運行狀態(tài)。當(dāng)動畫有相同的的關(guān)鍵幀動畫(keyframe values)而只是運動延遲時間不同,這個方法就可以大展身手了。
當(dāng)然,使用該概念進行調(diào)試也是不錯的選擇。設(shè)置 animation-play-state; 然后調(diào)整不同負(fù)時間的延遲。你會看到動畫在運動中的不同暫停狀態(tài)。
.thing { animation: move 2s linear infinite alternate; animation-play-state: paused; animation-delay: -1s;}
例:
在下面這個有趣的演示中,我們讓兩個機器人在一個稍微不同的時間移動,從而讓動畫更自然。這里也是給紫機器人使用負(fù)延遲來運行動畫,這樣用戶看到頁面時他已經(jīng)在運動了。
為了獲得最好的性能,您還應(yīng)該使用 transform 來進行移動和變換,從而節(jié)省重繪margin / top / left 之類的成本。 Paul Lewis做了一個 CSS Triggers 的列表來表示這些消耗。如果你想移動的東西有多種變換,那么也會有一些問題對應(yīng)而來。
其中一個大問題就是他們的順序。 transform 不會像人們預(yù)計的那樣同時運行,而是像訂單一樣操作(有一定的先后順序)。先運行的是最右邊最遠的一個,然后向內(nèi)。例如,在下面的代碼里,縮放會先執(zhí)行(scale),然后變換(translate),最后旋轉(zhuǎn)(rotate)。
@keyframes foo { to { /* 第三 第二 第一 */ transform: rotate(90deg) translateX(30px) scale(1.5); }}
然而在大多數(shù)情況下這并不是理想情況,有時候你寧愿他們同時運動。此外,當(dāng)你開始在多個 keyframe 里同時使用 transform 的值時候情況會變得更加復(fù)雜,像這樣:
@keyframes foo { 30% { transform: rotateY(360deg); } 65% { transform: translateY(-30px) rotateY(-360deg) scale(1.5); } 90% { transform: translateY(10px) scale(0.75); }}
然后就有一些奇怪的,出乎意料的事情發(fā)生了。不幸的是,解決這個問題的答案通常是嵌套多個< div >,每個用一種 translation ,這樣才不會出現(xiàn)沖突。
像這樣:
當(dāng)然也有一些解決方法,比如使用矩陣變換(不是直觀的手工代碼)或使用一個JavaScript動畫API,如 GreenSock ,它可以讓你不需要使用有序的序列來插入多個變換。
多使用個div也可以解決SVG的一些問題。例如在safari中,你不能在一個動畫中同時聲明透明度(opacity)和轉(zhuǎn)換(transform),不然其中一個肯定無效。
2015年8月初,獨立的變換聲明( ndependent transform declarations )已經(jīng)加入到了Chrome的Canary版本中。這意味著我們不用擔(dān)心用更多的變換效果,可以分別聲明 rotate , translate 和 scale 。
## 使用DevTools的時間控制器
無論是chrome還是firefox現(xiàn)在都有一些專門用于調(diào)試動畫的工具,比如可以控制動畫速度的滑塊,暫停按鈕和一些簡單數(shù)值的UI測試(UI for working with the easing values),通過放慢速度,暫停來觀察動畫的特殊點,是CSS動畫中的一個非常有用的調(diào)試方法。
兩個瀏覽器都使用Lea Verou的 cubic-bezier.com 的可視化GUI。因此我們就不用反復(fù)去cubic-bezier.com調(diào)整再修改文本編輯器中的代碼了。
這些工具讓我們更直觀的調(diào)整動畫,來看看兩個瀏覽器的界面:
chrome和firefox不僅可以控制動畫時間(加速或者減速),還可以使用自定義動畫。更為先進的時間軸工具也 即將chrome發(fā)布( youtube視頻需翻墻) ,它可以同時觀看多個元素。畢竟,一次只能處理一個元素實在是動畫調(diào)整中一個不小的限制。
還有一個麻煩就是如果動畫的存在時間很短很快我就很難抓取到了,所以通常要對其設(shè)置 animation-iteration-count: infinite; ,才能不用太在意時間繼續(xù)調(diào)試。
當(dāng)然還有一些額外的工具去幫助我們讓動畫在瀏覽器中慢下來以此調(diào)整,回放。它允許你從根本上分開每個動作,觀察元素之間的相互影響以及他們的運動狀態(tài)。當(dāng)你改變它的速度使其變流暢,整體效果也會更加出色的。
## 使用JavaScript調(diào)試CSS動畫事件
如果你不想去計算動畫到底是什么時間什么地方出錯了,你可以在事件觸發(fā)時用一點點的javascript來調(diào)試,將其添加到 animationstart , animationiteration 和 animationend 事件上。
例如:
我經(jīng)??吹接行┤嗽趉eyframe的0%和100%中聲明相同的屬性值,這是完全沒必要的而且會讓代碼變得很臃腫。瀏覽器將默認(rèn)屬性值作為初始值和結(jié)束值。
像這樣子就是太腫了:
.element { animation: animation-name 2s linear infinite;} @keyframes animation-name { 0% { transform: translateX(200px); } 50% { transform: translateX(350px); } 100% { transform: translateX(200px); }}
正確的寫法:
.element { transform: translateX(200px); animation: animation-name 2s linear infinite;} @keyframes animation-name { 50% { transform: translateX(350px); }}
創(chuàng)造簡潔漂亮的動畫通常意味著寫一個具體的 cubic-bezier() 函數(shù)。調(diào)整Easing函數(shù)的工作類似于公司的調(diào)色板。你可以在運動中擁有屬于自己個性的標(biāo)志和“聲音”。如果你想在整個網(wǎng)站中使用(為了保持統(tǒng)一,你應(yīng)該這樣做),最簡單的方法是將一個或兩個Easing函數(shù)存儲在一個變量中,就像我們將顏料混合在調(diào)色板里。使用SASS或者其他的于處理器可以讓其更簡單:
//scss$smooth: cubic-bezier(0.17, 0.67, 0.48, 1.28); .foo { animation: animation-name 3s $smooth; } .bar { animation: animation-name 1s $smooth; }
當(dāng)使用css的keyframe來做動畫時我們希望盡可能用到GPU的性能,這就意味著如果你有多個動畫你想更容易的DOM操作給接下來要加載的運動和懶加載的元素。你可以用CSS中的標(biāo)準(zhǔn)聲明塊讓硬件加速原生的DOM(不是SVG)。復(fù)用元素的動畫是有意義的,這里使用mixin:
@mixin accelerate($name) { will-change: $name; transform: translateZ(0); backface-visibility: hidden; perspective: 1000px;}.foo { @include accelerate(transform);}
當(dāng)心,一次性轉(zhuǎn)移太多元素可能會造成相反的效果并影響其性能。大多數(shù)動畫應(yīng)該正常,但是要如果你使用類似haml之類的標(biāo)記語言來生成大量DOM元素時候要注意。
Smashing Magazine最近發(fā)表的一個工作之余的神奇項目, http://species-in-pieces.com/ 。在一個特定的部分,作者討論了關(guān)于動畫細(xì)節(jié),其碎片導(dǎo)致的性能問題。他說:
假設(shè)你正在同時移動三十個物體,瀏覽器就要處理很多東西,然后或許就會有一些問題出現(xiàn)。如果你每個元素有0,199秒的速度和0.2秒的延遲,你可能會一次移動一個元素來修復(fù)這些問題。事實上,相同的運動并沒必要重復(fù)產(chǎn)生。如果動畫是一個鏈,性能是立即提高了30倍。
@for $i from 1 through $n { &:nth-child(#{$i}) { animation: loadIn 2s #{$i*0.11}s $easeOutSine forwards; }}
不僅如此,您可以使用它們來產(chǎn)生像顏色交錯的視覺效果。(點擊回放重新運行動畫。)
當(dāng)你在創(chuàng)建長動畫時,我們通常將其排列成鏈?zhǔn)健n愃?
animation: foo 3s ease-in-out, bar 4s 3s ease-in-out, brainz 6s 7s ease-in-out;
但是我們想想當(dāng)你優(yōu)化的時候,你發(fā)現(xiàn)你想改變動畫的第二個屬性值,這會影響接下來的它之后的所有元素,所以當(dāng)我們調(diào)整之后。好像沒什么大問題:
animation: foo 2.5s ease-in-out, bar 4s 2.5s ease-in-out, brainz 6s 6.5s ease-in-out;
現(xiàn)在讓我們添加另一個動畫也要再次進行調(diào)整(好的動畫產(chǎn)生之前這種微調(diào)似乎是必然的),于是事情的效率好像就有點低了。當(dāng)你這么做了3次,真的就非常低效率。
接著你可以想象一下如果你有兩個動畫并且要讓他們保持一致…嗯你理解就好。這就是為什么每當(dāng)當(dāng)鏈?zhǔn)絼赢嬓Ч饺齻€或四個,我就會使用JavaScript了。就個人而言,我比較喜歡 GreenSock animation API 因為它有非常強健的時間軸功能,但是很多JS允許你在不重新計算的情況下使用簡單的堆棧動畫創(chuàng)造工作流。
制作一個動畫不僅僅是構(gòu)建起來。通常情況下,它是人們通過編輯精煉和調(diào)試從而讓一個項目從一個只是精心策劃過的的運動變成一個有更好的性能的動畫。希望這些建議能夠成為你工具箱的工具,使你工作起來更加順暢。
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com