線條之美,玩轉SVG線條動畫
什麼是線條動畫
通常來說,對於web前端來實現動畫效果,不外乎通過下面幾種方案:
-
CSS動畫:利用css3的樣式效果可以將dom元素做出動畫的效果來。
-
Canvas動畫:利用Canvas提供的API,不斷清除--繪製這樣一幀一幀的做出動畫效果。
-
SVG動畫:SVG意為可縮放向量圖形,同時也是HTML中的一個標籤,在實現動畫方面較為小眾了一些,但其提供了不少的API來實現動畫效果,並且相容性也不差。
而線條動畫是一種以線條或者路徑為主要元素,利用各種組合和動作實現的動畫效果,通常使用SVG的<path>
路徑來實現,本文主要講解一下如何製作SVG線條動畫。
先來看幾個demo:
以上這些效果都是利用SVG線條動畫實現的,結合了css3和SVG相關的API,沒有使用到一行JavaScript程式碼,和Canvas比起來要容易一些,下面就說明一下實現這些效果的原理。
SVG的基礎知識
SVG主要以<svg>
標籤的形式在HTML文件中呈現,例如:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="40" stroke="black"
stroke-width="2" fill="red" />
</svg >
複製程式碼
其相關的API和Canvas非常像,提供了包括文字,直線,矩形,圓形,曲線,路徑等等相關形狀的繪製,同時也包括了一些濾鏡,陰影,漸變等一些效果,但是和Canvas不同的是,SVG作為網頁中的標籤,是會被CSS3等樣式或者動畫的相關引數影響的,藉助這一點實現SVG的路徑動畫就會簡單很多。
這裡我們只介紹<path>
相關的引數,其他更多關於SVG的API教程,推薦去官網來學習瞭解。
路徑<path>
:
<path>
元素是SVG基本形狀中最強大的一個,它不僅能建立其他基本形狀,還能建立更多其他形狀,例如貝塞爾曲線、2次曲線等曲線。<path>
<path>元素d屬性命令:
M = moveto(M X,Y) :將畫筆移動到指定的座標位置
L = lineto(L X,Y) :畫直線到指定的座標位置
H = horizontal lineto(H X):畫水平線到指定的X座標位置
V = vertical lineto(V Y):畫垂直線到指定的Y座標位置
C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次貝賽曲線
S = smooth curveto(S X2,ENDY):平滑曲率
Q = quadratic Belzier curve(Q X,Y,ENDY):二次貝賽曲線
T = smooth quadratic Belzier curveto(T ENDX,ENDY):對映
A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y):弧線
Z = closepath():關閉路徑
複製程式碼
利用<path>
的這些命令我們可以實現我們想要的任何線條組合,以一段簡單的線條為例:
<path id="path" fill="none" stroke="#000" stroke-width="1px" d="M452,293c0,0-61,72-44c0,0-47,117,81,57
s5-110,10-67s-51,77.979-50,33.989"/>
複製程式碼
效果如下:
看起來很簡單,但是,如何讓這個線條動起來呢?這裡就要用到SVG裡的<path>
的一些主要屬性:
-
stroke:標識路徑的顏色。
-
d:標識路徑命令的集合,這個屬性主要決定了線條的形狀。
-
stroke-width:標識路徑的寬度,單位是px。;
-
stroke-dasharray:它是一個和數列,數與數之間用逗號或者空白隔開,指定短劃線和缺口的長度。如果提供了奇數個值,則這個值的數列重複一次,從而變成偶數個值。因此,5,3,2等同於5,2,5,2。
-
stroke-dashoffset:標識的是整個路徑的偏移值。
stroke-dasharray和stroke-dashoffset
實現線條的動畫,核心是利用stroke-dasharray
和stroke-dashoffset
這兩個屬性,對於stroke-dasharray
可以參考下圖來理解:
stroke-dashoffset
則可以理解成類似translate
的偏移值。通過CSS來設定這兩個值,之前的路徑就會變成這個樣子:
#path {
stroke-dasharray: 3px,1px;
stroke-dashoffset: 0;
}
複製程式碼
效果:
下面就可以分別利用這兩個屬性並結合CSS3的animation來讓線條動態的繪製出來,從而實現簡單的動畫。
#path {
animation: move 3s linear forwards;
}
@keyframes move {
0%{
stroke-dasharray: 0,511px;
}
100%{
stroke-dasharray: 511px,0;
}
}
複製程式碼
效果:
511px這個值是整個路徑的長度,可以用DOM的API來獲取到:document.getElementById('path').getTotalLength()
複製程式碼
stroke-dasharray: 0,511px
表示實線和空隙的長度分別為 0 和 511px,所以一開始整個路徑都是空隙,所以是空的。
然後過渡到stroke-dasharray: 511px,0
因為整個線條的長度就是 511px,而實線的長度也慢慢變成511px,所以整個線條就出現了。
同樣利用stroke-dashoffset
也可以實現這個效果,原理就是最初線條分為511px實線,和511px空隙,但是由於設定了offset使線條偏移不可見了,當不斷修改offset後,線條慢慢出現。
#path {
animation: move 3s linear forwards;
stroke-dasharray: 511px,511px;
}
@keyframes move {
0%{
stroke-dashoffset: 511px;
}
100%{
stroke-dashoffset: 0;
}
}
複製程式碼
效果:
複雜的Path路徑
當我們掌握了上述的方法後,整個利用SVG實現線條動畫的原理就已經清楚了,我們需要的就是一個SVG路徑了,但是總畫一些簡單的線條還是不完美啊,那我們如何才能得到複雜的SVG路徑呢?
- 找UI設計師要
- 自己動手將圖片匯出SVG路徑,只需要簡單的2步
以蘋果LOGO為例:
- 得到蘋果LOGO的png圖片。
- 在PS裡開啟圖片,右鍵圖層,然後點選從選區生成工作路徑,我們就可以得到:
-
在AI裡面選擇儲存成svg格式的檔案,然後用文字開啟svg檔案,將path的d拷貝出來即可。
-
利用上文介紹的實現動畫的方法,我們就可以輕鬆的得到了下面這個效果。
線條動畫進階
可以看到上面的動畫效果和文章最初顯示的動畫效果還是有區別的,要想實現文章最初的動畫效果,需要用到SVG的<symbol>
和 <use>
來實現:
SVG複用:<symbol>
和<use>
在SVG中,<symbol>
元素用來定義一個圖形模板物件,它可以用一個<use>
元素例項化。當同一個圖形在SVG文件中多次使用時,就可以利用這兩個元素。注意,一個<symbol>
元素本身是不會有顯示效果的。只有<symbol>
元素的例項(一個引用了<symbol>
的 <use>
元素)才能呈現出效果。
利用這個思路,我們可以將原本的一條路徑複製多份進行疊加,同時設定上不同的顏色和動畫延時,從而達到一種"追擊線條"的動畫效果,程式碼如下:
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg">
<symbol id="pathSymbol">
<path class="path" stroke="#000" d="M344,26c3.595,1.373,3.172,0.899,4c16.619,39.859-50.248,119.052-93,107c-0.572-46.929,22.555-81.661,53-98
C320.666,34.667,332.334,30.333,344,26z"/>
<path class="path" stroke="#000" d="M338,132c53.094-1.055,80.442,15.317,103,44c0,1.333,2.667,4c-40.96,30.44-66.713,87.897-34,147
c6.417,11.595,21.062,26.807,32,34c5.333,10.667,5.333,16,8c-4.646,40.842-57.294,115.573-94,124
c-31.519,7.236-54.682-11.118-77-16c-37.039-8.102-61.021,12.37-87,18c-35.953,7.792-63.181-27.32-76-45
c-59.011-81.386-102.75-270.669,25-313c37.527-12.435,76.171,6.998,106,13C271.355,153.895,325.573,138.184,338,132z"/>
</symbol>
<g>
<use xlink:href="#pathSymbol"
id="path1"></use>
<use xlink:href="#pathSymbol"
id="path2"></use>
</g>
</svg>
複製程式碼
#path1 {
stroke: #9C27B0;
stroke-dashoffset: 7%;
stroke-dasharray: 0 35%;
animation: animation 3s linear forwards;
}
@keyframes animation {
100% {
stroke-dasharray: 7% 7%;
stroke-dashoffset: 7%;
}
}
#path2 {
stroke: red;
stroke-dashoffset: 7%;
stroke-dasharray: 0 35%;
animation: animation2 3s linear forwards;
}
@keyframes animation2 {
100% {
stroke-dasharray: 7% 7%;
stroke-dashoffset: 14%;
}
}
複製程式碼
效果:
上面程式碼,疊加了兩份路徑,同時設定了不同的stroke-dasharray
和stroke-dashoffset
動畫引數,從而實現了這種效果。
另外,可以直接將文字元素寫在<symbol>
中,會自動將文字文字轉化為對應的path路徑,如下:
<symbol id="text">
<text x="10%" y="35%" class="text">I</text>
<text x="30%" y="35%" class="text">❤</text>
<text x="60%" y="35%" class="text">U</text>
</symbol>
複製程式碼
通過設定font的一些屬性,以及不同疊加路徑的顏色搭配,就可以達到對文字新增線條動畫的效果:
文中相關完整原始碼可以直接右鍵-開發者工具檢視,盡情的發揮想象力來實現自己的SVG線條動畫吧~