去年我們發(fā)布了 Gyroscope 以來,許多人問過我們做動(dòng)畫用的什么 JavaScript 庫(kù),我們也曾想過將它公布于眾,但實(shí)際上那并不是奧妙所在。
我們不想讓大伙兒覺得自己需要依賴特別黑魔法的 JavaScript 插件才能解決問題。大部分時(shí)候,我們都只要對(duì)最新的瀏覽器和 GPU 的性能和 css3 加以利用就夠了。
其實(shí)并沒有什么絢麗動(dòng)畫的武功秘籍,唯一的辦法就是花大量時(shí)間測(cè)試和優(yōu)化。但是,在經(jīng)過多年的試驗(yàn)和瀏覽器性能的極限考驗(yàn),我們發(fā)現(xiàn)了一些設(shè)計(jì)和編碼的原則可以有效地提升動(dòng)畫表現(xiàn)。這些技巧能夠使你的頁面流暢,并且能夠運(yùn)行在流行的臺(tái)式和移動(dòng)設(shè)備的瀏覽器上,最重要的一點(diǎn),它們還非常易于維護(hù)。
技術(shù)手段和實(shí)現(xiàn)方式可能因人而異,但是通用性的原則幾乎能無所不包。
在互聯(lián)網(wǎng)發(fā)明之前,動(dòng)畫就已經(jīng)所處可見了,可能你需要窮盡畢生之力才能學(xué)會(huì)如何將動(dòng)畫做得絢麗輝煌。然而,在互聯(lián)網(wǎng)中實(shí)現(xiàn)動(dòng)畫效果自有其獨(dú)特的限制和挑戰(zhàn)。
為了實(shí)現(xiàn)流暢的 60 幀的動(dòng)畫效果,每一幀都需要在 16 毫秒內(nèi)完成渲染!時(shí)間很短,所以我們需要找到最高效的方法去渲染每一幀內(nèi)容,從而實(shí)現(xiàn)流暢的表現(xiàn)。
一些經(jīng)典的動(dòng)畫設(shè)計(jì)原則
在網(wǎng)站上實(shí)現(xiàn)動(dòng)畫效果的方式多種多樣。比如,在互聯(lián)網(wǎng)出現(xiàn)之前隨處可見的電影膠片,它利用手繪的漸變的膠片,每秒鐘播放多幀來實(shí)現(xiàn)動(dòng)畫的錯(cuò)覺。
Twitter 在最近的心形動(dòng)畫中就利用了這種方法,通過膠片繪出一個(gè)轉(zhuǎn)動(dòng)的精靈。
這個(gè)效果也可以通過許多獨(dú)立的小元素動(dòng)畫來實(shí)現(xiàn),或者用 SVG 現(xiàn),但是那樣會(huì)過于復(fù)雜,并且可能不會(huì)這么流暢。
許多時(shí)候,你會(huì)想要使用 CSS 切換屬性來自動(dòng)實(shí)現(xiàn)元素改變的動(dòng)畫效果,這種技術(shù)被稱作“tweening”—因其是在兩個(gè)不同的屬性值之間切換(譯者注:tweening 來自 transitioning be_tween_ two different values)。它的好處是可以非常簡(jiǎn)單地取消或者替換掉而不用重新構(gòu)造邏輯內(nèi)容,這是完美的一勞永逸式的動(dòng)畫,像介紹序言等,或者如鼠標(biāo)懸停等簡(jiǎn)單的交互。
更多資料: All you need to know about CSS Transitions
其他時(shí)候,基于關(guān)鍵幀的 CSS 動(dòng)畫屬性會(huì)非常適合不斷變化的背景元素。舉個(gè)例子,陀螺儀中的圓環(huán)按會(huì)照預(yù)設(shè)持續(xù)轉(zhuǎn)動(dòng),還有其他能夠利用 CSS 動(dòng)畫的類型比如齒輪。
為了免于后顧之憂,希望以下這些建議能極大地提高你的動(dòng)畫效果:
動(dòng)畫中百分之八十的優(yōu)化會(huì)用到這項(xiàng)基本原則,即使是在移動(dòng)端也一樣。你或許以前聽過這個(gè)原則,這不是我提出來的,但是很少有人去遵守。這跟“管住嘴邁開腿”一樣,建議很好卻也最容易被忽略。
對(duì)已經(jīng)習(xí)慣了這種思路的人來說這非常簡(jiǎn)單,但是對(duì)那些習(xí)慣用傳統(tǒng)的 CSS 屬性去做動(dòng)畫的人來說,這會(huì)是一次質(zhì)的飛躍。
比如,你想讓某個(gè)元素小,你可以使用 transform:scale(),而不是改變寬度;如果你想移動(dòng)它,你可以使用簡(jiǎn)單的transform:translateX 或者 transform:translateY,從而替代亂糟糟的外補(bǔ)白(margin)或者內(nèi)補(bǔ)白(padding)?—?那些需要重建每一幀的頁面布局。
為什么要這么做呢?
對(duì)人類來說,改變寬度、外補(bǔ)白或者其他屬性不是什么大事?—?甚至因?yàn)楹?jiǎn)單會(huì)更讓人喜歡這么做?—?但是對(duì)電腦來說,這事兒就像天塌了一樣,甚至比這更糟糕。
瀏覽器投入了九牛二虎之力來優(yōu)化這些操作,切換屬性(transform)真的非常容易且高效,并且能夠充分利用顯卡,并且不用重新渲染元素。
第一次加載頁面的時(shí)候,你可能會(huì)覺得抓狂?—?處理所有圓角、引入圖像、給一切添加陰影,如果你毫不在乎那么甚至可以再做一個(gè)動(dòng)態(tài)羽化。如果這種情況只會(huì)發(fā)生一次,多一些計(jì)算時(shí)間也沒關(guān)系。但是一旦內(nèi)容渲染完成了,你絕對(duì)不會(huì)再想要重新加載!
更多內(nèi)容: Moving elements with translate (Paul Irish)
或許會(huì)有跨瀏覽器的警示,但是如果你只是面向 webkit 和其他流行的瀏覽器,它將會(huì)讓你如虎添翼。
很久以前,動(dòng)畫效果必須由 jquery 的 animate() 方法來處理,許多復(fù)雜的淡入淡出效果的處理是通過 display 的屬性值切換實(shí)現(xiàn)的。太早顯示,那么動(dòng)畫還沒完成,但是太晚的話就會(huì)在頁面上顯示一片空白,總是需要回調(diào)函數(shù)去給執(zhí)行完的動(dòng)畫擦屁股。
CSS 中的 pointer-events 屬性(盡管已經(jīng)存在很長(zhǎng)時(shí)間,但是不經(jīng)常使用)只是讓元素失去了點(diǎn)擊和交互的響應(yīng),就好像它們不存在一樣。它能通過 CSS 控制顯示或隱藏,不會(huì)打斷動(dòng)畫也不會(huì)影響頁面的渲染或可見性。
除了將 opacity 設(shè)置為零,它和將 display 設(shè)置為 none 具有相同的效果,但是不會(huì)觸發(fā)新的渲染機(jī)制。需要隱藏元素的時(shí)候,我會(huì)將它的 opacity 設(shè)置為 0 并將 pointer-events 設(shè)置為 off,然后就任由其自生自滅啦。
這樣做尤其適用于絕對(duì)定位的元素,因?yàn)槟隳軌蜃孕艥M滿地說他們絕對(duì)不會(huì)影響到頁面中的其他元素。
它有時(shí)也會(huì)劍走偏鋒,因?yàn)閯?dòng)畫的時(shí)機(jī)并不總那么完美?—?比如一個(gè)元素在不可見狀態(tài)下仍然可以點(diǎn)擊或者覆蓋了其他內(nèi)容,或者只有當(dāng)元素淡入顯示完全的時(shí)候才可以點(diǎn)擊,但是不要灰心,會(huì)有辦法解決的。(下文會(huì)提到解決辦法,譯者注)
單一的動(dòng)畫會(huì)很流暢,但是和其他許多動(dòng)畫一起也許就完全亂套了。編寫一個(gè)流暢的全員動(dòng)畫的例子很簡(jiǎn)單,但當(dāng)數(shù)量級(jí)上升到整個(gè)網(wǎng)站時(shí)性能就很難維持了。因此,合理安排好每個(gè)元素非常重要。
你需要將所有的時(shí)間節(jié)點(diǎn)安排好,來避免所有的動(dòng)畫內(nèi)容同時(shí)開始或進(jìn)行。典型的例子,2 或 3 個(gè)動(dòng)畫同時(shí)進(jìn)行可能不會(huì)出現(xiàn)卡慢的現(xiàn)象,尤其是在它們開始的時(shí)間略有不同的情況下。但是超過這個(gè)數(shù)量,動(dòng)畫就可能發(fā)生滯緩。
理解動(dòng)作編排這個(gè)概念非常重要,除非你的頁面真的只有一個(gè)元素。它貌似是舞蹈領(lǐng)域的東西,但是在動(dòng)畫界它同樣的重要。每個(gè)內(nèi)容都要在合適的方向和時(shí)機(jī)出現(xiàn),即使它們相互分離,但是它們要給人一種按部就班的感覺。
谷歌的 material design 有幾點(diǎn)關(guān)于動(dòng)作編排的有趣建議,雖然這并不是實(shí)現(xiàn)目標(biāo)的不二法門,但總有一些是你應(yīng)該去考慮和嘗試的。
更多內(nèi)容: Google Material Design · Motion
動(dòng)畫的編排非常重要,同時(shí)也會(huì)做大量的試驗(yàn)和測(cè)試才能恰如其分。然而,動(dòng)畫編排的代碼并不會(huì)非常復(fù)雜。
我通常會(huì)改變一個(gè)父元素(通常是 body)的 class 值來觸發(fā)一系列的改變,這些改變有著各不相同的切換延時(shí)以便能夠適時(shí)展現(xiàn)。單從代碼來看,你只需要關(guān)心狀態(tài)的變化,而不用擔(dān)心一堆時(shí)間節(jié)點(diǎn)的維持。
Gyroscope Chrome Extension 的動(dòng)畫
交錯(cuò)安排一系列的元素是動(dòng)畫編排的一種簡(jiǎn)單易行的方法,這種方法很有效,因?yàn)樗谛阅芰己玫耐瑫r(shí)還好看—但請(qǐng)記住你本想讓幾個(gè)動(dòng)畫同時(shí)發(fā)生的。你想把這些動(dòng)畫分布開來,讓每個(gè)都表現(xiàn)地流暢,而不是一下子太多動(dòng)畫從而顯得特別慢。適當(dāng)部分的重疊會(huì)看起來連續(xù)流暢而不是鏈?zhǔn)降膯为?dú)動(dòng)畫。
代碼示例
有一些很簡(jiǎn)單的技巧來錯(cuò)開你的元素—尤其是其中有非常多的內(nèi)容。如果頁面中有小于 10 項(xiàng)內(nèi)容,或者元素?cái)?shù)量可預(yù)估(比如靜態(tài)頁面),我通常會(huì)在 CSS 中指定特定的值。這是最簡(jiǎn)單易行的方法了。
一個(gè)簡(jiǎn)單的 SASS 循環(huán)
對(duì)更多的內(nèi)容或者動(dòng)態(tài)內(nèi)容來說,可以在循環(huán)中動(dòng)態(tài)地給每項(xiàng)內(nèi)容添加時(shí)間節(jié)點(diǎn)。
一個(gè)簡(jiǎn)單的 JavaScript 循環(huán)
有兩個(gè)典型的變量:基本延時(shí)和各個(gè)項(xiàng)目的延時(shí)。它很難協(xié)調(diào),但你一旦找到正確的值,效果將會(huì)非常完美。
動(dòng)畫設(shè)計(jì)中,時(shí)間節(jié)點(diǎn)就是一切。20% 的工作是用來實(shí)現(xiàn)效果,剩下的 80% 使用來尋找合適的參數(shù)和持續(xù)時(shí)間來讓一切在同時(shí)發(fā)生時(shí)顯得流暢。
尤其是在編排多個(gè)動(dòng)畫的時(shí)候,為了達(dá)到高性能和高共同性,觀察動(dòng)畫的慢動(dòng)作會(huì)讓一切工作變得非常容易。
無論你用的是 JavaScript 還是 CSS 預(yù)處理器比如 SASS(我們非常喜歡它),都需要簡(jiǎn)單地做一些額外的計(jì)算并且需要聲明一些有用的變量。
你必須確保它能夠非常容易地嘗試不同的速度或時(shí)間節(jié)點(diǎn)。舉個(gè)例子,如果一個(gè)動(dòng)畫效果在 1/10 的速度下還表現(xiàn)地結(jié)結(jié)巴巴,那么可能會(huì)有一些非常基礎(chǔ)的錯(cuò)誤。如果在放慢 50 倍的速率下表現(xiàn)流暢,假以時(shí)日定能找到運(yùn)行流暢的最大速度?;蛟S正常速度下 5 毫秒的差池很難被注意到,但是放慢速度,它就變得非常明顯了。
尤其是做非常復(fù)雜的動(dòng)畫分析,或者解決非常棘手的性能瓶頸,慢動(dòng)作查看元素會(huì)非常的有用。
重要的一點(diǎn)就是,在慢動(dòng)作下你會(huì)將非常多的細(xì)節(jié)優(yōu)化地完美,當(dāng)動(dòng)畫加速之后它將會(huì)給人完美無瑕的感覺。盡管這些都顯得微不足道,但是用戶會(huì)注意到動(dòng)畫效果的流暢和細(xì)節(jié)的。
只有 OS X 才有的功能—如果你 shift + 點(diǎn)擊最小化按鈕或者一個(gè)應(yīng)用圖標(biāo),你將會(huì)看見它在緩慢移動(dòng)。基于這一點(diǎn),我們甚至在陀螺儀上實(shí)現(xiàn)了這個(gè)功能,當(dāng)你按下 shift 鍵的時(shí)候?qū)?huì)激活慢動(dòng)作模式。
有時(shí)候不同的視角能夠幫助你對(duì)事物有更加清楚的認(rèn)識(shí),而錄像則是一種很好的方法。
有的人會(huì)用 AE 做視頻然后放到網(wǎng)站上,而我恰恰相反,我總是嘗試將網(wǎng)站界面錄制成很棒的視頻。
發(fā)布視頻其實(shí)門檻很高的。有一天我對(duì)做出來的東西感到非常激動(dòng),想記錄下來和朋友們分享。
然而,當(dāng)看第二遍的時(shí)候,我發(fā)現(xiàn)了一些瑕疵,時(shí)間節(jié)點(diǎn)設(shè)置得不那么恰當(dāng),并且出現(xiàn)了一個(gè)延遲尖峰。這讓我有點(diǎn)打退堂鼓了,我發(fā)現(xiàn)還有很多的內(nèi)容需要優(yōu)化,所以我不能就這么把視頻發(fā)送給朋友。
在使用過程中這些瑕疵都很容易被掩蓋,但是在視頻中一次次地觀看慢動(dòng)作的動(dòng)畫能夠讓一切問題都暴露地非常明顯。
有人會(huì)說拍攝出來和看起來的效果并不完全相同,但也許它變更加精確了呢。
這已經(jīng)成為我工作中很重要的一部分,我會(huì)觀看慢動(dòng)作的視頻并且修改任何我覺得不妥的地方。其實(shí)也可以很容易地將這類問題歸咎于瀏覽器性能差,但是再多優(yōu)化一點(diǎn)多測(cè)試一點(diǎn),這些問題就能夠得到解決。
等到你在視頻中不會(huì)發(fā)現(xiàn)非常尷尬的延遲尖峰,并且感覺視頻挺好的可以曬出來了,這個(gè)時(shí)候你的頁面就可以發(fā)布了。
圖片便是其中一個(gè)元兇,無論是幾個(gè)大圖片(大的背景圖)或者非常多的小圖(五十個(gè)頭像),或者非常多的內(nèi)容(一個(gè)從頭到尾有很多圖片的長(zhǎng)頁面)。
頁面首次加載的時(shí)候,許多的東西會(huì)被初始化并下載。其中內(nèi)容解析、廣告和其他第三方腳本會(huì)使性能變得更糟糕。有時(shí)候,將動(dòng)畫效果在頁面加載后延遲零點(diǎn)幾秒將會(huì)對(duì)性能有很大的提升。
如果沒有必要的話,不要過度優(yōu)化動(dòng)畫延遲,一個(gè)復(fù)雜的頁面要求非常精確的延遲和時(shí)間節(jié)點(diǎn)才能運(yùn)行流暢。通常你會(huì)想要在開始的時(shí)候加載盡可能少的數(shù)據(jù),當(dāng)主要內(nèi)容和介紹動(dòng)畫完成之后再繼續(xù)加載其他的內(nèi)容。
一個(gè)有很多數(shù)據(jù)的頁面,需要深思熟慮地加載所有內(nèi)容。一個(gè)在靜態(tài)頁面中表現(xiàn)良好的動(dòng)畫效果也許就會(huì)在實(shí)時(shí)數(shù)據(jù)的加載中變得緩慢。如果有些內(nèi)容仿佛應(yīng)該生效但卻沒有,或者不能一如既往地流暢表現(xiàn),我建議檢查一下網(wǎng)絡(luò)活動(dòng),確認(rèn)一下你是否也在同時(shí)處理其他的內(nèi)容。
基于滾動(dòng)的動(dòng)畫在前些年一段時(shí)間非?;鸨绕涫巧婕耙暡罨蛘咂渌匦У膬?nèi)容里。它們的設(shè)計(jì)模式是好是壞仍有待考證,但是在技術(shù)上有著良莠不齊的實(shí)現(xiàn)方法。
基于滾動(dòng)的動(dòng)畫中有一種非常流行的處理方式,即將滾動(dòng)一定距離作為事件處理同時(shí)觸發(fā)動(dòng)畫內(nèi)容。除非你對(duì)自己的行為了如指掌,否則我會(huì)建議不要使用這種方式,因?yàn)樗娴暮苋菀壮鲥e(cuò)并且很難維護(hù)。
更糟糕的情況是自定義滾動(dòng)條功能,而不用默認(rèn)的功能—又名 scrolljacking 。請(qǐng)不要這么想不開。
在這十項(xiàng)準(zhǔn)則中,這項(xiàng)尤其適用于移動(dòng)開發(fā),另外可能也是理想用戶體驗(yàn)的好的實(shí)踐。
如果你確實(shí)要求獨(dú)特的體驗(yàn)并且你希望它基于滾動(dòng)或者其他的特殊事件,我建議創(chuàng)建一個(gè)快速原型來實(shí)現(xiàn),而不是費(fèi)力不討好地去設(shè)計(jì)事件形式。
大多數(shù)的網(wǎng)站都是在電腦上搭建的,并且最常用本機(jī)做測(cè)試。因此,移動(dòng)端體驗(yàn)和動(dòng)畫性能就被次要考慮了。一些技術(shù)(比如 canvas)或者動(dòng)畫技術(shù)可能在移動(dòng)端表現(xiàn)地并不好。
然而,如果代碼寫得好優(yōu)化也到位(參考規(guī)則 #1),移動(dòng)端的體驗(yàn)甚至比電腦更加流暢。移動(dòng)端的優(yōu)化是一項(xiàng)非常棘手的事情,但是新的 iPhone 比手提電腦更快!如果你采用了前幾項(xiàng)建議,你將會(huì)得到一個(gè)非常棒的移動(dòng)端表現(xiàn)。
移動(dòng)端訪問網(wǎng)站將會(huì)變得非常非常的重要。我建議你專門拿一個(gè)星期的時(shí)間認(rèn)真地用手機(jī)查看你的網(wǎng)站,這或許有些極端,你可能會(huì)感覺像是在接受懲罰而被迫使用移動(dòng)端版本,但是你應(yīng)該調(diào)整好心態(tài)。
不斷優(yōu)化設(shè)計(jì)和提高性能,直到網(wǎng)站在移動(dòng)端的表現(xiàn)和在電腦上一樣優(yōu)美和方便。
如果你堅(jiān)持一周都用移動(dòng)端來訪問網(wǎng)站,你將會(huì)得到一個(gè)比電腦上更優(yōu)化體驗(yàn)更好的網(wǎng)站。即使在使用過程中遇到非常惱人的事情也是值得的,那意味著這些問題將在你的用戶體驗(yàn)到之前就被解決掉了!
除了移動(dòng)端和電腦之外還有很多因素能夠?qū)π阅墚a(chǎn)生極大的影響,比如是否是 “retina” 屏幕、窗口的分辨率、硬件的老舊程度等等。
即使 Chorme 和 Safari 都是基于 Webkit 的瀏覽器并且有著相似的語法,但是他們也有各自的特點(diǎn)。每一次 Chrome 升級(jí)都會(huì)修復(fù)一些問題同時(shí)也會(huì)引入新的 bug,所以你必須時(shí)刻保持警惕。
當(dāng)然,你不會(huì)只想著搭建一個(gè)對(duì)于所有瀏覽器放之四海而皆準(zhǔn)的網(wǎng)站,所以尋找一個(gè)靈活的方法以便于你能夠增加或者移除一些功能是非常有用的。
我通常會(huì)交替在較小的 MacBook Air 和大屏的 iMac 中使用網(wǎng)站,每次都會(huì)暴露出新的問題然后再修復(fù)?—?尤其是動(dòng)畫性能方面的問題,有時(shí)候也會(huì)有全局設(shè)計(jì)的題、信息密度、可讀性的問題等等。
Media queries 是一款非常強(qiáng)大的工具,它典型的用處是定位由于高度或者寬度造成的樣式差異,但是它同樣能夠用來根據(jù)分辨率添加目標(biāo)內(nèi)容或者其他屬性。另外,識(shí)別系統(tǒng)和設(shè)備類型的功能也是非常有用的,因?yàn)橐苿?dòng)設(shè)備的性能特征和電腦還是有很大區(qū)別的。
相關(guān)文章推薦《我的圖標(biāo)不僅好看,還有這四個(gè)作用》
填寫下面表單即可預(yù)約申請(qǐng)免費(fèi)試聽!怕錢不夠?可先就業(yè)掙錢后再付學(xué)費(fèi)! 怕學(xué)不會(huì)?助教全程陪讀,隨時(shí)解惑!擔(dān)心就業(yè)?一地學(xué)習(xí),可推薦就業(yè)!
?2007-2022/ m.mwtacok.cn 北京漫動(dòng)者數(shù)字科技有限公司 備案號(hào): 京ICP備12034770號(hào) 監(jiān)督電話:010-53672995 郵箱:bjaaa@aaaedu.cc