SVG精髓(二)

257 阅读4分钟

第8章 渐变

8.1 linearGradient元素

从一个颜色平滑地过渡到另一个颜色,渐变可以是线性的,即沿着直线过度,也可以是径向的,从中心点向外辐射过渡。

<defs>中定义,然后在后面把它们作为填充或描边来引用。

使用<linearGradient>元素来定义线性渐变。

<svg width="660" height="220">
  <defs>
    <linearGradient id="linear" >
      <stop offset="0%"   stop-color="#05a"/>
      <stop offset="100%" stop-color="#0a5"/>
    </linearGradient>
  </defs>

  <rect x="10" y="10" width="600" height="200" fill="url(#linear)" />
</svg>

蓝色->绿色

image.png

<stop>元素有两个必要属性,offset和stop-color。offset用于确定哪个点颜色等于stop-color,offset使用 0%-100%或者 0-1表示

 <svg width="660" height="220">
    <defs>
      <linearGradient id="linear" >
        <stop offset="0%"   stop-color="#05a"/>
        <stop offset="50%"   stop-color="red"/>
        <stop offset="100%" stop-color="#0a5"/>
      </linearGradient>
    </defs>
      
    <rect x="10" y="10" width="600" height="200" fill="url(#linear)" />
 </svg>

image.png

 <svg width="660" height="220">
    <defs>
      <linearGradient id="linear" >
        <stop offset="0%"   stop-color="#05a" stop-opacity="1.0"/>
        <stop offset="50%"   stop-color="red" stop-opacity="0.5"/>
        <stop offset="100%" stop-color="#0a5" stop-opacity="0.3"/>
      </linearGradient>
    </defs>

    <rect x="10" y="10" width="600" height="200" fill="url(#linear)" />
 </svg>

image.png

定义线性渐变的方向

默认沿着水平线从左到右过渡,如果想要指定过渡方向,使用 x1 x2 y1 y2 指定渐变的起点和终点,由0%-100%或者 0-1表示。

<svg width="250px" height="250px" viewBox="0 0 250 250">
  <defs>
    <linearGradient id="three_stops">
      <stop offset="0%" style="stop-color: #ffcc00;"/>
      <stop offset="33.3%" style="stop-color: #cc6699"/>
      <stop offset="100%" style="stop-color: #66cc99;"/>
    </linearGradient>

    <linearGradient id="transition"
      xlink:href="#three_stops"
      x1="0%" y1="0%" x2="100%" y2="0%"/>
  </defs>
  
  <rect x="10" y="10" width="200" height="200"
    style="fill: url(#transition); stroke: black;"/>
</svg>

image.png

<svg width="250px" height="250px" viewBox="0 0 250 250">
  <defs>
    <linearGradient id="three_stops">
      <stop offset="0%" style="stop-color: #ffcc00;"/>
      <stop offset="33.3%" style="stop-color: #cc6699"/>
      <stop offset="100%" style="stop-color: #66cc99;"/>
    </linearGradient>

    <linearGradient id="transition"
      xlink:href="#three_stops"
      x1="100%" y1="0%" x2="0%" y2="0%"/>
  </defs>
  
  <rect x="10" y="10" width="200" height="200"
    style="fill: url(#transition); stroke: black;"/>
</svg>

image.png

<svg width="250px" height="250px" viewBox="0 0 250 250">
  <defs>
    <linearGradient id="three_stops">
      <stop offset="0%" style="stop-color: #ffcc00;"/>
      <stop offset="33.3%" style="stop-color: #cc6699"/>
      <stop offset="100%" style="stop-color: #66cc99;"/>
    </linearGradient>

    <linearGradient id="transition"
      xlink:href="#three_stops"
      x1="0%" y1="0%" x2="0%" y2="100%"/>
  </defs>
  
  <rect x="10" y="10" width="200" height="200"
    style="fill: url(#transition); stroke: black;"/>
</svg>

image.png

<svg width="250px" height="250px" viewBox="0 0 250 250">
  <defs>
    <linearGradient id="three_stops">
      <stop offset="0%" style="stop-color: #ffcc00;"/>
      <stop offset="33.3%" style="stop-color: #cc6699"/>
      <stop offset="100%" style="stop-color: #66cc99;"/>
    </linearGradient>

    <linearGradient id="transition"
      xlink:href="#three_stops"
      x1="0%" y1="0%" x2="100%" y2="100%"/>
  </defs>
  
  <rect x="10" y="10" width="200" height="200"
    style="fill: url(#transition); stroke: black;"/>
