酷炫的SVG 動態圖標

                                                                  

  在  loading.io 上能看到好多效果驚豔的loading圖標。它們都是用svg寫成的,寥寥幾行代碼,比img圖片更精細更節省體積,比純dom實現要更靈活和高效。css

  怎麼畫這些圓和方塊?怎麼着色?怎麼動起來? 先看看svg的基礎知識,而後將上面第一個圖標畫出來。html

 

1、基本圖形元素

  svg有一些預約義的形狀元素:矩形<rect>,圓形<circle>,橢圓<ellipse>,直線<line>,折線<polyline>,多邊形<polygon>,路徑<path>和文本<text>。html5

 1 <!-- viewBox定義畫布大小 width/height定義實際大小 -->
 2 <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300" height="300" viewBox="0 0 300 300">
 3 
 4     <!-- 直線 (x1,y1)與(x2,y2)爲兩點座標 -->
 5     <line x1="0" y1="0" x2="250" y2="30" />
 6 
 7     <!-- 多邊形 經過多個點的座標造成封閉圖形 -->
 8     <polygon points="5,5 100,100 50,200" />
 9 
10     <!-- 矩形 (x,y)爲左上角起始點 -->
11     <rect x="100" y="100" width="120" height="100" />
12 
13     <!-- 圓形 (cx,cy)圓心點 r半徑 -->
14     <circle cx="100" cy="50" r="40" stroke="black"/>
15 
16     <!-- 文本 (x,y)左下角座標  -->
17     <text x="0" y="20" style="font-size:16px;font-weight: bold">Try SVG</text>
18 
19 </svg>

 

2、樣式與效果 

  svg元素的樣式能夠寫成標籤的屬性,也能夠寫在style裏面。下面是一些主要的樣式屬性:css3

  • stroke: 筆觸顏色
  • stroke-width:筆觸寬度
  • stroke-opacity:筆觸的透明度
  • fill:填充色,即background
  • fill-opacity:填充色的透明度
  • transform:圖形變換,相似css3 transform

  svg還支持不少濾鏡效果,能作漸變、陰影、模糊、圖像混合等等。不須要了解那麼多,例如要畫幾個彩色圓圈,用circle 配合fill 便可。dom

  注意:transform 默認以svg左上角爲基點,而不是圓心或其餘中心。左上角是svg座標系原點。瞭解transform和座標系統,能夠參考 這裏svg

 

3、輔助元素

  svg有幾個輔助元素:<g> <defs> <symbol> <use>。它們不表明具體形狀,而是幫助進行圖形元素的分組管理、重複使用等。具體介紹能夠參考 這裏wordpress

  • <g>  元素一般用來對相關圖形元素進行分組,以便統一操做,好比旋轉,縮放或者添加相關樣式等。
  • <use>  實現SVG現有圖形的重用,能夠重用單個SVG圖形元素,也能夠重用<g><defs>定義的組元素。
  • <defs>  內部定義的元素不會直接顯示,能夠不用事先定義樣式,而是在使用<use>實例化的時候再定義。
  • <symbol>  可以建立本身的視窗,兼具<g>的分組功能和<defs>初始不可見的特性。

  對於上面提到的transform基點問題,能夠經過嵌套<g>標籤並偏移<g>的位置,進而重設基點。以下畫出幾個水平排列的圓圈,並設置不一樣的縮放尺寸,獲得動畫

 1 <svg width="80px" height="80px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
 2     <g transform="translate(20 50)">
 3         <circle cx="0" cy="0" r="7" fill="#e15b64" transform="scale(0.99275 0.99275)" />
 4     </g>
 5     <g transform="translate(40 50)">
 6         <circle cx="0" cy="0" r="7" fill="#f47e60" transform="scale(0.773605 0.773605)" />
 7     </g>
 8     <g transform="translate(60 50)">
 9         <circle cx="0" cy="0" r="7" fill="#f8b26a" transform="scale(0.42525 0.42525)" />
10     </g>
11     <g transform="translate(80 50)">
12         <circle cx="0" cy="0" r="7" fill="#abbd81" transform="scale(0.113418 0.113418)" />
13     </g>
14 </svg>

 

