之前分享了一些自己平時整理的可以通用的SVG動畫的教程基本都是最基礎(chǔ)的變化,旋轉(zhuǎn)也好,縮放也好,沿路徑運(yùn)動也好顽分,只需要定義CSS3的一些動畫屬性值或者SVG的動畫屬性標(biāo)簽,當(dāng)然施蜜,運(yùn)用得當(dāng)?shù)脑捵湔海揽窟@些也能做出很多超炫的效果,只要想象力足夠花墩,idear勝過方法悬秉。
本質(zhì)上來講澄步,各種動畫原理都是相通的冰蘑,包括AE,包括Macromedia Flash村缸、包括ps自帶的時間軸動畫祠肥,包括SVG的動畫屬性和CSS3的動畫屬性,都需要定義關(guān)鍵幀梯皿,不過補(bǔ)間動畫一個是軟件生成仇箱,一個是瀏覽器來執(zhí)行而已。之前做過flash動畫的UI設(shè)計師們一定知道东羹,動畫最難的部分其中之一是變形動畫剂桥,形狀A(yù)→形狀B無規(guī)律的變形才是最難掌握的部分。今天來分享一份全網(wǎng)獨(dú)一無二(啊哈哈属提,有種要上天的感覺)的SVG變形動畫教程权逗,讓UI設(shè)計師華麗麗變身動畫設(shè)計師,關(guān)鍵是冤议,看完這篇文章后斟薇,你可以實現(xiàn)任意形狀之間的變形動畫,是的恕酸,你沒有看錯堪滨,任意!獨(dú)家心得蕊温,高能預(yù)警袱箱。我的所有SVG動畫重點部分,一直都是從UI設(shè)計師最擅長的AI工具入手义矛,和SVG的參數(shù)如何相結(jié)合犯眠,不說了,快上車症革。
因為實在太長了筐咧,后面有進(jìn)階教程,所以分上下兩個篇章吧。如果沒有任何SVG基礎(chǔ)的話量蕊,建議只看上篇铺罢。
先看下面一個動畫效果,這是我初學(xué)AE時残炮,跟著教程做的韭赘,做了多久呢?我記得是一上午/(ㄒoㄒ)/~~势就,自我辯解一下泉瞻,不是學(xué)習(xí)能力差,而是當(dāng)時那一丟丟的動畫基礎(chǔ)知識全部忘光光“耄現(xiàn)在這個動畫如果用SVG來做袖牙,需要多久,二十分鐘吧我猜舅锄,當(dāng)然了鞭达,是在代碼模板的基礎(chǔ)上。
看到這里皇忿,熟練使用AE的設(shè)計師小伙伴或許不服氣了畴蹭,AE也可以,要SVG這勞什子作甚鳍烁?來來來叨襟,你來告訴我AE生成的動畫你來增加些交互,比如鼠標(biāo)單擊控制開始暫停結(jié)束幔荒?就算改改顏色和尺寸你都要去動源文件糊闽,然后重新生成的好吧?
另外補(bǔ)充一下铺峭,既然chrome聲稱要“拋棄”SMIL(不用擔(dān)心墓怀,一邊喊著拋棄,一邊繼續(xù)支持)卫键,那我們以后所有的SVG動畫盡量都用CSS3動畫屬性來完成傀履,SVG只用來繪圖。
1.變形動畫實現(xiàn)代碼原理
如果用SMIL來實現(xiàn)變形動畫莉炉,基礎(chǔ)代碼如下:
<svg width="" height="" >
<path>
<animate attributeName="d" dur="" values=" ; "/>
</path>
</svg>
就是利用<path>
的屬性d的變化钓账,value值用分號;隔開,前后分別對應(yīng)兩個形狀的路徑值絮宁。但我們上面說過梆暮,要用CSS3來實現(xiàn),那代碼就變成了下面這種(以后就用這個模板啦):
<svg height=" " width=" ">
<style>
@keyframes deform{
0% {d:path('');}
100% {d:path(''); }
}
#animated {
animation: deform 2s;
}
</style>
<path id="animated" />
</svg>
哇绍昂,好簡單啦粹,好清爽偿荷。通過定義一個名為deform的動畫,然后設(shè)置開始和結(jié)束唠椭,進(jìn)行繪制路徑命令d:path(' ')跳纳,單引號里面就是對應(yīng)的路徑的d值;<path>
標(biāo)簽直接調(diào)用這個動畫就可以了贪嫂。
2.最簡單的普通形狀的變形動畫
有了上面的代碼模板了寺庄,然后可以進(jìn)行動畫的真正制作了。從最簡單的開始力崇,根據(jù)最少三點組成一個形狀斗塘,比如我在AI里面隨手畫了一個,叫它啥好呢亮靴,單峰山吧馍盟。
把導(dǎo)出的SVG中
<path>
標(biāo)簽的d值復(fù)制下來,放到模板里初始值0%對應(yīng)的d:path(' ')里台猴。然后動動錨點的位置朽合,拖拖手柄俱两,得到下面這個饱狂,雙峰山
同樣,得到d值放到結(jié)束100%對應(yīng)的d:path(' ')里宪彩。好了休讳,我們做的第一個變形動畫出來了。
單峰山變雙峰山了尿孔。
是不是感覺很簡單俊柔,別急,因為有可能活合,你的動畫是下面這樣的:
也是由單峰變雙峰雏婶,but,那順滑的過渡效果呢白指?
別急留晚,我們從SVG代碼里找一下原因,我把能變形和不能變形的
<path>
標(biāo)簽的d值一并貼上告嘲,如下:
為了方便d值的解讀错维,我重新組織了一下分行。關(guān)于M橄唬、C赋焕、c、S仰楚、z等等的含義隆判,怕解釋后UI設(shè)計師們看了后心煩意亂犬庇,你只需要知道的是,M對應(yīng)起點侨嘀,后面一組坐標(biāo)即2個值械筛,z表示路徑閉合,C(大寫)c(小寫)S(大寫)s(小寫)都是代表曲線繪制方法飒炎,C(大小寫)后面對應(yīng)3組即6個值埋哟,S(大小寫)對應(yīng)2組即4個值。為了看起來不亂郎汪,我特意給每組坐標(biāo)畫了下劃線赤赊。另外AI直接生成的SVG的
<path>
的d值寫法很不標(biāo)準(zhǔn),它的原則是負(fù)數(shù)和負(fù)數(shù)之間不加逗號,隔開(狠狠吐槽)煞赢,所以你看到數(shù)值中的那些短線比如0-77抛计,不是區(qū)間,而是數(shù)字0和數(shù)字-77照筑。看到區(qū)別了吧吹截?不能變形的山峰你會發(fā)現(xiàn)其d值最后是S不是C。對于這類變形動畫凝危,瀏覽器可不會解讀C和S的區(qū)別波俄,更何況對應(yīng)的數(shù)組量不同,這就是沒有發(fā)生動畫的原因蛾默。
作為UI設(shè)計師的你懦铺,一定更迷糊了,這S怎么生成支鸡,怎么控制岸睢?我怎么知道AI會導(dǎo)出什么牧挣?秘密就是——
——
手柄急前!
沒錯,就是你用AI繪制曲線時離不開的好幫手瀑构。當(dāng)你使用錨點工具直接拖放同時操作兩個手柄裆针,然后不再單獨(dú)調(diào)整手柄時,導(dǎo)出d值中的就會有S。換句話說,一個錨點的兩個手柄對稱等長堕担。具體的原理解釋出來又是一大堆督弓,所以,為了不給自己添麻煩,建議變形時,除非你能確保同一個錨點都進(jìn)行了這種同時拖放手柄的操作,否則一概動動其中一個手柄(放心边篮,微調(diào)一下手柄幾乎完全不影響你的圖形)己莺。
3.最簡單的多邊形變形動畫
還是從最簡單的三角形開始
比如我希望從三角形1→三角形2。這次我用了描邊戈轿,關(guān)于樣式屬性凌受,放到CSS里或者
<path>
里都可以。但對于這種多邊形來說思杯,SVG對應(yīng)的標(biāo)簽不是<path>
胜蛉,而是<polygon>
,同樣色乾,沒有d值而是point誊册。那怎么套用呢?
方法1:改造point為d暖璧。
很簡單案怯,point對應(yīng)值為點的坐標(biāo),我們只需要給第一組值前面加上M澎办,剩下的每組前面加L嘲碱,最后z結(jié)束,就成功實現(xiàn)了point到d的轉(zhuǎn)化局蚀。舉例說明:
我的三角形1對應(yīng)的代碼如下:
<polygon points="148,288 350,134 390,299 "/>
那我要做的就是改成
d:path('M148,188L350,134L390,299z')
然后調(diào)用<path>
標(biāo)簽麦锯。
那試一下套用效果如何:
改造成功!
方法2:改造原圖形
這個方法是我推薦的方法至会,我叫它視覺欺騙离咐,哈哈谱俭。因為在AI里奉件,我只要用錨點工具那么輕輕的拖一下,多邊形就變身普通形狀了昆著。但從視覺上來看县貌,它還是一個三角形哦。
此時導(dǎo)出的就是
<path>
而不是<polygon>
凑懂。所以煤痕,設(shè)計師小伙伴們感到自己的優(yōu)越感了沒?用工具接谨,我們可以勝過前端吶(某些方面~)摆碉。而且利用這個方法,你可以打破多邊形與普通形狀之間的障礙脓豪,想怎么變身就怎么變身巷帝。因為如果三角形之間的這種變換,你用CSS3的變形屬性旋轉(zhuǎn)rotate扫夜、扭曲skew楞泼、縮放scale也能實現(xiàn)驰徊。
但比如下面這種,只有路徑變形動畫才能實現(xiàn):
從視覺上看就是(偽)三角形變成“巫師帽”了對不對堕阔?
4.進(jìn)階1——任意形狀的變形動畫(自己變自己)
有了前面的基礎(chǔ)棍厂,就可以玩點高級的玩意了。
下面這種:
咱們先理一下思路超陆,首先牺弹,錨點的數(shù)量不是問題,圓有4個时呀,四葉草也是4個例驹,但我們知道圓形AI導(dǎo)出SVG的標(biāo)簽是
<circle>
,沒關(guān)系退唠,用我們的“作弊手段”鹃锈。此處提供一個已踩過的坑,如果是在標(biāo)準(zhǔn)圓形的基礎(chǔ)上無論怎么調(diào)整瞧预,最后輸出的d值會有兩段曲線使用了絕對位置大C屎债,而普通圖形只有最后一段曲線使用絕對位置,其余均為相對位置小c垢油,雖然這兩個可以計算互相轉(zhuǎn)化盆驹,但畢竟也是麻煩的,獨(dú)家秘笈就是用橢圓工具來繪制滩愁,然后寬和高可以只差1px躯喇,最后視覺效果和標(biāo)準(zhǔn)圓形是無差的。然后再把橢圓的四個錨點都稍稍動一點手柄硝枉,這次我讓變化后的四葉草與原來的圓形位置拉開一點距離廉丽,并且定義了運(yùn)動速率曲線為ease(最常用的設(shè)置,盡量不要用默認(rèn)線性的勻速運(yùn)動妻味,太過生硬)正压,即animation: deform ease 2s;就得到了下面這種效果:
5.進(jìn)階2——兩個不同圖形的變形動畫(圖形A變圖形B)
有了上面這個四個錨點變形的動畫,那下面這個理解起來就方便多了责球。
這次我不想在原有形狀上變化焦履,而是想完成這樣一次變形,最大的問題出現(xiàn)在錨點數(shù)量不同上雏逾,怎么辦嘉裤?聰明的設(shè)計師小伙伴一定可以想到,給錨點數(shù)量少的形狀用鋼筆工具添加錨點唄栖博。(什么屑宠?顏色太難看?這可是我特意找的日本傳統(tǒng)色的藤鼠和水淺蔥啊笛匙,身為一名不合適的UI我會告訴你我根本不會配色嘛侨把。)
除了改造左側(cè)的圖形犀变,我們還有一個工作,就是右邊這盆小花花秋柄,花莖(3-4和8-9)是標(biāo)準(zhǔn)垂直直線获枝,導(dǎo)出的d值對應(yīng)的是L開頭的一組數(shù)(相當(dāng)于曲線繪制時沒有嚴(yán)格按照開始手柄控制點,結(jié)束手柄控制點骇笔,結(jié)束點來完成)省店。
看到這里,可能會有設(shè)計師提出問題笨触,我怎么知道哪些需要改哪些不需要懦傍?而且哪些改過哪些沒改過?尤其是有些微調(diào)芦劣,根本看不出來粗俱。好了,你可以按照我下面這種方法來進(jìn)行校驗虚吟。
那堆數(shù)不用管寸认,我們只看開頭,對于兩個圖形來說串慰,只要是M開頭偏塞,中間全部小c(我們暫且稱之為標(biāo)準(zhǔn)路徑繪制)且數(shù)量保持一致,最后大C和z結(jié)尾邦鲫,就絕對能實現(xiàn)動畫效果灸叼。
我個人是非常建議在導(dǎo)出d值之后一定用這個方法先檢查一遍。
那出現(xiàn)問題后怎么對癥下藥呢庆捺?
但當(dāng)錨點數(shù)量很龐大的時候古今,正解是:(因為小c是相對位置,不能直觀的看出對應(yīng)的錨點)先找到路徑的起點疼燥,即M對應(yīng)的坐標(biāo)沧卢,然后根據(jù)第一組c值判斷路徑方向,每組開頭的字母+數(shù)字對應(yīng)一段路徑醉者,第幾組出錯就是該路徑的起點或終點手柄出現(xiàn)問題。并且解決方法簡化給為非標(biāo)準(zhǔn)路徑(即不是小c開頭的路徑)兩側(cè)錨點都加上非對稱手柄披诗。因為你可能會碰到各種你不了解的字母開頭的情況撬即,所以索性把解決方法統(tǒng)一起來。
關(guān)于判斷路徑方向呈队,因為我們的例子恰巧我讓第一組出現(xiàn)問題剥槐,所以拿修改之后標(biāo)準(zhǔn)小c來說,我們只看最后一組坐標(biāo)宪摧,0,-42.5粒竖,因為是相對位置颅崩,所以表示該錨點相對于起點M水平方向位移0,垂直方向位移-42.5(向上位移42.5)蕊苗,這樣就很容易判斷對應(yīng)的是哪個點沿后,也就看出路徑方向了。
知道修改原則后朽砰,對設(shè)計師來說應(yīng)該不是什么難事尖滚。這里設(shè)計師們不要感覺很麻煩,畢竟瞧柔,做變形動畫本身就是很費(fèi)時間的一件事情漆弄,不是量產(chǎn)的工作類型,另外平時也不過是偶爾需要這種動畫造锅。舉例說明撼唾,我的花花的d值是下面這種:
通過M值我找到了花朵形狀的路徑起點,然后根據(jù)d值哥蔚,判斷出是第一段和第六段路徑出了問題券坞,并且確認(rèn)了路徑方向為逆時針,開始數(shù)數(shù)肺素,對應(yīng)圖形上紅線標(biāo)出的路徑恨锚。通過放大圖形,找到原因倍靡,以路徑1為例猴伶,錨點A和錨點B只有一側(cè)手柄,然后按我們簡單粗暴的解決方法塌西,給A和B都加上很短的另一側(cè)手柄他挎,同理修改路徑6,再導(dǎo)出d值看一下捡需。
完美办桨!
別急,來看動畫效果:
(此處還有一個坑站辉,如果設(shè)計師發(fā)現(xiàn)沒有動畫效果呢撞,不不不,是畫面一片空白的時候饰剥,只需要把d值里的空格去掉就可以殊霞,這是語法問題,無法解釋汰蓉。)
喲喲绷蹲,位置,顏色過渡什么的都沒問題,但是祝钢,變形效果太過猛烈……中間那么翻轉(zhuǎn)一下子是鬧哪樣比规?
別急,所有的問題都是出現(xiàn)在d值上拦英,我們見招拆招蜒什。
這里我只放上一部分d值,先找到起點龄章,然后通過第一組c的最末一對相對坐標(biāo)對應(yīng)的錨點吃谣,得到的信息是向左11.5,向下37.7做裙,所以岗憋,這個圓的路徑方向是順時針。方向我用線連起來10段路徑對應(yīng)的變化關(guān)系是下面這樣的:
縱橫交錯锚贱,真是頭大啊仔戈。
這種情況只會出現(xiàn)在兩個無關(guān)聯(lián)的圖形的變形動畫,不會出現(xiàn)在由同一個圖形修改生成的第二個圖形(因為這種是變形動畫的初衷)的情況拧廊,但我們的目的恰恰就是想讓現(xiàn)有的任意圖形來完成動畫监徘。
那如何應(yīng)對出現(xiàn)這種兩個圖形路徑反向的情況?
解決方法——路徑反轉(zhuǎn)
我們AI里有個神奇的功能吧碾,就是下面的反轉(zhuǎn)路徑方向凰盔。當(dāng)你把路徑變成復(fù)合路徑(具體操作:對象-復(fù)合路徑-建立-反向),然后屬性面板里就會出現(xiàn)可用的反轉(zhuǎn)路徑方向操作項
只需那么輕輕的一點倦春,搞定户敬,方便不?來睁本,我們通過真實數(shù)據(jù)來看一下是不是達(dá)到了目的尿庐。
上圖的形狀為順時針路徑,下圖輕松變身逆時針路徑呢堰。再看下應(yīng)用翻轉(zhuǎn)路徑后的d值的動畫效果抄瑟。
關(guān)于路徑反轉(zhuǎn),你仔細(xì)看下代碼會說枉疼,咦皮假?怎么起點也發(fā)生了變化?我們下篇揭曉如何任意控制起點位置往衷。
提前預(yù)告钞翔,在下篇里,還將進(jìn)階一個圖形如何變身兩個圖形席舍,圖形多合一,以及鏤空圖形的變形動畫等哮笆。
向前端開發(fā)人員求JavaScript代碼来颤,因為兩個任意圖形之間的動畫效果如果不去修改圖形中的錨點的手柄汰扭,只要保證錨點數(shù)量一致,是可以通過js來把繪制貝塞爾曲線的S福铅、L直線萝毛、V垂直直線、H水平直線滑黔、絕對位置大C等等統(tǒng)統(tǒng)轉(zhuǎn)換成相對位置小c笆包,達(dá)到一統(tǒng)江湖的目的。因為我js只是渣渣入門略荡,勉強(qiáng)能看懂基礎(chǔ)的庵佣,寫不來。但可提供轉(zhuǎn)換公式汛兜,有興趣的可留言巴粪。這樣借助js的話,工作就簡化到只要“噠噠噠”給錨點數(shù)量少的圖形任意補(bǔ)充上錨點就可以了粥谬。