</svg>

image.png

spreadMethod属性

过度方向不一定是从对象的一角到另一角,我们可以指定从(20% 80%)到(40% 80%)渐变,可以通过spreadMethod属性来改变显示内容

pad:起始和结束渐变点会扩散到对象边缘

<svg width="250" height="250" viewBox="0 0 250 200">
  <defs>
    <linearGradient id="partial"
        x1="20%" y1="30%" x2="40%" y2="80%"
        spreadMethod="pad">
        <stop offset="0%" style="stop-color: #ffcc00;"/>
        <stop offset="33.3%" style="stop-color: #cc6699"/>
        <stop offset="100%" style="stop-color: #66cc99;"/>
    </linearGradient>
  </defs>
  
  <rect x="10" y="10" width="200" height="200"
    style="fill: url(#partial); stroke: black;"/>
</svg>

image.png

repeat:渐变会重复起点到终点的过程,直到充满整个对象

<svg width="250" height="250" viewBox="0 0 250 200">
  <defs>
    <linearGradient id="partial"
        x1="20%" y1="30%" x2="40%" y2="80%"
        spreadMethod="repeat">
        <stop offset="0%" style="stop-color: #ffcc00;"/>
        <stop offset="33.3%" style="stop-color: #cc6699"/>
        <stop offset="100%" style="stop-color: #66cc99;"/>
    </linearGradient>
  </defs>
  
  <rect x="10" y="10" width="200" height="200"
    style="fill: url(#partial); stroke: black;"/>
</svg>

image.png

reflect:渐变会重复终点到起点,起点到终点的过程,直到充满整个对象

<svg width="250" height="250" viewBox="0 0 250 200">
  <defs>
    <linearGradient id="partial"
        x1="20%" y1="30%" x2="40%" y2="80%"
        spreadMethod="reflect">
        <stop offset="0%" style="stop-color: #ffcc00;"/>
        <stop offset="33.3%" style="stop-color: #cc6699"/>
        <stop offset="100%" style="stop-color: #66cc99;"/>
    </linearGradient>
  </defs>
  
  <rect x="10" y="10" width="200" height="200"
    style="fill: url(#partial); stroke: black;"/>
</svg>

image.png

8.2 radialGradient元素

<svg width="150" height="150">
    <defs>
      <radialGradient  id="linear" >
        <stop offset="0%"   stop-color="red"/>
        <stop offset="33.3%"   stop-color="blue"/>
        <stop offset="100%" stop-color="pink"/>
      </radialGradient >
    </defs>

    <rect x="10" y="10" width="150" height="150" fill="url(#linear)" />
 </svg>

image.png

径向渐变的范围由一个圆确定,其中,中心店是0%,外圆周为100%,使用cx cy和r定义外圆,这些属性的值为外边框的百分比,默认值为50%

 <svg width="150" height="150">
    <defs>
      <radialGradient  id="linear" cx="0%" cy="0%" r="100%">
        <stop offset="0%"   stop-color="red"/>
        <stop offset="33.3%"   stop-color="blue"/>
        <stop offset="100%" stop-color="pink"/>
      </radialGradient >
    </defs>

    <rect x="10" y="10" width="150" height="150" fill="url(#linear)" />
 </svg>

image.png

第九章 文本

9.1 <text>基本属性

最简单的情况是只给 xy,指定第一个字符的基线位置。

image.png

font-family font-size font-weight font-style text-decoration

9.2 文本对齐

<text>元素指定了起始点,但是我们无法知道终点,让文本对齐变的困难,我们可以使用text-anchor属性来指定文本生效的位置,值为 start middle end

 <svg width="250px" height="600px" viewBox="0 0 250 60">
    <g style="font-size: 12pt;">
      <path d="M 125 10 125 600"
        style="stroke: gray; fill: none;"/>
      <text x="125" y="30" style="text-anchor: middle">
        Sample Text
      </text>
      <text x="125" y="60" style="text-anchor: start">
        Sample Text
      </text>  
      <text x="125" y="90" style="text-anchor: end">
        Sample Text
      </text>  
    </g>
 </svg>

image.png

9.3 <tspan>元素

