一個比想象中更騷氣的圓-svg實現

以前寫了一篇Canvas畫圖-一個比想象中更騷氣的圓(漸變圓環),其實SVG也能夠實現相似的效果,並且二者api驚人的類似。javascript

關於SVG

SVG是一種矢量圖形,在圖形改變尺寸的狀況下質量不會損失。css

相比canvas,svg有一個很大的優點就是內聯進html的時候能夠像操做dom同樣操做svg,這樣作起動畫來很是方便。html

本文不會介紹svg的基礎知識,不過也沒涉及什麼複雜的東西,基於xml的語法仍是比較好理解的。java

指望實現的效果和Canvas同樣是顏色非對稱的沿着圓周進行漸變。android

SVG的漸變

和以前講canvas同樣,svg也有線性漸變和徑向漸變,這裏主要講線性漸變,徑向漸變api差異不大。git

老規矩,上代碼:github

<svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="595.28px" height="841.89px" viewBox="0 0 595.28 841.89" enable-background="new 0 0 595.28 841.89" xml:space="preserve">
    <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="213.0787" y1="303.3227" x2="384.1807" y2="303.3227">
        <stop offset="0.107" style="stop-color:#00A29A"/>
        <stop offset="0.1301" style="stop-color:#28A891"/>
        <stop offset="0.1968" style="stop-color:#76B874"/>
        <stop offset="0.2649" style="stop-color:#9FC758"/>
        <stop offset="0.3339" style="stop-color:#BBD338"/>
        <stop offset="0.4041" style="stop-color:#CDDA06"/>
        <stop offset="0.4761" style="stop-color:#D7DE00"/>
        <stop offset="0.5527" style="stop-color:#DAE000"/>
        <stop offset="0.9265" style="stop-color:#F39800"/>
    </linearGradient>
    <circle fill="none" stroke="url(#SVGID_1_)" stroke-width="16" stroke-miterlimit="10" cx="306.385" cy="355.208" r="77.551"/>
    </svg>複製代碼

這個是直接從AI裏導出的,也能夠嘗試使用別的SVG編輯器,其中linearGradient就是定義一個線性漸變,和Canvas中的ctx.createLinearGradient一個意思,stop標籤就相似Canvas中的grd.addColorStop方法,一樣是設置漸變點,這裏給這個漸變設置了一個id,id="SVGID_1_"canvas

下面的那個circle標籤就是定義一個圓,cx,cy,r分別是圓心座標和半徑,fill和stroke分辨對應canvas中的fillStyle和strokeStyle,stroke-width對應canvas中的lineWidth。api

和以前給canvas版的騷氣圓環用漸變同樣,svg的實現也是定義一個線性漸變,而後讓圓用這個漸變來描邊stroke="url(#SVGID_1_)"dom

實際上出來的效果,和Canvas漸變是殊途同歸,即便svg有路徑的概念,漸變也沒有按照路徑來漸變,而是和canvas同樣從左到右,上下顏色是對稱的。

如圖:

一個比想象中更騷氣的圓-svg實現

SVG非對稱的漸變圓環

Canvas的非對稱漸變圓環咱們藉助了ctx.createPattern,google一下,svg裏一樣有個<pattern>

這裏爲了方便,我把要用到的圖片base64進去了,實際上用線上圖片也能夠。

代碼以下,省略base64的內容:

<svg height="108" width="108" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
      <defs>
        <pattern id="fill-img" patternUnits="userSpaceOnUse" width="108" height="108">
          <image xlink:href="data:image/png;base64,xxxxxxxxxxx" x="0" y="0" width="108" height="108">
          </image>
        </pattern>
      </defs>
       <circle fill="none" stroke="url(#fill-img)" stroke-width="10" stroke-miterlimit="1" cx="54" cy="54" r="49" >
       </circle>
    </svg>複製代碼

和canvas同樣,定一個<pattern>,而後給圓描邊的時候用這個東東。

出來的效果:

一個比想象中更騷氣的圓-svg實現

看了以前Canvas的文章的話,svg代碼仍是比較簡單的,而後咱們來加個動畫。

SVG動畫

