一个比想象中更骚气的圆-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…

相关文章
相关标签/搜索