前段時間大家有被《你的人格主導色》這個 H5 刷屏了吧
你的人格主導色-錄屏
還沒玩的朋友可以在云音樂 APP 搜索關鍵詞「顏色測試」
或者 用云音樂 APP 掃這個二維碼(不要用微信,被屏蔽了)
https://st.music.163.com/st-color-quiz (二維碼自動識別)
今天我來和大家聊聊這個項目中動效設計是怎么落地的。這個 H5 從結構上來說很簡單,8 個頁面 8 道選擇題,每個頁面有一段聲音,用戶選擇自己認為這個聲音是什么,然后系統根據選擇結果分析用戶的人格「成分」并呈現在結果頁。這里的動效也主要是每個頁面內的動效和轉場動效等幾個部分。
頁面內的動效,大部分是用一個帶音頻的視頻作為背景動效,少部分用代碼完成。這樣的好處是如果背景動效需要修改,只需要調整視頻內容,輸出并替換資源就好,兼容性也是相對較好。
但是選項按鈕部分,因為不同用戶點擊的不一樣,就還是需要結合代碼來做效果了。這里主要用到的是 CSS 動畫。
我們先來看看翻頁效果:
這個效果我們是模擬的幕布從一邊被拉出并遮蓋整個頁面的效果,材質還是有點彈性的那種,這個形狀是在 canvas 中繪制的,繪制方法其實和我們平時在作圖軟件里的原理一樣,是由幾段閉合的貝塞爾曲線或直線組成的形狀:
//繪制從點 p1(x,y) 到點 p2(x,y) 的一段貝塞爾曲線 ctx.bezierCurveTo( p1(起始頂點)的控制點 2 的 x 坐標, p1 的控制點 2 的 y 坐標, p2(下一個頂點)的控制點 1 的 x 坐標, p2 的控制點 1 的 y 坐標, p2 的 x 坐標, p2 的 y 坐標);
形狀的運動實際上就是構成它的頂點的運動,這塊「布」是由這些點構成的:
在用戶沒有操作的時候,所有的點,包括 P2 的控制點,都貼著屏幕右邊沿,這樣構成的圖形是一條看不見的線(P1、P5 重合,P3、P4 重合,且這四個點的控制點都是他們本身)。當用戶點擊操作之后,點 P2 先向屏幕左邊移動,它的兩個控制點也以相同速度移動,這時看到的就如上圖般被扯出一塊布的效果;P2 移動一段距離后,P1 和 P3 也開始移動,做出被「拉扯」出來的感覺,最后都移動到屏幕左邊沿,然后 P2 再在水平位移上做幾次回彈效果:
轉場 demo:https://codepen.io/bigxixi/pen/yLMvmEL
?
其實一開始我們設計了可以用手拖拽翻頁的效果,但由于一些音視頻播放的兼容性問題,無奈簡化成了點擊觸發~
拖拽翻頁演示
我們再來看看頁面里的動效。
這一頁背景視頻里的雨主要是用 AE 自帶的 CC Rainfall 效果器制作:
三個選項按鈕就是三張圖片,點擊之后「被選中」狀態的圖片透明度漸現覆蓋掉黑字。透明度動畫我通過定義 fadeIn 和 fadeOut 兩個簡單的動畫 class,在點擊的時候添加到對應的 dom 上就好了。
.fadeOut{
animation: fadeKey 0.3s ease 0s 1 reverse both;
}.fadeIn{
animation: fadeKey 0.3s ease 0s 1 normal both;
}@keyframes fadeKey {
from{opacity: 0;}
to{opacity: 1;}
}
詳情參見:
下雨-選項 demo:https://codepen.io/bigxixi/pen/zYZVpWe
這一頁,火焰背景同樣是視頻
主要通過 AE 里的「分型雜色」+「置換圖」效果器模擬火焰動畫。
而幾個選項的動效則用 CSS+圖片資源來完成。其中火焰拖尾是畫好的一張圖,我把圖的錨點定在圖片靠上的位置:
transform-origin: 50% 22.5%;
選項向上飛入畫面的過程中做了個 Y 方向從 50%到 100%的縮放。當然還有透明度的變化。
@keyframes optionTileInAniP2Key { 0%{ opacity: 0; transform: scaleY(0.5); } 20%{ opacity: 1; } 100%{ opacity: 0; transform: scaleY(1); } }
三個選項用了三張 png 圖片來呈現,雖然看起來是「黑字」+「紅色影子」的組合,實際上圖片資源用的是「紅字」,在 CSS 里直接用 filter:saturate(0) 把它的飽和度降為 0,這樣就呈現黑色了,而選項背后的紅色影子,其實是用的圖還是前面的同一張圖,這時就不必著色了直接用本來的顏色,同時同樣通過 filter 添加模糊和投影效果,也順便降低一點透明度。
.optionShadow { filter: opacity(0.5) blur(0.5vw) drop-shadow(0px 0px 1px rgb(255, 155, 93)); }
這樣就可以做到「字、影分離」——他們的浮動是有個微小的錯位的——的同時只用到一張圖片資源,而原圖用紅字的原因是把圖中黑色部分填充為紅色效果不好(至少我沒試出很好的方法),但紅色變成黑色卻很方便。
詳情可以參考 demo:https://codepen.io/bigxixi/pen/qBryRJM
我們再看看這一頁
背景視頻是個簡單的三維物體旋轉動畫,用金屬材質+環境光澤的反射渲染。
選項動畫也很簡單,每個選項我們拆分為選項(A、B、C)和內容描述,把他們的錨點定位到他們相接的線條上:
選項:
transform-origin: 100% 50%;
文字:
transform-origin: 0% 50%;
然后對文字添加一個 skewY 和 scaleX 的動畫,它就看起來像是進行了一個 3d 旋轉,被「按」進屏幕了。
顏色變深的效果,其實是同一層做同一個動畫的純色 div 在點擊后疊加了一個透明度動畫。
.optionChoosenAni{ animation: optionChoosenAniKey 0.5s cubic-bezier(.38,1.5,.5,1.01) 0s 1 normal both; } @keyframes optionChoosenAniKey { 0%{ transform: skewY(0) scaleX(1); } 100%{ transform: skewY(-15deg) scaleX(0.5); } }
詳情可以參考 demo:https://codepen.io/bigxixi/pen/oNZrqYq?
鯨魚這個頁面
背景視頻部分我們主要使用了 AE 自帶的 分型雜色 + 毛邊 效果器,通過調整亮度、對比度,模擬科考船用聲吶掃描海底的圖像效果。
選項部分的背景是分別用了三張 apng 動圖,而文字則是 CSS 精靈圖。
在用戶未做出選擇時,精靈圖靜止于第一幀;用戶點擊對應選項后,精靈圖動畫開始播放,文字「散開」
.choosenAni_A{
animation: whaleOptionASprAniKey 1s steps(1) 0s 1 normal both;
}
@keyframes whaleOptionASprAniKey {
0% { background-position: 0 0; }
3.45% { background-position: -387px 0px; }
6.90% { background-position: -774px 0px; }
……
96.55% { background-position: -3096px -200px; }
100.00% { background-position: -3483px -200px; }
}
同時調整色相 filter:hue-rotate() 為背景動圖「著色」
.chooosenBG_A{ transition: all 0.2s linear; filter:hue-rotate(120deg); }
詳細可以看下 demo:https://codepen.io/bigxixi/pen/ZEedxJL
這個頁面的背景視頻里
布簾被風吹起動畫使用了簡單的 C4D 的動力學來完成
三個選項隨風擺動的效果則是簡單粗暴的用了三個 apng 動圖
選項飄動的扭曲是用 AE 的「置換圖」制作。
不過他們的飄入、飄出,以及選中的著色都還是 CSS 做的。這個「著色」動畫也是用了之前火焰那個頁面的小技巧,三個原圖都是被選中后的橙色,默認未選狀態使飽和度 filter:saturate(0) 和亮度 brightness(0) 設為零將他們變成黑色,選中后再回復成 1,這樣就「變成」橙色了
.selectedAni_p6{ animation: selecetedKey_p6 0.2s linear 0s 1 normal both; } @keyframes selecetedKey_p6 { 0%{ filter: saturate(0) brightness(0); } 100%{ filter: saturate(1) brightness(1); } }
詳情可以參考風吹-選項 demo:https://codepen.io/bigxixi/pen/OJpevEL
最后的這個頁面
我們可以看到背景視頻里有很多泡泡,首先在 C4D 里做一個簡單的肥皂泡
然后給她加一個 displacer 變形器,用 noise 驅動制作變形動畫模擬肥皂泡在空氣中的擠壓變形效果,并導出為一段循環的序列幀(注意渲染時間和 noise 中的循環時間對上)
然后在 AE 里導入這個序列幀, 復制多個,改變尺寸大小等讓他們看起來各自稍微不同。這里我各自對他們的位移加入了隨機表達式 wiggle
//循環 wiggle 表達式 loopTime = 10; //循環周期 freq = 0.5;//頻率 amp = 25;//振幅 t = time % loopTime; wiggle1 = wiggle(freq, amp, 1, 0.5, t); wiggle2 = wiggle(freq, amp, 1, 0.5, t - loopTime); linear(t, 0, loopTime, wiggle1, wiggle2)
而泡泡的縮放則是先將音頻的振幅轉換為關鍵幀,再用表達式與縮放關聯起來起來,并各自錯開一點時間
vol = thisComp.layer("音頻振幅").effect("兩個通道")("滑塊").valueAtTime(time-0.05*index)+90; [vol, vol*0.8]
這樣泡泡們就看起來像是比較自然地被音頻驅動而震動了。
而兩個選項,是先把選項文字圖片導入 AE 用 湍流置換 效果器模擬 C4D 中做泡泡時的扭曲動畫,注意循環得勾上,后面就直接放上泡泡的序列幀,導出為 apng 動圖。
點擊之后的泡泡碎裂,則是如之前的鯨魚那頁,直接切到一個精靈圖動畫播放,因為模擬的泡泡破碎的效果,是一個瞬間的事情,所以這里就直接切過去了。
泡泡破碎動畫主要是用了 AE 里的 「CC Mr.Mercury」這個效果器來制作。
詳情參閱泡泡-選項 demo:https://codepen.io/bigxixi/pen/eYvwMwy
除了 CSS,有些動效還是需要 JS + Canvas 這個萬能組合,除了一開始介紹的翻頁效果外,有些頁面里也在使用。這是表現力最豐富,相對來說門檻也比較高的一個方向,幸好有很多前輩高人做了很多 JS 庫并開源給我們使用。比如鍵盤聲這一頁
這頁主要用了 Matter.js 進行物體下落效果的物理模擬,可以看看 Matter.js 官網直接就有類似例子,我們只需要依葫蘆畫瓢替換成對應的視覺資源,控制物體下落的時機等參數就好。
Matter.js Demo · code by @liabru:https://brm.io/matter-js/demo/#sprites
這個頁面的選項是藏在背景里的,點擊之后實際上是換了張圖片資源表示「按下」。
詳情可以參考(演示版,選項只有 A 可以點)鍵盤-demo:https://codepen.io/bigxixi/pen/dyvBeoL
云彩這一頁主要是前端同學在實現效果,具體細節講解我就不越俎代庖了,有機會可以把話筒遞給前端小哥哥哈
最后說下結果頁,結果頁會根據我們的選擇,生成不同的關鍵詞、文案及背景色動畫
這里的背景色動畫使用的是 GLSL Shader 動畫,基本原理是根據用戶的選擇結果,生成一張漸變貼圖(視覺同學繪制了很多漸變圖,覆蓋了每個關鍵詞),貼圖再經過 fragment shader 中的 noise 通過不同參數扭曲得到動畫,這部分參考了 MartinRGB 大神的案例,詳細原理可以參考他在 Droidcon 2019 上海站的分享:?https://github.com/MartinRGB/Droidcon_Shanghai_Keynote/releases/tag/0.4
這里因為不同關鍵詞也會對應不同的音樂,最初我們也是希望背景漸變動畫能和音頻有關聯,實際上我也寫了一些 demo:http://bethe.top/163/color-quitz-simplified/end.html
但由于一些兼容性問題,研發沒有足夠的時間來處理,而沒有和音頻關聯的效果也可以接受(結果頁最重要的還是關鍵詞和對應的文案),最后沒有用上。
好了,這個項目的動效部分大概就和大家分享這些,大家如果對最后的結果是如何生成的感興趣,可以看下這篇文章:https://zhuanlan.zhihu.com/p/376712328
作為一個的動效設計師,我們除了設計動態效果,如何幫助研發將動效在產品中落地實現也是非常重要的一個工作內容,不然再好的設計最后只能淪為自嗨的空中樓閣,豈不可惜。
有的設計師可能想,這不應該是研發的指責嗎?其實對于設計師,多了解一些動效實現原理也是有好處的。
一方面在設計動效方案時可以對實現難度有個預估,面對無法實現的可能性要有「優雅降級」的能力,不然不斷返工折磨的也是自己;另一方面可以從更多維度作為設計出發點,有的效果設計師想破腦袋想不出來如何表達,研發那邊可能就一行代碼的事兒…
這是個不斷妥協,也在不斷突破自我的過程,在這個過程中我們可能更迷茫,但一撥開云霧,對設計對動效的認知也更清晰。
這個專題我也將分享這幾年的項目里的一些落地經驗,主要是 H5 項目,可能涉及到一些 web 前端的代碼知識,由于我不是專業的程序員,有寫的不對的地方,懇請大家不吝斧正,謝謝!
復制本文鏈接 文章為作者獨立觀點不代表優設網立場,未經允許不得轉載。
熱評 王亞洲