前言前端
週四晚是否被薛段子代言騰訊動漫的廣告刷了朋友圈呢?在一些產品介紹中爲了加強視覺效果,吸引用戶注意,也會搞不少動畫效果。那這些動畫效果有沒一些指導原則可讓咱們在這塊作的更好呢?今天由掘金翻譯計劃@王子建童鞋帶來的翻譯受權分享。web
正文從這開始~canvas
去年咱們發佈了 Gyroscope 以來,許多人問過咱們作動畫用的什麼 JavaScript 庫,咱們也曾想過將它公佈於衆,但實際上那並非奧妙所在。設計模式
咱們不想讓大夥兒以爲本身須要依賴特別黑魔法的 JavaScript 插件才能解決問題。大部分時候,咱們都只要對最新的瀏覽器和 GPU 的性能和 CSS3 加以利用就夠了。瀏覽器
其實並無什麼絢麗動畫的武功祕籍,惟一的辦法就是花大量時間測試和優化。可是,在通過多年的試驗和瀏覽器性能的極限考驗,咱們發現了一些設計和編碼的原則能夠有效地提高動畫表現。這些技巧可以使你的頁面流暢,而且可以運行在流行的臺式和移動設備的瀏覽器上,最重要的一點,它們還很是易於維護。微信
技術手段和實現方式可能因人而異,可是通用性的原則幾乎能無所不包。網絡
什麼是動畫?函數
在互聯網發明以前,動畫就已經所處可見了,可能你須要窮盡畢生之力才能學會如何將動畫作得絢麗輝煌。然而,在互聯網中實現動畫效果自有其獨特的限制和挑戰。工具
爲了實現流暢的 60 幀的動畫效果,每一幀都須要在 16 毫秒內完成渲染!時間很短,因此咱們須要找到最高效的方法去渲染每一幀內容,從而實現流暢的表現。佈局
一些經典的動畫設計原則
在網站上實現動畫效果的方式多種多樣。好比,在互聯網出現以前隨處可見的電影膠片,它利用手繪的漸變的膠片,每秒鐘播放多幀來實現動畫的錯覺。
Twitter 在最近的心形動畫中就利用了這種方法,經過膠片繪出一個轉動的精靈。
這個效果也能夠經過許多獨立的小元素動畫來實現,或者用 SVG 實現,可是那樣會過於複雜,而且可能不會這麼流暢。
許多時候,你會想要使用 CSS 切換屬性來自動實現元素改變的動畫效果,這種技術被稱做「tweening」—因其是在兩個不一樣的屬性值之間切換(譯者注:tweening 來自 transitioning be_tween_ two different values)。它的好處是能夠很是簡單地取消或者替換掉而不用從新構造邏輯內容,這是完美的一勞永逸式的動畫,像介紹序言等,或者如鼠標懸停等簡單的交互。
更多資料: All you need to know about CSS Transitions
其餘時候,基於關鍵幀的 CSS 動畫屬性會很是適合不斷變化的背景元素。舉個例子,陀螺儀中的圓環按會照預設持續轉動,還有其餘可以利用 CSS 動畫的類型好比齒輪。
爲了免於後顧之憂,但願如下這些建議能極大地提升你的動畫效果:
除了透明度(opacity)和切換(transform),不要改變任何屬性!
即使你以爲可行,那也別衝動!
動畫中百分之八十的優化會用到這項基本原則,即便是在移動端也同樣。你或許之前聽過這個原則,這不是我提出來的,可是不多有人去遵照。這跟「管住嘴邁開腿」同樣,建議很好卻也最容易被忽略。
對已經習慣了這種思路的人來講這很是簡單,可是對那些習慣用傳統的 CSS 屬性去作動畫的人來講,這會是一次質的飛躍。
好比,你想讓某個元素小,你可使用 transform:scale(),而不是改變寬度;若是你想移動它,你可使用簡單的 transform:translateX 或者 transform:translateY,從而替代亂糟糟的外補白(margin)或者內補白(padding) — 那些須要重建每一幀的頁面佈局。
爲何要這麼作呢?
對人類來講,改變寬度、外補白或者其餘屬性不是什麼大事 — 甚至由於簡單會更讓人喜歡這麼作 — 可是對電腦來講,這事兒就像天塌了同樣,甚至比這更糟糕。
瀏覽器投入了九牛二虎之力來優化這些操做,切換屬性(transform)真的很是容易且高效,而且可以充分利用顯卡,而且不用從新渲染元素。
第一次加載頁面的時候,你可能會以爲抓狂 — 處理全部圓角、引入圖像、給一切添加陰影,若是你絕不在意那麼甚至能夠再作一個動態羽化。若是這種狀況只會發生一次,多一些計算時間也不要緊。可是一旦內容渲染完成了,你絕對不會再想要從新加載!
更多內容: Moving elements with translate (Paul Irish)
用很是清楚的方式隱藏內容
使用 pointer-events 屬性:僅僅利用透明度隱藏元素
或許會有跨瀏覽器的警示,可是若是你只是面向 webkit 和其餘流行的瀏覽器,它將會讓你如虎添翼。
好久之前,動畫效果必須由 jQuery 的 animate() 方法來處理,許多複雜的淡入淡出效果的處理是經過 display 的屬性值切換實現的。太早顯示,那麼動畫還沒完成,可是太晚的話就會在頁面上顯示一片空白,老是須要回調函數去給執行完的動畫擦屁股。
CSS 中的 pointer-events 屬性(儘管已經存在很長時間,可是不常用)只是讓元素失去了點擊和交互的響應,就好像它們不存在同樣。它能經過 CSS 控制顯示或隱藏,不會打斷動畫也不會影響頁面的渲染或可見性。
除了將 opacity 設置爲零,它和將 display 設置爲 none 具備相同的效果,可是不會觸發新的渲染機制。須要隱藏元素的時候,我會將它的 opacity 設置爲 0 並將 pointer-events 設置爲 off,而後就職由其自生自滅啦。
這樣作尤爲適用於絕對定位的元素,由於你可以自信滿滿地說他們絕對不會影響到頁面中的其餘元素。
它有時也會劍走偏鋒,由於動畫的時機並不總那麼完美 — 好比一個元素在不可見狀態下仍然能夠點擊或者覆蓋了其餘內容,或者只有當元素淡入顯示徹底的時候才能夠點擊,可是不要灰心,會有辦法解決的。(下文會提到解決辦法,譯者注)
不要一次給全部內容都設置動畫
用動做編排加以替代
單一的動畫會很流暢,可是和其餘許多動畫一塊兒也許就徹底亂套了。編寫一個流暢的全員動畫的例子很簡單,但當數量級上升到整個網站時性能就很難維持了。所以,合理安排好每一個元素很是重要。
你須要將全部的時間節點安排好,來避免全部的動畫內容同時開始或進行。典型的例子,2 或 3 個動畫同時進行可能不會出現卡慢的現象,尤爲是在它們開始的時間略有不一樣的狀況下。可是超過這個數量,動畫就可能發生滯緩。
理解動做編排這個概念很是重要,除非你的頁面真的只有一個元素。它貌似是舞蹈領域的東西,可是在動畫界它一樣的重要。每一個內容都要在合適的方向和時機出現,即便它們相互分離,可是它們要給人一種循序漸進的感受。
谷歌的 material design 有幾點關於動做編排的有趣建議,雖然這並非實現目標的不二法門,但總有一些是你應該去考慮和嘗試的。
更多內容: Google Material Design · Motion
適當增長切換延時可以更簡單地編排動做
動畫的編排很是重要,同時也會作大量的試驗和測試才能恰如其分。然而,動畫編排的代碼並不會很是複雜。
我一般會改變一個父元素(一般是 body)的 class 值來觸發一系列的改變,這些改變有着各不相同的切換延時以便可以適時展示。單從代碼來看,你只須要關心狀態的變化,而不用擔憂一堆時間節點的維持。
Gyroscope Chrome Extension 的動畫
交錯安排一系列的元素是動畫編排的一種簡單易行的方法,這種方法頗有效,由於它在性能良好的同時還好看—但請記住你本想讓幾個動畫同時發生的。你想把這些動畫分佈開來,讓每一個都表現地流暢,而不是一會兒太多動畫從而顯得特別慢。適當部分的重疊會看起來連續流暢而不是鏈式的單獨動畫。
代碼示例
有一些很簡單的技巧來錯開你的元素—尤爲是其中有很是多的內容。若是頁面中有小於 10 項內容,或者元素數量可預估(好比靜態頁面),我一般會在 CSS 中指定特定的值。這是最簡單易行的方法了。
一個簡單的 SASS 循環
對更多的內容或者動態內容來講,能夠在循環中動態地給每項內容添加時間節點。
一個簡單的 JavaScript 循環
有兩個典型的變量:基本延時和各個項目的延時。它很難協調,但你一旦找到正確的值,效果將會很是完美。
在慢動做中使用增量設計
事後再加快動畫的速度
動畫設計中,時間節點就是一切。20% 的工做是用來實現效果,剩下的 80% 使用來尋找合適的參數和持續時間來讓一切在同時發生時顯得流暢。
尤爲是在編排多個動畫的時候,爲了達到高性能和高共同性,觀察動畫的慢動做會讓一切工做變得很是容易。
不管你用的是 JavaScript 仍是 CSS 預處理器好比 SASS(咱們很是喜歡它),都須要簡單地作一些額外的計算而且須要聲明一些有用的變量。
你必須確保它可以很是容易地嘗試不一樣的速度或時間節點。舉個例子,若是一個動畫效果在 1/10 的速度下還表現地結結巴巴,那麼可能會有一些很是基礎的錯誤。若是在放慢 50 倍的速率下表現流暢,假以時日定能找到運行流暢的最大速度。或許正常速度下 5 毫秒的差池很難被注意到,可是放慢速度,它就變得很是明顯了。
尤爲是作很是複雜的動畫分析,或者解決很是棘手的性能瓶頸,慢動做查看元素會很是的有用。
重要的一點就是,在慢動做下你會將很是多的細節優化地完美,當動畫加速以後它將會給人完美無瑕的感受。儘管這些都顯得微不足道,可是用戶會注意到動畫效果的流暢和細節的。
只有 OS X 纔有的功能—若是你 shift + 點擊最小化按鈕或者一個應用圖標,你將會看見它在緩慢移動。基於這一點,咱們甚至在陀螺儀上實現了這個功能,當你按下 shift 鍵的時候將會激活慢動做模式。
給你的用戶界面錄個像,而且在重複播放中獲得一個有價值的第三人視角的見解。
有時候不一樣的視角可以幫助你對事物有更加清楚的認識,而錄像則是一種很好的方法。
有的人會用 AE 作視頻而後放到網站上,而我偏偏相反,我老是嘗試將網站界面錄製成很棒的視頻。
發佈視頻其實門檻很高的。有一天我對作出來的東西感到很是激動,想記錄下來和朋友們分享。
然而,當看第二遍的時候,我發現了一些瑕疵,時間節點設置得不那麼恰當,而且出現了一個延遲尖峯。這讓我有點打退堂鼓了,我發現還有不少的內容須要優化,因此我不能就這麼把視頻發送給朋友。
在使用過程當中這些瑕疵都很容易被掩蓋,可是在視頻中一次次地觀看慢動做的動畫可以讓一切問題都暴露地很是明顯。
有人會說拍攝出來和看起來的效果並不徹底相同,但也許它變動加精確了呢。
這已經成爲我工做中很重要的一部分,我會觀看慢動做的視頻而且修改任何我以爲不妥的地方。其實也能夠很容易地將這類問題歸咎於瀏覽器性能差,可是再多優化一點多測試一點,這些問題就可以獲得解決。
等到你在視頻中不會發現很是尷尬的延遲尖峯,而且感受視頻挺好的能夠曬出來了,這個時候你的頁面就能夠發佈了。
網絡活動可能會形成延遲。
你應該預加載或者延遲處理很是大的 HTTP 請求
圖片即是其中一個元兇,不管是幾個大圖片(大的背景圖)或者很是多的小圖(五十個頭像),或者很是多的內容(一個從頭至尾有不少圖片的長頁面)。
頁面首次加載的時候,許多的東西會被初始化並下載。其中內容解析、廣告和其餘第三方腳本會使性能變得更糟糕。有時候,將動畫效果在頁面加載後延遲零點幾秒將會對性能有很大的提高。
若是沒有必要的話,不要過分優化動畫延遲,一個複雜的頁面要求很是精確的延遲和時間節點才能運行流暢。一般你會想要在開始的時候加載儘量少的數據,當主要內容和介紹動畫完成以後再繼續加載其餘的內容。
一個有不少數據的頁面,須要深思熟慮地加載全部內容。一個在靜態頁面中表現良好的動畫效果也許就會在實時數據的加載中變得緩慢。若是有些內容彷彿應該生效但卻沒有,或者不能一如既往地流暢表現,我建議檢查一下網絡活動,確認一下你是否也在同時處理其餘的內容。
不要直接綁定滾動事件。
貌似是個好主意,其實否則
基於滾動的動畫在前些年一段時間很是火爆,尤爲是涉及視差或者其餘特效的內容裏。它們的設計模式是好是壞仍有待考證,可是在技術上有着參差不齊的實現方法。
基於滾動的動畫中有一種很是流行的處理方式,即將滾動必定距離做爲事件處理同時觸發動畫內容。除非你對本身的行爲了如指掌,不然我會建議不要使用這種方式,由於它真的很容易出錯而且很難維護。
更糟糕的狀況是自定義滾動條功能,而不用默認的功能—又名 scrolljacking 。請不要這麼想不開。
在這十項準則中,這項尤爲適用於移動開發,另外可能也是理想用戶體驗的好的實踐。
若是你確實要求獨特的體驗而且你但願它基於滾動或者其餘的特殊事件,我建議建立一個快速原型來實現,而不是費力不討好地去設計事件形式。
儘早而且常常地在移動設備上的測試。
大多數的網站都是在電腦上搭建的,而且最經常使用本機作測試。所以,移動端體驗和動畫性能就被次要考慮了。一些技術(好比 canvas)或者動畫技術可能在移動端表現地並很差。
然而,若是代碼寫得好優化也到位(參考規則 #1),移動端的體驗甚至比電腦更加流暢。移動端的優化是一項很是棘手的事情,可是新的 iPhone 比手提電腦更快!若是你採用了前幾項建議,你將會獲得一個很是棒的移動端表現。
移動端訪問網站將會變得很是很是的重要。我建議你專門拿一個星期的時間認真地用手機查看你的網站,這或許有些極端,你可能會感受像是在接受懲罰而被迫使用移動端版本,可是你應該調整好心態。
不斷優化設計和提升性能,直到網站在移動端的表現和在電腦上同樣優美和方便。
若是你堅持一週都用移動端來訪問網站,你將會獲得一個比電腦上更優化體驗更好的網站。即便在使用過程當中遇到很是惱人的事情也是值得的,那意味着這些問題將在你的用戶體驗到以前就被解決掉了!
常常在不一樣的設備上測試
不一樣屏幕尺寸、分辨率,或者有着各類樣式的設備
除了移動端和電腦以外還有不少因素可以對性能產生極大的影響,好比是不是 "retina" 屏幕、窗口的分辨率、硬件的老舊程度等等。
即便 Chorme 和 Safari 都是基於 Webkit 的瀏覽器而且有着類似的語法,可是他們也有各自的特色。每一次 Chrome 升級都會修復一些問題同時也會引入新的 bug,因此你必須時刻保持警戒。
固然,你不會只想着搭建一個對於全部瀏覽器放之四海而皆準的網站,因此尋找一個靈活的方法以便於你可以增長或者移除一些功能是很是有用的。
我一般會交替在較小的 MacBook Air 和大屏的 iMac 中使用網站,每次都會暴露出新的問題而後再修復 — 尤爲是動畫性能方面的問題,有時候也會有全局設計的題、信息密度、可讀性的問題等等。
Media queries 是一款很是強大的工具,它典型的用處是定位因爲高度或者寬度形成的樣式差別,可是它一樣可以用來根據分辨率添加目標內容或者其餘屬性。另外,識別系統和設備類型的功能也是很是有用的,由於移動設備的性能特徵和電腦仍是有很大區別的。
原文:來自 前端早讀課