先放上效果圖,再說實現方法。
bash
不管何種形式的SVG動圖,第一步天然離不開咱們的「動靜分離大法」。靜態圖分離出來以下:函數
<g id="base">
…對應靜態底圖的代碼…
</g>
<g class="emotion">
<path id="left"/>
<path id="right"/>
<path id="mouse"/>
</g>複製代碼
"left"爲左眼路徑(因爲悲傷sad的左右眼是對稱關係,因此沒有定義一組動畫屢次引用);"right"爲右眼路徑;"mouse"爲嘴巴路徑。爲了方便定義描邊屬性,我把全部的表情元素放到了一個組裏。這樣我就能夠經過定義CSS屬性post
.emotion path{fill:none;stroke:#615658;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10}複製代碼
來賦給全部的表情元素相同的描邊效果了。動畫
先說眼睛從圓形變成彎彎曲線的過程。首先肯定的是,確定是用了變形動畫。彎彎曲線只須要一段路徑就能夠實現,而圓形的組成路徑有四段路徑,所以咱們須要改造的就是路徑少的曲線,方法也很簡單,只須要給其增長三個錨點,使其變成四段路徑就能夠了。另外圓形路徑也要用剪刀剪成開放路徑。其餘要注意的細節調整方法再也不詳細說了,變形動畫的三篇文章裏有詳細介紹。spa
@keyframes deformLeft1{
0% {d:path('')} /*圓形路徑*/
100%{d:path('')} /*笑時的彎彎路徑*/
}
#left{animation:deformLeft1 1s ease}複製代碼
這樣就實現了左眼的變形動畫。
這個動畫過程沒有給路徑少的曲線直接增長虛擬曲線是由於試過以後效果很差。
嘴巴實現的過程是直線變曲線的過程,AI直接導出的直線必定是下面這樣的3d
<line x1="" y1="" x2="" y2=""/>複製代碼
而微微上翹的嘴巴是對應路徑標籤<path>
。咱們要作的,就是根據直線起點(x1,y1)終點(x2,y2),(水平直線的縱座標y1與y2是等值的)將其轉化成路徑標籤,方法也很簡單,對應d值Mx1,y1c0,0,0,0,(x2-x1),0。code
@keyframes deformMouse1{
0% {d:path('')} /*直線轉化後的路徑*/
100%{d:path('')} /*微微上翹的嘴巴的路徑*/
}
#mouse{animation:deformMouse1 1s ease}複製代碼
至此,完成了第一個動畫過程。
在路徑的改造過程當中,請用任意一個方法保留未修改的路徑,後面揭曉緣由。orm
在由微笑變傷心的過程當中,由於表示傷心的眼睛是兩條直線折線繪製的,這時導出的標籤是<polyline points=""/>
,固然了,若是你對貝塞爾曲線比較熟悉的話,徹底能夠根據座標值直接來轉化成小c開頭的路徑繪製方法,不熟悉的話就把直線改爲帶不多不多不多一點點手柄的曲線吧。
咱們在上一個動畫完成時,爲了配合圓形,把眼睛彎彎的一條路徑改爲了四條,那麼到了這裏怎麼辦?難道再把傷心的眼睛也切成四份,好吧,即便這裏能夠這麼操做,那最後暈暈眼睛的螺旋線?那但是N條路徑組成的,難道都要以最終數量最多的路徑爲準,加錨點加到手軟抽筋?!
因此說纔要保留一份未修改的路徑嘛。咱們直接用原始的路徑來進行改造,由於傷心的眼睛是兩條路徑,因此給原始路徑增長一個錨點,使路徑由一條變成兩條就能夠啦。不管是路徑上添加了幾個錨點,視覺上無差,因此動畫才能實現無縫拼接。cdn
@keyframes deformLeft2{
0% {d:path('')} /*變身兩條路徑的彎彎的眼睛*/
100%{d:path('')}/*悲傷的眼睛*/
}複製代碼
咱們是給一個元素附加多個動畫,語法以下:blog
#left{animation:deformLeft1 1s ease,deformLeft2 1s ease 1s}複製代碼
後面依次累加,用逗號,隔開就能夠了,由於第一個動畫我設置了1s的完成周期,因此第二段動畫deformLeft2最後的1s表示延遲1s後執行。
之因此沒有采用定義多個關鍵幀的方式來實現多個變形動畫,一個是考慮到最後的螺旋線路徑數量太多,固然,最重要的是每個變形動畫完成我都採用了ease函數,使每段動畫增長一點停頓感。
對於第二個動畫而言,嘴巴的變形很簡單,就再也不贅述了。
這個動畫變形過程路徑的數量差別比較大,固然了,掌握了奇淫技巧的咱們怎會被這個問題難住,悲傷的眼睛只有兩段路徑,而螺旋線眼睛足足有七段路徑,差的五段路徑讓咱們萬能的虛擬曲線c0,0,0,0,0,0來實現就好啦,so easy!
這裏由於圈圈太多,因此描邊粗細stroke-width也順便改一下。
@keyframes deformLeft3{
0% {d:path('')} /*後面補5個c0,0,0,0,0,0*/
100%{d:path('');stroke-width:4}
}複製代碼
繼續日後面追加定義的動畫deformLeft3咯
#left{animation:deformLeft1 1s ease backwards 1s,deformLeft2 1s ease 1s,deformLeft3 1s ease 2s forwards}複製代碼
這裏惟一的不一樣是我加了 forwards,這個屬性值對應的動畫屬性animation-fill-mode,用來定義結束後動畫的狀態,forwards爲動畫完成後保持最後一個屬性值。
爲何要添加這個屬性呢?由於從一開始,咱們的眼睛和嘴巴元素在代碼中是沒有體現的,全憑動畫屬性繪製路徑來添加,而眼睛的下一組動畫爲旋轉,若是變成圈圈眼以後不定義結束後動畫狀態,在旋轉動畫時,動畫元素爲空。
嘴巴的變形動畫也星對比較簡單,只須要給表示悲傷的向下彎曲的路徑增長錨點,補齊撇嘴對應的路徑數量就好啦。
眼睛的旋轉動畫實現起來很簡單,不過要定義一下旋轉的中心點transform-origin,不定義爲默認以畫布左上角原點爲中心點。
@keyframes deformLeft4{
0%{transform:rotate(0); transform-origin:}
100%{transform:rotate(360deg); transform-origin:}
}複製代碼
這個值直接經過AI得到。
#mouse{animation:deformMouse1 1s ease,deformMouse2 1s ease 2s,deformMouse3 1s ease 3s forwards}複製代碼
好了,以上就是所有動畫的實現過程,那麼作完這麼一套動態變化的表情能用在什麼地方呢?這就是咱們「動靜分離大法」玄妙之處,你只須要改一下靜態底圖,就能得到各類不一樣效果。並且任意改顏色,簡直爽歪歪。
好比我曾經作過一組方形的表情圖標,是下面這種
如今,我想讓第一排第二個當心心圖標變身動態表情,只要把咱們的動畫效果疊加上,再經過SVG的width、height、viewBox屬性值的設定進行縮放,就獲得了下面這個方形表情:
其餘應用就再也不一一舉例了,就醬。