svg之渐变填充

与图案(pattern)一样,渐变也只是专门用来被填充的,所以也需要事先在defs中进行定义。

SVG中的渐变分为线性渐变(linearGradient)和径向渐变(radialGradient)两种,从名字就能看出这是两种不同方向的渐变,所以参数也会有所不同。

线性渐变

线性渐变由linearGradient标签所定义,线性渐变主要受直线的方向和渐变点的位置的影响,也就是沿着直线的方向按照渐变点的颜色设置进行变化。

渐变点

渐变点就是在linearGradient标签内所定义的<stop>元素,该元素有以下的属性:

  • offset:偏离位置,范围为0-1(0%-100%);实际上就是在直线方向(这个方向其实可看作向量方向)上的位置。

  • stop-color:该渐变点的颜色

  • stop-opacity:该渐变点的不透明度

1
2
3
4
5
6
7
8
<defs>
<linearGradient id="lg1">
<stop offset="0%" stop-color="#ff3366"></stop>
<stop offset="100%" stop-color="#3366ff"></stop>
</linearGradient>
</defs>

<rect x="50" y="50" width="300" height="60" fill="url(#lg1)"></rect>

mark

上面的示例就是在首尾两端(即0%100%处)各定义了一个不同颜色的渐变点。

1
2
3
4
5
6
7
<defs>
<linearGradient id="lg1">
<stop stop-color="#36f" stop-opacity="1" offset="0"></stop>
<stop stop-color="#36f" stop-opacity="0.2"offset="0.618"></stop>
<stop stop-color="#36f" stop-opacity="0" offset="1"></stop>
</linearGradient>
</defs>

mark

而这个示例不仅在首尾两端,还在中间设置了一个渐变点;这里的渐变点颜色都是一致的,只是每个渐变点的不透明度是不相同的。

直线方向

默认情况下的直线方向是从左端的中点(0%, 50%)指向右端的中点(100%, 50%)的。如下图所示:

mark

可以通过设置直线的起点(x1,y1)和终点(x2,y2)的位置(这里的单位为比例大小,相对于被填充元素的大小而言)来控制线性渐变的方向:

  • x1:起点的x坐标,范围为0-1(0%-100%);
  • y1:起点的y坐标
  • x2:终点的x坐标
  • y2:终点的y坐标

:这里的单位也可以设置为用户坐标系的单位,通过设置gradientUnits属性即可;默认属性值为objectBoundingBox,设置为userSpaceOnUse即可使用用户坐标系的单位!

1
2
3
4
5
6
<defs>
<linearGradient id="lg1" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#ff3366"></stop>
<stop offset="100%" stop-color="#3366ff"></stop>
</linearGradient>
</defs>

mark

上面的示例当中,把起点设置在(0,0),终点设置在(1,1),也就是从左上角到右下角进行渐变。

过渡填充:spreadMethod属性

因为可能出现指定的起始点并没有覆盖被填充元素全部范围的情况,因此没有被定义渐变的区域该如何进行填充就可以通过spreadMethod属性来设置:

  • pad(默认值):没有定义渐变的区域直接按照起始点的渐变颜色进行填充,即相当于未定义渐变的区域只有单色填充;
  • repeat:即定义渐变的区域会首尾相连(即起始点0%外侧相连的是100%处,反之终点100%的外侧相连的是0%处)的方式对未定义渐变的区域进行填充;
  • reflect:镜像填充,即首和首相连,尾和尾相连

mark

径向渐变

径向渐变则是由radialGradient标签进行定义的,径向渐变则受渐变点的位置与焦点的位置所控制。

渐变点

与线性渐变的渐变点不同的是,径向渐变的渐变点偏移的位置(offset)是相对于从焦点0%)到最外层的圆弧100%)之间的。

  • offset:范围依然是0-1(0%-100%)2x3
1
2
3
4
5
6
7
8
<defs>
<radialGradient id="rg1">
<stop offset="0%" stop-color="#ff3366"></stop>
<stop offset="50%" stop-color="#66ff99"></stop>
<stop offset="100%" stop-color="#3366ff"></stop>
</radialGradient>
</defs>
<rect x="50" y="50" width="100" height="100" fill="url(#rg1)"></rect>

mark

上例定义了三个渐变点(0%50%100%),其中『圆心』、『半径』和『焦点』默认参数为:

属性 默认属性值
cx 50%(相对于被填充元素的大小,下同)
cy 50%
r 50%
fx cx相同(注意并非指的是50%,而是跟cx的设置值相同!)
fy cy相同

因此,默认情况下,『圆心』在元素正中心(50%,50%),而『焦点』就在『圆心』处,『半径』为元素长宽的一半;也就是说,默认情况下0%处就在『圆心』,而最外层的圆弧即为元素边框的内切圆:

mark

径向设置:『圆心』、『半径』和『焦点』

不像线性渐变那样直接通过起始点的方向来控制渐变的方向,径向渐变是通过焦点到最外层圆弧的方向来控制渐变的方向,这就是所谓的『径向』。在这里,『圆心』的作用就是和『半径』一起定义最外层圆弧位置的;当『焦点』使用默认值时,实际上就是由『圆心』向『最外层圆弧』进行渐变的。但是如果『焦点』改变时,比如下面这个:

1
2
3
4
5
6
7
8
<defs>
<radialGradient id="rg1" cx="0" cy="0" r="1" fx="0.5" fy="0.5">
<stop offset="0%" stop-color="#ff3366"></stop>
<stop offset="50%" stop-color="#66ff99"></stop>
<stop offset="100%" stop-color="#3366ff"></stop>
</radialGradient>
</defs>
<rect x="50" y="50" width="100" height="100" fill="url(#rg1)"></rect>

mark

『圆心』位置为(0,0),『半径』为1(也就是元素本身的大小),而『焦点』位置为(0.5,0.5);所以渐变的方向就是从正中心的『焦点』(蓝色点)指向『最外层圆弧』(黑色圆弧),而『焦点』处为0%,『最外层圆弧』处为100%!而没有改变『焦点』的效果如下:

mark

spreadMethod

同线性渐变中的设置!

渐变引用

可以在渐变的定义中直接引用已经定义好的同一类型的渐变,使用的是xlink:href属性,如:

1
2
3
4
5
<linearGradient id="lg1" x1="0.2" x2="0.8">
<stop offset="0%" stop-color="#ff3366"></stop>
<stop offset="100%" stop-color="#3366ff"></stop>
</linearGradient>
<linearGradient id="lg2" xlink:href="#lg1" spreadMethod="repeat"></linearGradient>

参考文档

  1. 《SVG精髓(第2版)》