1. 程式人生 > 前端設計 >線條之美,玩轉SVG線條動畫

線條之美,玩轉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>

元素的形狀是通過屬性 d 來定義的,其值是一個“命令+引數”的序列,規則如下:

<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-dasharraystroke-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為例:

  1. 得到蘋果LOGO的png圖片。
  2. 在PS裡開啟圖片,右鍵圖層,然後點選從選區生成工作路徑,我們就可以得到:

3. 檔案–匯出–路徑到AI,將路徑匯出在AI裡面開啟:

  1. 在AI裡面選擇儲存成svg格式的檔案,然後用文字開啟svg檔案,將path的d拷貝出來即可。

  2. 利用上文介紹的實現動畫的方法,我們就可以輕鬆的得到了下面這個效果。

線條動畫進階

可以看到上面的動畫效果和文章最初顯示的動畫效果還是有區別的,要想實現文章最初的動畫效果,需要用到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-dasharraystroke-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線條動畫吧~