如何给SVG填充和描边应用径向渐变

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何给SVG填充和描边应用径向渐变相关的知识,希望对你有一定的参考价值。

参考技术A SVG线性渐变
上篇文章中也提到,如果你理解了线性渐变的原理,学习径向渐变是很容易哒。
使用 <radialGradient> 元素定义径向渐变,以及一些相关属性。我们还是一样,从一个简单的例子开始。
<svg width="660" height="330">
<defs>
<radialGradient id="radial" fx="50%" fy="50%" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#05a" stop-opacity="1"/>
<stop offset="100%" stop-color="#0a5" stop-opacity="1" />
</radialGradient>
</defs>

<rect x="0" y="0" width="600" height="300" fill="url(#radial)" />
</svg>

注:原文 radialGradient 的属性 r="75%" 与实例不对应,应该修正为 r="50%"
这个例子非常眼熟啊。在 <defs> 中定义渐变 ,设置 id 为 radial ,方便我们在后面的矩形中引用。
在 <radialGradient> 元素中放置了两个颜色结点,一个蓝色一个绿色。两个都是用 <stop> 元素定义的, <stop> 元素中包括三个属性。
offset : 在径向渐变中,它表示从点 (fx,fy) 到外边缘的圆的百分比值距离。它定义了渐变结点的位置。值从 0 到 1 之间,或者 0% 到 100% 。
stop-color : 定义offset结点位置的颜色
stop-opacity : 定义颜色结点的透明度 ,值从 0 到 1 ,或 0% 到 100% 。
我们先看看上面实例的结果,然后再接着讨论 <radialGradient> 元素的属性。

渐变从中心处的蓝色,一直过渡到边缘处的绿色。我们现在来看看它是如何创建出来的。
除了 id="radial" 这个属性,这里面还有五个属性, fx 、 fy 、 cx 、 cy 和r 。
r : 设置圆的半径
cx 和 cy : 渐变的中心点坐标。要移动渐变的位置,改变这俩值即可。
fx 和 fy : 定义渐变的焦点坐标。你可以通过改变这俩值,移动渐变第一个颜色结点的位置。
你应该理解半径是干啥的,所以我下面找的实例是帮助大家理解 cx 、 cy 、 fx、 fy 的。
这里我把前面实例的半径 r 改为 75% ,其它内容不变。
<radialGradient id="radial" fx="50%" fy="50%" cx="50%" cy="50%" r="75%">

你可以看到蓝色在过渡到绿色之前扩散得更远了。

现在我们把半径变回 50% ,然后把 cx 改成 20% 。
<radialGradient id="radial" fx="50%" fy="50%" cx="20%" cy="50%" r="50%">

你可以看到蓝色部分的大小和初始实例一样了,但是渐变的中心移动到了左边,距离左边缘 20% 的位置。还有,蓝色的焦点(由 fx 和 fy 确定)还是在矩形的中心。

最后,把半径都 cx 都变回 50% ,把 fx 变成 20% 。
<radialGradient id="radial" fx="20%" fy="50%" cx="50%" cy="50%" r="50%">

乍一看,可能和上个实例没什么区别,都是蓝色向左移了。但是注意到蓝色的中心点现在的位置,已经不再是中心处,而是距离矩形左边缘 20% 的位置。渐变的 焦点移动 了。

cx 和 cy 属性定义了渐变的中心位置。 fx 和 fy 定义了渐变的焦点的位置。默认都是 50% ,但是 cx 和 cy 控制的渐变层面和 fx 、 fy 控制的不一样。
因为我只改变 x 方向的的 c 和 f , y 方向的部分并没有太大改变。
<radialGradient> 元素的属性
径向渐变 有几个属性,和线性渐变一样。
xlink:href 属性提供了在渐变中引用另一个渐变的方法。通过这个属性引用的渐变是可继承的,也可以被重写。
gradientUnits 属性决定了 cx``cy``fx``fy 的值是否缩放,它接受两个值,我们前面的文章中也讲过了。
userSpaceOnUse : cx``cy``fx``fy 和 r 表示的值是根据当前用户坐标系统的。也就是说这些值都是绝对值,不会进行缩放。
objectBoundingBox : cx``cy``fx``fy 和 r 表示当前应用的元素的坐标系统。也就是说渐变随着引用它的元素一起缩放。
你还可以使用 gradientTransform 属性对径向渐变进行变换。
在下面的实例中我给第一个渐变( radial-1 )添加了 gradientUnits="objectBoundingBox" ,允许渐变缩放。
我还给第二个 <radialGradient> 添加了 id="radial-2" 。它使用 xlink:href 属性引用了 #raidal-1 ,并重写了 fx 的值为 20% 。最后我添加了一个 gradientTransform 来将渐变旋转了 -20deg 。
<svg width="660" height="330">
<defs>
<radialGradient id="radial-1" fx="50%" fy="50%" cx="50%" cy="50%" r="50%" gradientUnits="objectBoundingBox">
<stop offset="0%" stop-color="#05a" stop-opacity="1"/>
<stop offset="100%" stop-color="#0a5" stop-opacity="1" />
</radialGradient>
<radialGradient id="radial-2" fx="20%" fy="50%" cx="50%" cy="50%" r="50%" xlink:href="#radial-1" gradientTransform="rotate(20)">
</defs>