类似<span>元素,可以嵌套在文本内容中,改变文本样式。也可以使用dy元素改变某个字母的位置,

 <svg width="250px" height="600px" viewBox="0 0 250 60">
        <text x="10" y="30">
        Sample Text
        <tspan dy="4">a</tspan>
        <tspan dy="6">a</tspan>
        </text>  
 </svg>

image.png

第十章 蒙版和剪裁

第十一章 滤镜

第十二章 动画

12.1 动画基础

<svg width="250" height="50">
<rect x="10" y="10" width="200" height="20" stroke="black" fill="none">
  <animate id="animation"
    attributeName="width"
    attributeType="XML"
    from="200" to="20"
    begin="0s" dur="5s"
    fill="freeze" />
</rect>

atrributeName:动画中持续改变的值

attributeType 值为XML或者CSS ,在本例中改变的是XML属性的width,所以值为XML。默认为auto,先搜索CSS属性,再搜索XML属性

from to属性的起始值和结束值,from值是可选的,如果不指定,使用父元素的值。

begin dur动画开始和持续时间

fill 动画结束后做什么 freeze:冻结 默认值为remove,返回原来的属性

<svg width="275" height="275">
    <rect x="10" y="10" width="20" height="20"
      style="stroke: black; fill: green; style: fill-opacity: 0.25;">
    <animate attributeName="width" attributeType="XML"
      from="20" to="200" begin="0s" dur="8s" fill="freeze"/>
    <animate attributeName="height" attributeType="XML"
      from="20" to="150" begin="0s" dur="8s" fill="freeze"/>
    <animate attributeName="fill-opacity" attributeType="CSS"
      from="0.25" to="1" begin="0s" dur="3s" fill="freeze"/>
    <animate attributeName="fill-opacity" attributeType="CSS"
      from="1" to="0.25" begin="3s" dur="3s" fill="freeze"/>
  </rect>
</svg>
<svg width="200" height="200">
    <rect x="10" y="10" width="20" height="20"
      style="stroke: black; fill: #cfc;">
      <animate attributeName="width" attributeType="XML"
        begin="0s" dur="8s" from="20" to="120" fill="freeze"/>
      <animate attributeName="height" attributeType="XML"
        begin="0s" dur="8s" from="20" to="120" fill="freeze"/>
    </rect>

    <circle cx="70" cy="70" r="20"
      style="fill: #ccf; stroke: black;">
      <animate attributeName="r" attributeType="XML"
        begin="2s" dur="4s" from="20" to="50" fill="freeze"/>
    </circle>
</svg>

12.2 动画时间讲解

svg动画在svg加载完成时启动,用户离开页面停止计时。

(1)时、分、秒(1:20:33)的完整时间

(2)分、秒(02:15)

(3)秒

12.3 同步动画

绑定动画开始时间为另一个动画的结束时间

 <svg width="200" height="200">
    <circle cx="60" cy="60" r="30" style="fill: #f9f; stroke: gray;">
      <animate id="c1" attributeName="r" attributeType="XML"
        begin="0s" dur="4s" from="30" to="10" fill="freeze"/>
    </circle>

    <circle cx="120" cy="60" r="10" style="fill: #9f9; stroke: gray;">
      <animate attributeName="r" attributeType="XML"
        begin="c1.begin+1.25s" dur="4s" from="10" to="30" fill="freeze"/>
    </circle>
 </svg>

end给动画设置结束时间,但不能替代dur属性,动画结束时间取min(end,dur)

12.4 重复动作

repeatCount:设置动画执行多少次。

repeatDur:设置动画持续多次时间

<svg width="350" height="120">
  <circle cx="60" cy="60" r="30" style="fill: none; stroke: red;">
    <animate attributeName="cx" attributeType="XML"
      begin="0s" dur="5s" repeatCount="2"
      from="60" to="260" fill="freeze"/>
  </circle>

  <circle cx="260" cy="90" r="30" style="fill: #ccf; stroke: black;">
    <animate attributeName="cx" attributeType="XML"
      begin="0s" dur="5s" repeatDur="8s"
      from="260" to="60" fill="freeze"/>
  </circle>
  </svg>
  

12.5 设置复杂属性

<svg width="250" height="250"
  xmlns="http://www.w3.org/2000/svg">
  <polygon points="30 30 70 30 90 70 10 70"
    style="fill:#fcc; stroke:black">
    <animate id="animation"
      attributeName="points"
      attributeType="XML"
      to="50 30 70 50 50 90 30 50"
      begin="0s" dur="5s" fill="freeze" />
  </polygon>

  <path d="M15 50 Q 40 15, 50 50, 65 32, 100 40"
    style="fill:none; stroke: black" transform="translate(0,50)">
    <animate attributeName="d"
      attributeType="XML"
      to="M50 15 Q 15 40, 50 50, 32 65, 40 100"
      begin="0s" dur="5s" fill="freeze"/>
  </path>
