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

发布于 彦子

图案一样,渐变可以给作品增加深度和趣味。虽然当前的趋势是扁平化设计,渐变还是很经常使用的。

上节我们大概讲了线性渐变的内容。今天就到径向渐变啦。径向渐变和线性渐变是很相似的,区别只是在于如何定义渐变。

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>中定义渐变,设置idradial,方便我们在后面的矩形中引用。

<radialGradient>元素中放置了两个颜色结点,一个蓝色一个绿色。两个都是用<stop>元素定义的,<stop>元素中包括三个属性。

  • offset: 在径向渐变中,它表示从点(fx,fy)到外边缘的圆的百分比值距离。它定义了渐变结点的位置。值从01之间,或者0%100%
  • stop-color: 定义offset结点位置的颜色
  • stop-opacity: 定义颜色结点的透明度,值从01,或0%100%

我们先看看上面实例的结果,然后再接着讨论<radialGradient>元素的属性。

渐变从中心处的蓝色,一直过渡到边缘处的绿色。我们现在来看看它是如何创建出来的。

除了id="radial"这个属性,这里面还有五个属性,fxfycxcyr

  • r: 设置圆的半径
  • cxcy: 渐变的中心点坐标。要移动渐变的位置,改变这俩值即可。
  • fxfy: 定义渐变的焦点坐标。你可以通过改变这俩值,移动渐变第一个颜色结点的位置。

你应该理解半径是干啥的,所以我下面找的实例是帮助大家理解cxcyfxfy的。

这里我把前面实例的半径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%的位置。还有,蓝色的焦点(由fxfy确定)还是在矩形的中心。

最后,把半径都cx都变回50%,把fx变成20%

<radialGradient id="radial" fx="20%" fy="50%" cx="50%" cy="50%" r="50%">

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

cxcy属性定义了渐变的中心位置。fxfy定义了渐变的焦点的位置。默认都是50%,但是cxcy控制的渐变层面和fxfy控制的不一样。

因为我只改变x方向的的cfy方向的部分并没有太大改变。

<radialGradient>元素的属性

径向渐变有几个属性,和线性渐变一样。

**xlink:href**属性提供了在渐变中引用另一个渐变的方法。通过这个属性引用的渐变是可继承的,也可以被重写。

gradientUnits属性决定了cx``cy``fx``fy的值是否缩放,它接受两个值,我们前面的文章中也讲过了。

  • userSpaceOnUse: cx``cy``fx``fyr表示的值是根据当前用户坐标系统的。也就是说这些值都是绝对值,不会进行缩放。
  • objectBoundingBox: cx``cy``fx``fyr表示当前应用的元素的坐标系统。也就是说渐变随着引用它的元素一起缩放。

你还可以使用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,和线性渐变一样。它可以接受三个值,padreflectrepeat,它定义了渐变如何开始和结束,当cxcy的值是在0%100%里面的时候。

  • pad:(默认值)使用开始和结束位置的颜色结点来填充剩余的部分。
  • reflect: 反射渐变图案,从开始->结束,再从结束->开始,然后开始->结束,往复直到空间都填满。
  • repeat: 从start-to-end重复渐变图案,直到空间填满。

和线性渐变一样,我相信这三个值都很容易通过下面的实例来理解。reflectrepeat的值在一些浏览器中工作有点小问题。所以我下面放了可以工作的情况的截屏。

先放这篇文章开始的那个实例,然后改几个值。首先我把半径变成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

截图

svg渐变

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

SVG

截图

svg渐变

尽管reflectrepeat听起来好像差不多,但是结果是截然不同的。上篇讲线性渐变的时候也看到了,不过我觉得reflectrepeat在径向渐变上看起来更好玩一些。不过如果没有浏览器支持的话,那还是so sad(Chrome完全没问题啊)。

总结

渐变是可用于SVG元素填充和描边的第三种类型(前两种是纯色和图案)。

你可以创建线性渐变和径向渐变,除了渐变本身,两个元素的工作原理是一样的。你可以按照自己喜欢的定义足够多的颜色结点,然后缩放、变换,或者在一个渐变中引用和继承另一个渐变,随心所欲。

径向渐变你需要设置半径,放置的位置以及渐变的焦点。一旦你尝试并理解了每个值都是干嘛的,就会发现其实用起来是很简单的。

学习线性渐变和径向渐变最好的方法是复制我提供的实例,或者你在其它地方找到的实例,然后修改属性值,来看看结果。

cx``cy``fx``fy这几个值的不同,会导致很多差异。你会发现半径比较小的话,渐变会比较明显,在设置spreadMethod的值的时候。

我们已经学习SVG有一段时间了,所以我想是时候进入下一个主题了,下篇要讲SVG文本啦~

本文根据@Steven Bradley的《How To Apply SVG Radial Gradients To A Fill Or Stroke》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://vanseodesign.com/web-design/svg-radial-graidents/

彦子

在校学生,本科计算机专业。逗比一枚,热爱前端热爱生活,喜欢CSS喜欢JavaScript喜欢SVG,爱玩PS玩AI玩啊逗比的软件。努力向上,厚积薄发。

如需转载,烦请注明出处:https://www.fedev.cn/svg/svg-radial-graidents.htmlAir Max 95 Flyknit