設計師的專屬魔法,用SVG動畫重現布爾運算的設計過程

這是在做圖時忽然迸發的靈感(是的,偶爾也會有那麼一瞬間頭腦開竅),做爲設計師小夥伴們,平時用的最多的應該是布爾運算吧,基礎圖形的加加減減,獲得任意的形狀。就不說經典的Apple了,好比網易雲音樂圖標,你若是直接放上這個,彷佛沒什麼。面試


但放上布爾運算過程的設計稿(全部基礎圖形的輪廓),瞬間高大上起來,滿滿的設計感。


因此在作矢量圖的過程就忽然想到若是能用SVG結合CSS3的動效來還原這個設計過程,也不失爲一個好玩的效果,固然了,不會那麼巧恰好用到全部的四種運算,只是用動畫過程演示一遍,此爲目的。由於本身的底子就很弱,因此選了一個臨摹的圖形,衆位客官湊合看吧。

1.準備工做——圖形分層

每次在作SVG動效以前,都會給本身一點時間思考一下動畫完成的思路,以及用什麼屬性來實現,正所謂多點思考,少點勞做,或者換句話說,「不能用戰術的勤奮來代替戰略的懶惰」。
先放一張成品的效果圖,以下,就是這隻萌萌的小象bash


AI中作布爾運算雖然用路徑查找器極其方便,且能切割,任意玩,可是修改起來卻沒有PS那麼方便,給作完運算後的調整不是很方便的說。好比十幾甚至更多個形狀的布爾運算在PS裏玩起來還算輕鬆,左挪右挪上層下層的調節麼有壓力,在AI裏那要被玩壞了。因此第一步,要在AI裏作好分層。註明一點,這些是要在做圖以前就肯定的。
我把小象分紅三個部分,身體、頭部和尾巴,目的就是爲了減小每一個部分的基本形狀的數量。
AI中進行過布爾運算後的形狀導出後是獲得的結果的路徑,這就不歡樂了,舉個簡單的例子:


上面兩個圓形,相交以後獲得的形狀,導出後是 <path d="">,徹底不見兩個圓形 <circle>的蹤影,既然咱們是還原過程, 過程,就須要把原運算前的路徑保留,怎麼破?在進行運算以前原位複製到新的圖層中唄。以小象的身體爲例,我保留了兩個圖層,運算後和運算前的,這些路徑都是我須要用到的。

2.建立圖形過程的動畫

鑑於本身這渣渣通常的水平,圖形加減那一套過程就不拿出來嘚瑟了,仍是留着自家珍藏吧,這裏只說如何用動畫表現出來。各位設計師回想一下本身的建立基本形狀的過程,是否是選擇形狀後在畫布進行鼠標拖動就能夠了,嗯,這裏咱們主要實現的就是鼠標拖動的動畫過程。來看下面這張圖(不要給我講你是按着alt鍵巴拉巴拉的,無論,要不這動畫無法作了 ~~(>_<)~~):優化


從左上角到右下角的拖動過程就是圖形的建立過程,並且在建立的過程當中,圖形是逐漸從無到有,從小到大的。好了,廢話了半天,不不,是拋磚引玉,這就是咱們實現建立圖形過程的動畫思路。

@keyframes draw{
0%{transform:scale(0,0);transform-origin:left top}
100%{transform:scale(1,1);transform-origin:left top}
}  
/*通用繪製過程的動畫定義*/複製代碼

通過分析咱們得出,縮放變形transform:scale()是實現這種效果的最佳方案,這裏惟一要注意的是關於變形的基點,前面在涉及旋轉動畫中,更多的定義是transform-origin:center center,也就是以圓心爲基點,而這裏定義的是左上角,也就是left top,其實CSS的一些語法真的算是很簡單了,英語入門級。另外這裏對應的left和top的值是相對位置,這也是爲何能把draw定義成通用的緣由。
下面這張圖形虛線部分是爲了獲得身體部分建立的全部基礎圖形,實色填充的部分即爲最後須要的身體部分。動畫

基礎圖形是由5個圓形和1個矩形共同組成的。我進行了標號。url


對於身體部分,是4個圓形和1個矩形與1個基礎圓形進行相減獲得的。爲了讓動畫過程更形象,讓基礎圓形進行了實色填充,其餘形狀用虛線來表示。根據上面動畫的定義,先來實現基礎圖形的建立過程,CSS部分以下:

