UI設計師福利之手把手打造SVG動畫應用的微場景

泱泱發表於2019-02-19

SVG動畫即使可以做的炫酷爆炸,但與AE不同,它不能導成視訊,不能導成GIF,而且考慮到AI與SVG的互通性,SVG動畫合適用來做向量卡通風格,放到實際應用中,不太建議利用SVG動畫做太複雜的效果,畢竟UI設計師不是動效設計師,且動畫做起來確實複雜的多。但雖然不適合大舞臺,我們卻可以用SVG動畫來打造一些微場景的應用,首先,動畫屬性的設定極其簡單,其次,效果卻比較出彩,下面來看幾個應用。

1.利用軌跡動畫的表情

先看效果

表情
表情

除了會動的眼睛之外,其他對於UI設計師來說,實在是太簡單了,而左顧右盼的眼睛,只用了最最基礎的軌跡動畫。看過我之前的其他幾篇文章的小夥伴應該很輕鬆的能做出來這種效果吧。
說一下實現的方法。
第一步,把動靜元素分開。
所有的SVG動效,都要把動靜元素分開,這是非常關鍵的一部,靜態元素直接匯出,動態元素單獨賦予動畫屬性。

為了不讓自己迷糊,在AI裡面繪製圖形的時候,一定建好圖層,重要的問題說三遍,圖層!圖層!圖層!我知道,除非繪製非常複雜的圖形,UI設計師在使用AI時是不太願意使用圖層的,畢竟一個快捷鍵ctrl+2就能鎖定,還有隔離選中路徑,外加編組,一個圖層裡來來回回的操作更加快捷。但從現在開始,如果需要做SVG動畫,一定要養成這種分圖層的好習慣,否則AI匯出的SVG將亂到崩潰。

繪製底圖
繪製底圖

比如這個案例裡,我建了三個圖層,分別命名為base,eye,path,依次承載底圖,運動的眼睛,運動的路徑。底圖裡扔進去背景、手機、一隻mbe風格的蛋。
繼續

眼睛和路徑
眼睛和路徑

命名eye的圖層裡自然是放眼睛了,然後path上繪製路徑。紅色雖然比較刺眼,但是在SVG中我能一眼看出嘛,而且繪製運動路徑只是為了提供一個路徑值,實際又不顯示的嘛。
靜的元素有了,動的元素有了,動的路徑有了,好了,開始搞一搞程式碼。

<svg>
<g id="base"><!--以下為AI匯出的組成底圖的程式碼-->
……
</g>
<g id="eye">
<circle cx="0" cy="0" r="">
<animateMotion path="" dur="1.5s" repeatCount="indefinite" calcMode="spline"  keySplines=".42, 0, .58, 1" keyTimes="0;1" /><!--path對應左眼的運動路徑-->
</circle>
<circle cx="0" cy="0" r="">
<animateMotion path="" dur="1.5s" repeatCount="indefinite" calcMode="spline"  keySplines=".42, 0, .58, 1" keyTimes="0;1" /><!--path對應右眼的運動路徑-->
</circle>
</g>
</svg>複製程式碼

程式碼部分就是介麼簡單。另外關於眼睛對應的<circle>標籤,AI匯出的cx和cy值肯定不是零,那為什麼要修改,請移步路徑動畫的文章,裡面有詳解,包括各個動畫屬性值對動效的影響。對於這個動畫效果而言,唯一需要注意的是SVG動畫屬性並不像CSS3的animation-direction:alternate這種屬性支援逆向播放,也就是說如果眼睛的效果想做成“左右對稱震盪”的型別,有兩個解決方法,一個是繪製成下面這種路徑後手動修改path值補充一個反向路徑,這需要了解貝塞爾曲線,略有難度。

還有一個方法UI設計師會更喜歡,就是再原路徑基礎上再繪製一段路徑,終點就是原路徑的起點,路徑差不多重合就可以了,不用那麼嚴格。

補充反向路徑
補充反向路徑

然後把匯出的path值進行替換,就能得到下面這種效果(重點看眼睛~)

改變眼睛運動路徑後的動效
改變眼睛運動路徑後的動效

嗯,so easy。

2.利用旋轉動畫實現的運動車輪效果

這個動效也是特別的簡單,只用到transform:rotate旋轉動畫屬性,但用對地方的話,效果還蠻好,所以特意拿出來說一下。
先來個場景設定


最終的動畫是我想要實現藍天白雲背景下,一輛自行車行駛的情景。先來動靜拆分,背景和自行車架是靜態的,車輪是動態的,然後再AI裡面,搞清楚圖層關係就OK了,我的由下到上的順序為 背景stage——後車輪back——前車輪head——自行車架body ,然後,AI,直接匯出SVG。
這裡有一個重要工作,就是關於前後車輪圓形的中心點,這是我們旋轉動畫的原點。為了不去程式碼裡扒拉出來,可以手動記錄下來。

只要加上下面的CSS樣式,車輪就可以動起來了。

<style>
@keyframes bicycle{
0%{transform:rotate(0)}
100%{transform:rotate(360deg)}/*定義旋轉動畫*/
}
#head{animation:bicycle 0.5s  linear infinite ; transform-origin:165px 440px}/*transform-origin根據自己的車輪的圓心定義*/
#back{animation:bicycle 0.5s  linear infinite; transform-origin:450px 440px}
</style>複製程式碼

非常簡單的定義,需要注意的地方一個是圓心對應的旋轉的中心點,另外關於運動速率,定義為線性linear。
好嘞,轉起來嘞。