SVG動畫其實是讓路徑動起來,要讓路徑動起來首先要了解stroke-dasharray和stroke-dashoffset這兩個屬性。

  • stroke-dasharray 表示用虛線描邊。可選值爲none, , inherit。

    • none 表示不用虛線描邊
    • inherit 表示繼承
    • 可就厲害了,基本上路徑動畫都須要用到,這是一個逗號或者空格分隔的數值列表,第一個值表示線段的長度,第二個值表示線段間空白的長度,舉個例子 stroke-dasharray="308 1000"中,308表示虛線中的線段的長度,而1000表示兩個線段間的長度是1000px。其實這個dasharray能夠不僅兩個值,能夠有不少個,會循環依次用到線段和空白之間。
  • stroke-dashoffset 表示虛線的起始偏移。可選值爲: , , inherit. 分別表示:百分比值,長度值,繼承。這個dashoffset和上面那個結合起來用,通常來講虛線的第一段是實線線段,若是我想要第一段是空白怎麼辦,設置這個dashoffset就能夠了。

如今就來試一試,只須要修改circle元素的代碼就能夠了:

<circle fill="none" stroke="url(#fill-img)" stroke-width="10" stroke-miterlimit="1" cx="54" cy="54" r="49" stroke-dasharray="308 1000" stroke-dashoffset="100">
    </circle>複製代碼

以下圖:

一個比想象中更騷氣的圓-svg實現

缺的那一塊就是由於虛線的空白部分被移出來了,這裏r設置49和Canvas的原理同樣,想畫看起來半徑54的圓,須要用54減去描邊寬度的一半,54-10/2,而這裏stroke-dasharray的第一個數,我這裏設置的是圓的周長,2Math.PI49=307.8760800517997 約等於308啦,至於第二個數,設大一點就好,大過圓的周長就能夠了。

想要作動畫就不斷的改變stroke-dashoffset的值讓虛線的空隙動起來就能夠了,svg自己支持屬性的動畫,稍微改動一下代碼:

<circle fill="none" stroke="#e5ece7" stroke-width="10" stroke-miterlimit="1" cx="54" cy="54" r="49"/>

    <circle fill="none" stroke="url(#fill-img)" stroke-width="10" stroke-miterlimit="1" cx="54" cy="54" r="49" stroke-dasharray="308 1000" stroke-dashoffset="308" stroke-linecap="round" transform="rotate(-88 54 54)">
        <animate attributeName="stroke-dashoffset" begin="0s" dur="1.5s" from="308" to="0" repeatCount="indefinite" />
    </circle>複製代碼

這裏我把circle的初始stroke-dashoffset改爲308,表示從空白開始,animate標籤中attributeName表示動畫屬性是stroke-dashoffset,begin表示開始的延時,dur表示時間整個動畫的時間,frometo表示初始值和最終值,repeatCount表示重複次數,這裏是無限次。總體和CSS3動畫仍是很像的。

這裏還有一個stroke-linecap="round"和Canvas的ctx2.lineCap="round";做用同樣,是設置描邊的兩頭是圓形。

另外我還在上面加了一個圓,用來作底色,同時給作動畫的圓作了一個旋轉transform="rotate(-88 54 54)"用來改變起始點。

效果以下:

一個比想象中更騷氣的圓-svg實現

SVG動畫2

大體瞭解了SVG動畫的原理以後,其實SVG還能夠用CSS3的transition和animation來作動畫。

添加css:

.animate-item {
        transition: stroke-dashoffset 1.5s ease;
    }複製代碼

添加js:

setTimeout(function(){
        $(".animate-item").css("stroke-dashoffset",94);
    }, 1000)複製代碼

前面說過svg聯進html的時候能夠像操做dom同樣操做svg,這裏修改了一下圓環,給了一個class.animate-item

修改圓環:

<circle class="animate-item" fill="none" stroke="url(#fill-img)" stroke-width="10" stroke-miterlimit="1" cx="54" cy="54" r="49" stroke-dasharray="308 1000" stroke-dashoffset="308" stroke-linecap="round" transform="rotate(-88 54 54)">
    </circle>複製代碼

效果以下:

一個比想象中更騷氣的圓-svg實現

至此,騷氣圓環SVG版也就完成了,整體上來講svg的實現更簡單,作動畫的代碼也比較少,相對於canvas須要佔用js線程進行必定量的計算來講,svg的性能要好一些。

不過svg在android4.3以上纔有比較好的支持,相對來講canvas的支持就比較好了。

一個比想象中更騷氣的圓-svg實現

完整代碼: github.com/bob-chen/ca…

參考

www.zhangxinxu.com/wordpress/2…

designmodo.com/svg-pattern…

相關文章
相關標籤/搜索