<style>
@keyframes draw{
0%{transform:scale(0,0);transform-origin:left top}
100%{transform:scale(1,1);transform-origin:left top}
} 
#circle0{animation:draw 1s ease;fill:#414c68;}/*基礎形狀用實色填充*/
#circle1{animation:draw 1s ease 1s backwards;}
#circle2{animation:draw 1s ease 2s backwards;}
#circle3{animation:draw 1s ease 3s backwards;}
#circle4{animation:draw 1s ease 4s backwards;}
#rect1{animation:draw 1s ease 5s backwards;}
.sketch{stroke:#c0f1ff;stroke-width:2;fill:none}/*其餘形狀用描邊*/
</style>複製代碼

SVG部分簡化以下(去掉了和形狀尺寸位置相關的屬性定義):spa

<circle id="circle0"/> <!--基礎形狀-->
<g class="sketch">  <!--其餘形狀-->
<circle id="circle1" />
<circle id="circle2" />
<circle id="circle3"/>
<circle id="circle4"/>
<rect id="rect1"/>
</g>複製代碼

簡單解釋一下,動畫屬性定義那裏拿這個#circle1{animation:draw 1s ease 1s backwards;}爲例,第一個1s是繪製時間,第二個1s是延遲時間,爲了讓圖形呈現出依次建立的過程,因此延遲時間是遞增的。backwards這個屬性必定要定義,當咱們給動畫定義了延遲時,咱們須要定義動畫時間以外對象的狀態(animation-fill-mode),backwards表示動畫開始前應用開始屬性值,也就是咱們定義的scale(0,0),換句話說,是不顯示的,這裏也能夠定義成both,對這個動畫效果而言,沒有區別。
如今看一下動畫效果:設計


嗯,基本重現了建立了基礎圖形的過程。那麼下一部分來了,怎麼才能過渡到運算以後的形狀呢?

3.運算過程的動畫

在作這個動畫伊始,我想到的是把相減的圖形轉化成蒙版,能行不?絕對能行,但實在是太麻煩了。記得咱們還保留了運算後的圖形放到了單獨的圖層中吧?這時,須要它粉墨登場了,而後其餘的圖形怎麼辦?集體消失!
關於消失的方法也有不少種,隨便來個順手的就好了,我準備用蒙版。爲了實現組合圖形消失以及運算後的圖形出現的過程,不得已,又定義了兩個動畫,其實作到這裏的時候,已經很後悔了,遠不如好好學學AE,在AE裏實現,但本身挖的坑,含着淚也要跳進去再努力爬出來啊,有始有終,硬着頭皮繼續作吧。流着淚補充了下面的動畫定義:3d

@keyframes skip{
0%{opacity:0}
100%{opacity:1}
} /*這是爲要登場的圖形準備的*/
@keyframes combine{
0%{fill:#FFFFFF}
100%{fill:#000000}
}/*這是爲要退出舞臺的圖形準備的*/

.skip{animation:skip 1s  6s both; fill:#414c68}
.combine{animation:combine 1s 6s both;}複製代碼

以及:code

<mask id="shade"><rect x="0" y="0" width="800" height="600" id="combine"/></mask> <!--蒙版定義-->
<g mask="url(#shade)">……</g>
<path class="skip" d=""/><!--組合後的形狀-->複製代碼

<g mask="url(#shade)">是把全部的圖形又組合後,使用這個蒙版。惟一值得欣慰的是skip和combine這兩個動畫能夠被複用。
插播一個小知識點,關於利用蒙版的漸隱動畫,是不能用0%{opacity:0} 100%{opacity:1} 而後填充黑色fill:#000000這種表面上看上去是蒙版漸現的方式來實現,是由於當不給蒙版定義顏色時,蒙版會被默認爲黑色,所以即便開始定義了透明度爲0,也會被當作黑色處理。若是實在要用的話,就套兩層蒙版,一層黑色的透明度改變,下面一層白色實色底。我只截變化的那一部分動畫來看一下:orm


彷佛銜接的還不錯喲。

剩下的工做就是體力活了呃,須要把頭部的動畫和尾巴的動畫補充上,沒有什麼特殊的,延遲的時間別弄錯了就行,這裏就不說了吧。最後獲得的統一的動畫是這個樣子的:


與理想中那種滿滿的設計感有差別,不過還好。下面試着來優化一下,上個色吧。

4.顏色填充過程

顏色填充的過程,與這個展現繪製動畫過程沒有什麼毛線關係,就是爲了好看!好看!我還能說什麼呢?說什麼顯示填色的過程,鬼,對於怎麼展現漸變填充完美沒有思路,我就利用了一下蒙版,把已經填充好的圖形先用蒙版蓋起來,讓大家看不見看不見,而後在適當的時間,蒙版逐漸移動,露出填充好顏色圖形。爲了讓蒙版顯示的效果更加天然,這裏我用漸變色對蒙版進行了填充。圖示以下:

<defs>
<linearGradient id="gradient3"  x1="0" y1="0" x2="0" y2="600">
  <stop offset="0" stop-color="#ffffff"/>
  <stop offset="0.1" stop-color="#000000"/>
</linearGradient>
</defs>    <!--定義的漸變類型-->複製代碼

最後獲得的效果以下:

另外,狠狠的告誡本身,下次不再作這種費勁巴拉但不酷炫的效果了。

相關文章
相關標籤/搜索