4、動畫的實現

  svg的動畫效果是基於動畫標籤元素實現的:spa

  <animate>實現單屬性的過渡效果,code

  <animateTransform>實現transform變換動畫效果,

  <animateMotion>實現路徑動畫效果。

  svg的寫法很靈活,樣式能夠寫成標籤屬性也能夠寫在style裏面,動畫標籤能夠經過xlink指定元素,也能夠寫在動畫元素的內部。以下演示animateTransform的xlink寫法:

<svg xmlns="http://www.w3.org/2000/svg">
    <rect id="animateObject" x="20" y="20" width="50" height="50" fill="blue"></rect>
    <animateTransform 
        xlink:href="#animateObject" <!-- 指定動畫元素 -->
        attributeName="transform"  <!-- 須要動畫的屬性名稱 -->
        type="scale"  <!-- 指定transform屬性 -->
        begin="0s"    <!-- 開始時間,即延遲 -->
        dur="3s"      <!-- 動畫時間 -->
        from="1"      <!-- 開始值 -->
        to="2"        <!-- 結束值 -->
        repeatCount="indefinite"   <!-- 重複方式,indefinite無限重複  -->
    />
</svg>

  上例的動畫是A到B的過渡,要造成順暢的循環,至少要定義三個關鍵點。animateTransform支持更多更靈活的屬性設置:

  • values:多個關鍵點的值,替代from和to,例如 values="0;1;0" 
  • keyTimes:跟values對應,各個點的時間點
  • calcMode:動畫快慢方式。discrete | linear | paced | spline
  • keySplines:設置運動的貝塞爾控制點,calcMode爲spline時有效

   對svg動畫的更詳細介紹,參考 這裏

5、代碼實例

       

  circle畫圓,fill着色,用g標籤包裹並定位,transform設置初始形變,animateTransform設置動畫。如今來看代碼,相信不會再是一頭霧水了:

<svg class="lds-message" width="80px" height="80px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
    <g transform="translate(20 50)">
        <circle cx="0" cy="0" r="7" fill="#e15b64" transform="scale(0.99275 0.99275)">
            <animateTransform attributeName="transform" type="scale" begin="-0.375s" calcMode="spline" keySplines="0.3 0 0.7 1;0.3 0 0.7 1" values="0;1;0" keyTimes="0;0.5;1" dur="1s" repeatCount="indefinite"></animateTransform>
        </circle>
    </g>
    <g transform="translate(40 50)">
        <circle cx="0" cy="0" r="7" fill="#f47e60" transform="scale(0.773605 0.773605)">
            <animateTransform attributeName="transform" type="scale" begin="-0.25s" calcMode="spline" keySplines="0.3 0 0.7 1;0.3 0 0.7 1" values="0;1;0" keyTimes="0;0.5;1" dur="1s" repeatCount="indefinite"></animateTransform>
        </circle>
    </g>
    <g transform="translate(60 50)">
        <circle cx="0" cy="0" r="7" fill="#f8b26a" transform="scale(0.42525 0.42525)">
            <animateTransform attributeName="transform" type="scale" begin="-0.125s" calcMode="spline" keySplines="0.3 0 0.7 1;0.3 0 0.7 1" values="0;1;0" keyTimes="0;0.5;1" dur="1s" repeatCount="indefinite"></animateTransform>
        </circle>
    </g>
    <g transform="translate(80 50)">
        <circle cx="0" cy="0" r="7" fill="#abbd81" transform="scale(0.113418 0.113418)">
            <animateTransform attributeName="transform" type="scale" begin="0s" calcMode="spline" keySplines="0.3 0 0.7 1;0.3 0 0.7 1" values="0;1;0" keyTimes="0;0.5;1" dur="1s" repeatCount="indefinite"></animateTransform>
        </circle>
    </g>
</svg>

 

  也能夠用js控制svg的屬性,控制svg的動畫過程,作成能響應點擊等事件的圖標按鈕。固然svg能作的遠不止圖標,這裏有很多例子

相關文章
相關標籤/搜索