<rect x="0" y="0" width="600" height="200" fill="url(#radial-2)" />
</svg>

希望现在还没有太多改变。第二个渐变只是把焦点转移了,然后旋转。结果如下。

因为在径向渐变中这些变化比较难看出来,但是希望你还是发现了焦点已经向左移动,整个渐变也都旋转了。
最后一个属性, spreadMethod ,和线性渐变一样。它可以接受三个值, pad ,reflect , repeat ,它定义了渐变如何开始和结束,当 cx 和 cy 的值是在 0%到 100% 里面的时候。
pad :(默认值)使用开始和结束位置的颜色结点来填充剩余的部分。
reflect : 反射渐变图案,从开始->结束,再从结束->开始,然后开始->结束,往复直到空间都填满。
repeat : 从 start-to-end 重复渐变图案,直到空间填满。
和线性渐变一样,我相信这三个值都很容易通过下面的实例来理解。 reflect 和repeat 的值在一些浏览器中工作有点小问题。所以我下面放了可以工作的情况的截屏。
先放这篇文章开始的那个实例,然后改几个值。首先我把半径变成 20% ,因为比较小的半径有助于我们设置 spreadMethod 的值时差异更明显。然后我添加了 spreadMethod 属性。
<svg width="660" height="330">
<defs>
<radialGradient id="radial" fx="50%" fy="50%" cx="50%" cy="50%" r="20%" spreadMethod="pad">
<stop offset="0%" stop-color="#05a" />
<stop offset="100%" stop-color="#0a5" />
</radialGradient>
</defs>

<rect x="0" y="0" width="600" height="300" fill="url(#radial)" />
</svg>

spreadMethod 设置为 pad 时的情况。当渐变在所有方向达到矩形的 20% 的位置时,它整个变成了绿色,直到矩形的边缘。

这是把 spreadMethod 设置为 reflect 的情况。当渐变在颜色结点的位置从蓝色变成绿色之后,反射回来,从绿色变成蓝色。然后又反射,从蓝色变成绿色。这样一直持续到渐变填满矩形。
SVG

截图

最后是把 spreadMethod 设置为 repeat 的结果,这次图案是从蓝色过渡到绿色。变成绿色后又突然变成蓝色,然后再过渡到绿色。一直持续到渐变填满矩形。
SVG

截图

尽管 reflect 和 repeat 听起来好像差不多,但是结果是截然不同的。上篇讲线性渐变的时候也看到了,不过我觉得 reflect 和 repeat 在径向渐变上看起来更好玩一些。不过如果没有浏览器支持的话,那还是so sad(Chrome完全没问题啊)。
总结
渐变是可用于SVG元素填充和描边的第三种类型(前两种是纯色和图案)。
你可以创建线性渐变和径向渐变,除了渐变本身,两个元素的工作原理是一样的。你可以按照自己喜欢的定义足够多的颜色结点,然后缩放、变换,或者在一个渐变中引用和继承另一个渐变,随心所欲。
径向渐变你需要设置半径,放置的位置以及渐变的焦点。一旦你尝试并理解了每个值都是干嘛的,就会发现其实用起来是很简单的。
学习线性渐变和径向渐变最好的方法是复制我提供的实例,或者你在其它地方找到的实例,然后修改属性值,来看看结果。
cx``cy``fx``fy 这几个值的不同,会导致很多差异。你会发现半径比较小的话,渐变会比较明显,在设置 spreadMethod 的值的时候。
我们已经学习SVG有一段时间了,所以我想是时候进入下一个主题了,下篇要讲SVG文本啦~

以上是关于如何给SVG填充和描边应用径向渐变的主要内容,如果未能解决你的问题,请参考以下文章

如何给SVG填充和描边应用线性渐变

SVG渐变

SVG图案

如何给button控件添加描边填充背景和描边

如何给button控件添加描边填充背景和描边

如何使用 Skia Sharp 添加矩形并将填充颜色和描边颜色应用于该对象?