使用SVG来制作颜色渐变效果是非常方便的。SVG的线性渐变和径向渐变元素有一些可用的参数选项可以让我们来控制渐变的变化。在这篇文章中,我们将介绍一些基本的SVG渐变知识。
浏览器支持
所有的现代浏览器,包括桌面和移动版本的浏览器都支持SVG。
关于SVG SMIL动画(动画在SVG元素内部),IE浏览器、IE mobile和Opera Mini不支持这种动画,但是它被最新版本的Chrome、Firefox、Safari、Opera的桌面和移动版本的浏览器所支持。
SVG渐变
在我们开始制作SVG渐变动画之前,我们首先要知道SVG渐变使如何工作的。
我们可以在SVG中使用渐变属性,但是如果我们不使用fill
或stroke
属性来填充它,它是不会有任何视觉效果的。
基本的SVG渐变的代码结构像下面这个样子:
<svg> <defs> <linearGradient id="greenGradient"> <stop offset="0" stop-color="#b2ed9d" /> <stop offset="100%" stop-color="#569b3d" /> </linearGradient> </defs> <rect width="600" height="150" fill= "url(#greenGradient)" /> </svg>
渐变的详细信息我们写在<defs>
元素中,但是这些信息不会有任何视觉效果,知道我们通过ID来在fill
属性中引用它:fill= "url(#greenGradient)"
。在上面的代码中,我们画了一个600像素宽,150像素高的矩形,并用绿色渐变来填充它。
<stop>
元素代表了映射在渐变中的颜色和它们的位置。
SVG渐变属性
<linearGradient>
和<radialGradient>
的属性值允许我们指定渐变的颜色和坐标。
下面我们来看一下我们的DEMO中用到的属性:
- ID:一个渐变的唯一标识符,它会在
fill
或stroke
中被用于引用渐变。 - x1, x2, y1, y2: x1, x2, y1, y2的值用于指定SVG线性渐变在X和Y轴上的开始和结束坐标。默认左值为0,右值为100%。
- cx, cy, r, fx, fy:径向渐变的属性和线性渐变的属性差不多,只是坐标系更为复杂。cx、cy 和 r(半径)用于指定径向渐变的外层圆,最外层的半径stop点为100%。fx和fy调用径向渐变的圆点,这里的stop点为0%。
<stop>
在渐变元素的内部包含了<stop>
节点。在<stop>
节点中的属性定义了渐变的颜色被放置在什么地方,以及颜色使用多少的透明度。
offset
属性用于表示该颜色位于渐变的什么位置上。对于线性渐变它是一段渐变直线上的距离,对于径向渐变它的位置在原点到外层圆的边线的距离。
stop-color
属性用于定义在该stop点上使用什么颜色。stop-opacity
属性用于定义该颜色的透明度。
<animate>
<animate>
元素允许我们选择指定的渐变属性,然后在指定的时间内将它们修改为其它值。<animate>
元素会被放置在我们想要制作渐变效果的元素的内部。下面是一个简单的矩形渐变动画的代码结构:
<svg> <rect x="0" y="20" width="100" height="100"> <animate attributeName="x" from="0" to="400px" dur="5s" repeatCount="indefinite" /> </rect> </svg>
这个动画效果会将矩形从它的起始点沿X轴移动400像素,动画持续时间为5秒钟,并且是无限循环动画。
<animate>
元素有下面几个基本的属性:
- attributeName:attributeName 定义执行动画的属性名称。例如上面的代码中,attributeName的值为"x",表示要在X轴上移动元素。
- to, from:
from
和to
属性用于指定目标元素的开始和结束值。 - values:在
<values>
元素的内部,我们可以创建一组用分号隔开的值,动画会在持续时间内应用这些值。 - dur:动画的持续时间。
- fill:
fill
属性通常是用于填充SVG的颜色,但是在<animate>
元素中它有不同的含义。我们可以将它的值设置为freezes
,这样动画会在结束后被“冻结”,不再从新开始。 - repeatCount:指定SVG动画的重复次数。它的值可以是一个数值,或者是
indefinite
。
渐变动画
为了制作SVG渐变效果,我们需要指定哪些属性需要执行动画,例如stop-color
、offset
或者坐标。
为了在一个矩形中制作渐变效果,我们需要在<rect>
元素中放置<animate>
元素,然后指定我们想要的<stop>
值。为了在<linearGradient>
元素和<radialGradient>
元素中直接动画一个属性,例如坐标,我们可以将<animate>
放置在渐变原宿中,但是要放在<stop>
之外。
下面是<stop>
节点上制作stop-color
动画的SVG结构:
<stop offset="<value>" stop-color="<color>"> <animate attributeName="stop-color" from=”<color>” to=”<color> dur="<duration>" repeatCount="indefinite" /> </stop>
应用举例
在这篇文章中我们会举三个SVG渐变的例子:燃烧的火焰、阳光照在树上和天空颜色变化的效果。
燃烧的火焰
在这个SVG动画中我们要针对两个火焰来执行填充和动画。它们会被放置在<svg>
元素的<defs>
节点之中。
<defs> <radialGradient id="smallGradient" fy="90%"> <stop offset="0%" stop-color="#f4c708"></stop> <stop offset="100%" stop-color="#f7e69a"></stop> <animate attributeName="fy" dur="700ms" from="90%" to="0%" repeatCount="indefinite" /> </radialGradient> <radialGradient id="largeGradient" fy="90%"> <stop offset="0%" stop-color="#ff8806"></stop> <stop offset="100%" stop-color="#d9574a"></stop> <animate attributeName="fy" dur="700ms" from="90%" to="0%" repeatCount="indefinite" /> </radialGradient> </defs>
上面有两个径向渐变:"smallGradient"和"largeGradient"。它们在fy
坐标上被执行相同的动画,在700毫秒时间内从90%变化到0%。这个效果被制作为无限循环动画。
这些动画被目标元素使用fill
属性的url
通过ID标识符来引用:
fill="url(#largeGradient)"
阳光照在树上的效果
在这个demo中使用的是stop-color
来制作渐变动画效果。这里有两种不同的渐变代表不同的树的颜色,一个是较暗的绿色渐变,另一个较亮的绿色渐变。两个颜色的渐变动画本质是相同的,只是使用的颜色不同而已。
<defs> <linearGradient id="darkGradient" x1="30%" y1="70%"> <stop offset="0%" stop-color="#0b2d13"> <animate attributeName="stop-color" values="#0b2d13; #79c98c" dur="3s" fill="freeze" /> </stop> <stop offset="100%" stop-color="#79c98c"> <animate attributeName="stop-color" values="#79c98c; #0b2d13" dur="3s" fill="freeze" /> </stop> </linearGradient> <linearGradient id="lightGradient" x1="30%" y1="70%"> <stop offset="0%" stop-color="#054f16"> <animate attributeName="stop-color" values="#054f16; #91bc9c" dur="3s" fill="freeze" /> </stop> <stop offset="100%" stop-color="#91bc9c"> <animate attributeName="stop-color" values="#91bc9c; #054f16" dur="3s" fill="freeze" /> </stop> </linearGradient> </defs>
<animate>
元素放置在100% stop点的内部,它要动画的属性名称是stop-color
。渐变动画的颜色值使用的的<values>
属性中的值,动画持续时间为3秒,并且动画在移除循环结束之后就会被“冻结”(停止)。
天空颜色变化效果
这个demo实际是动画stop的offset属性。它有两组渐变,每一组都有一系列的颜色变化值。它通过offset
的一个额外动画,使stop点从100%变化到0%,从而使整个动画无限循环下去。
<defs> <linearGradient id="skyGradient" x1="100%" y1="100%"> <stop offset="0%" stop-color="lightblue" stop-opacity=".5"> <animate attributeName="stop-color" values="lightblue;blue;red;red;black;red;red;purple;lightblue" dur="14s" repeatCount="indefinite" /> </stop> <stop offset="100%" stop-color="lightblue" stop-opacity=".5"> <animate attributeName="stop-color" values="lightblue;orange;purple;purple;black;purple;purple;blue;lightblue" dur="14s" repeatCount="indefinite" /> <animate attributeName="offset" values=".95;.80;.60;.40;.20;0;.20;.40;.60;.80;.95" dur="14s" repeatCount="indefinite" /> </stop> </linearGradient> </defs>
在stop-color
动画中,在14秒的时间内,颜色会均匀的循环改变为<values>
中的颜色值。额外的offset
动画会在14秒时间内使用<values>
中的值将stop点从100%修改到0%。
这里需要注意一点:在执行offset
属性动画时使用百分比的值,可以在Firefox浏览器中正常执行。Chrome和Safari在<animate>
元素中执行offset
属性动画时使用百分比值时不会得到正确的结果。
使用方法
这篇文章简单的介绍了SVG渐变的代码结构,以及如何制作SVG渐变动画效果。希望通过这篇文章能有更多的人去研究和使用SVG渐变动画,更希望这篇文章对你能有所帮助。