旋轉的車輪
旋轉的車輪

有沒有看出哪裡不對?
再提示一下,車輪旋轉的方向
順時針!然後想象一下我們生活中,車把在左側時,車輪要逆時針旋轉才是前進,這是一輛沒有追求的不停後退的自行車啊。
修改方法自然很簡單,transform:rotate(-360deg)就好了。
先不著急放改之後的效果圖,繼續深入想一下。自行車車輪倒是轉起來了,但是運動過程缺乏真實感。問題出在哪裡?
答案:背景的白雲。
當運動的物體沒有參照物還好,一旦有了參照物,前進的物體對應參照物要後退。所以這裡,我不小心給自己挖了個坑(早知如此何必當初畫蛇添足/(ㄒoㄒ)/~~)
讓白雲後退意味著白雲由靜態元素變成了動態元素,根據我們的“動靜分離法則”,我需要把白雲元素從背景層裡分離出來,單獨放到一個命名為cloud的圖層中。
白雲的無限迴圈的運動我準備用下面的方法實現,建一個寬度是背景2倍的元素,執行位移動畫,直到B完全進入背景圖層中,迴圈這一過程。

運動示意圖
運動示意圖

現在最大的問題就是要解決無限迴圈的運動週期無縫對接的問題,換句話說,當B完全進入背景圖層後,下一個迴圈從頭開始,此時A位於背景圖層,那瞬間轉換的時候怎麼才能沒有跳躍感?很簡單,讓B與A完全重合。
在AI裡面實現更簡單了,只要把原來的白雲元素移動複製,左移距離等同於背景寬度。
給白雲元素增加一個位移動畫

@keyframes move{
0%{transform:translateX(0)}
100%{transform:translateX(600px)} /*600為背景的寬度*/
}
#cloud{animation:move 2s linear infinite;}複製程式碼

為了測試是不是達到了無縫拼接的效果,我暫時把白雲運動的速度加快了(一個位移週期2s),看一下白雲的運動。

無縫拼接的運動的白雲
無縫拼接的運動的白雲

當然,和自行車組合的時候白雲速度要很慢,畢竟自行車達不到風馳電掣的速度。
考慮到有天空了,索性把大地也填上,同樣的方法,給自行車增加一道地平線,圖層命名為earth。此處又有坑,白雲也就罷了,速度慢點就行,具體多慢隨心情。地平線後退的速度就不能這麼隨心所欲了,因為它們之間存在下面這種關係。
車輪旋轉一圈距離=地平線後退距離
在我們位移動畫中,位移距離是固定的,速度由一個動畫週期需要的時間決定,換算到具體時間怎麼辦?
我們假設地平線後退600px(場景寬度)需要的時間為T1,速度C=600px/T1,車輪旋轉一圈需要的時間為T2,同時C*T2=車輪周長(2πR),得到T1=(600px*T2)/2πR。
在我們這個案例裡,T2定義為0.5s,車輪半徑R為75,算出來T1≈0.64,所以對應地平線動畫設定如下

#earth{animation:move 0.64s linear infinite;}複製程式碼

現在看一下最終的效果

正向車輪
正向車輪

然後比較一下最開始懸空的只有車輪轉動的效果,感覺真實了好多。
當然了,如果你有更多的時間和精力,甚至可以不把白雲作為一個整體移動,而是每一朵單獨拆分出來,設定不同的透明度和速度,非同步播放,效果更好。還有其他元素可以自己隨意新增。

3.利用變形動畫實現的風吹動頭髮的效果

前面寫過的SVG變形動畫真的很!復!雜!我自己偶爾練手的時候都會感覺繁瑣,繁瑣,但實際應用時,真的不需要太複雜的圖形變化,來看下面這個案例。
這是我的底圖

底圖
底圖

效果來個簡單的,微風輕拂秀髮吧。依據“動靜分離大法”,我的AI中的圖層拆分成這三個部分。
由下到上的順序如下圖所示

動靜元素拆解
動靜元素拆解

請忽略那個詭異的劉海,沒有辦法……
對應的SVG檔案應該是下面這種

<SVG>
<g id="base">
…底圖程式碼…
</g>
<g id="hair">
<path d=""><!--頭髮-->
</g>
<g id="face">
…面部其他元素程式碼…
</g>複製程式碼

頭髮隨風飄搖那是必須要用變形動畫,而且是最最簡單的那種,修改幾個錨點的位置,調整一下形狀就可以了。不會的移步SVG變形動畫文章裡,有詳解。
為了方便調整,可以像我這樣另存到一個新的AI檔案裡面刪除其他元素進行修改

修改頭髮
修改頭髮

我們通過修改能得到兩個d值,一個是飄到左邊的一個是飄到右邊的。然後給原SVG增加樣式檔案

<style>
@keyframes blow{
0% {d:path('')} /*對應頭髮飄到左邊的d值*/
100%{d:path('')}/*對應頭髮飄到右邊的d值*/
}
#hair {animation: blow 2s ease-in-out infinite alternate;}
</style>複製程式碼

再做一個小修改,把

<g id="hair">
<path d="">
</g>複製程式碼

改成

<path id="hair" />複製程式碼

放效果

微風輕拂
微風輕拂

因為我設定的一個週期的時間比較長,所以是這種緩動效果。
所以即使SVG變形動畫應用,也儘量只用在整個圖形的區域性元素上,畫龍點睛就好啦。

相關文章