</svg>

12.6 指定多个值

 <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
      <circle cx="50" cy="50" r="30" style="fill: #ff9; stroke: black;">
        <animate
          attributeName="fill"
          begin="2s"
          dur="4s"
          values="red;blue;pink;yellow"
          fill="freeze"
        />
      </circle>
</svg>

12.7 <set>元素

动画归根到底都是修改值,有时候,我们想改变非数字属性或者不能过度的属性,因此svg引入了<set>元素,需要to属性以及适当的时间信息。

 <svg width="150" height="100">
  <circle cx="60" cy="60" r="30" style="fill: #ff9; stroke: gray;">
    <animate
      id="c1"
      attributeName="r"
      attributeType="XML"
      begin="0s"
      dur="4s"
      from="30"
      to="0"
      fill="freeze"
    />
  </circle>

  <text text-anchor="middle" x="60" y="60" style="visibility: hidden;">
    <set
      attributeName="visibility"
      attributeType="CSS"
      to="visible"
      begin="4.5s"
      dur="1s"
      fill="freeze"
    />
    All gone!
  </text>
    </svg>

12.8 <animateTransform>元素

<animate>元素不适用于旋转,平移缩放和倾斜变换, <animateTransform>元素可以用来解决这个问题,设置attributeName为transform,type属性可以指定哪些值应该变化,(translate,scale,rotate)

 <svg width="200" height="100">
  <g transform="translate(100,60)">
    <rect
      x="-10"
      y="-10"
      width="20"
      height="20"
      style="fill: #ff9; stroke: black;"
    >
      <animateTransform
        attributeType="XML"
        attributeName="transform"
        type="scale"
        from="1"
        to="4 2"
        begin="0s"
        dur="4s"
        fill="freeze"
      />
    </rect>
  </g>
    </svg>

如果打算为多个变换应用动画,必须使用additive属性,它的默认值为replace,会替换之前的动画,通过设置为sum来积累变化

 <svg width="200" height="100">
  <g transform="translate(100,60)">
    <rect
      x="-10"
      y="-10"
      width="20"
      height="20"
      style="fill: #ff9; stroke: black;"
    >
      <animateTransform
        attributeType="XML"
        attributeName="transform"
        type="scale"
        from="1"
        to="4 2"
        begin="0s"
        dur="4s"
        fill="freeze"
      />
      <animateTransform
        attributeType="XML"
        attributeName="transform"
        type="rotate"
        from="0"
        to="45"
        begin="0s"
        dur="4s"
        fill="freeze"
        additive="sum"
      />
    </rect>
  </g>
 </svg>

12.9 <animateMotion>元素

我们可以在<animateMotion>元素中使用translate让对象沿着一条路径运动,如果想要对直线运动使用<animateMotion>,设置fromto属性,给每个属性分配一对(x,y)坐标即可,如果想要复杂的路径运动,使用path属性

<svg width="120" height="100" viewBox="0 0 120 100">
  <g>
    <rect x="0" y="0" width="30" height="30" style="fill: #ccc;" />
    <circle cx="30" cy="30" r="15" style="fill: #cfc; stroke: green;" />
    <animateMotion from="0,0" to="60,30" dur="4s" fill="freeze" />
  </g>
</svg>
 <svg width="250" height="250">
  <path
    d="M50,125 C 100,25 150,225, 200, 125"
    style="fill: none; stroke: blue;"
  />
  <path d="M-10,-3 L10,-3 L0,-25z" style="fill: yellow; stroke: red;">
    <animateMotion
      path="M50,125 C 100,25 150,225, 200, 125"
      rotate="auto"
      dur="6s"
      fill="freeze"
    />
  </path>
 </svg>
q

12.10 使用css处理SVG动画

animation-name规定需要绑定到选择器的 keyframe 名称。。
animation-duration规定完成动画所花费的时间,以秒或毫秒计。
animation-timing-function规定动画的速度曲线。
animation-delay规定在动画开始之前的延迟。
animation-iteration-count规定动画应该播放的次数。
animation-direction规定是否应该轮流反向播放动画。