svg 动画取值属性


动画取值属性

动画取值属性 定义了动画中目标属性的值随时间是如何变化的,动画取值属性提供了对关键帧的相对时间和离散值之间的插值方法和控制。

比如填充颜色从浅到深,光照滤镜的光源移动位置,噪点矩阵的混乱程度等等,都可以通过动画取值属性来设置。

属性列表

  • calcMode:用于设置都插值模式。

  • values:用于设置过渡值列表。

  • keyTimes:用于设置过渡关键帧的时间点。

  • keySplines:使用曲线来控制插值时间。

  • from:设置过渡的开始状态。

  • to:设置过渡的最终状态。

  • by:设置过渡的相对偏移值。

from

from 属性用来定义动画操作属性的初始值,to 属性用来定义动画操作属性的最终值。动画会从 from 状态过渡到 to 状态,from 属性和 to 属性需要搭配使用。

示例:

<svg width="200" height="100" viewPort="0 0 200 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
	<rect fill="#f0f" x="10" y="10" width="100" height="100">
		<animate attributeType="XML" attributeName="width" from="100" to="150" dur="3s" repeatCount="indefinite" />
	</rect>
</svg>

dur 表示动画进行一个周期的时间,repeatCount 表示动画的重复次数,“indefinite” 表示无限次重复。

to

to 属性用来定义动画操作熟悉的最终值。使用参见 from

by

by 用来定义动画操作属性相对默认静止状态下的偏移值。这个属性适用于动画是从默认静止状态开始的情况。

示例:

<svg width="200" height="100" viewPort="0 0 200 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
	<rect fill="#f0f" x="10" y="10" width="100" height="100">
		<animate attributeType="XML" attributeName="width" by="50" dur="3s" repeatCount="indefinite" />
	</rect>
</svg>

上面矩形的宽度会从默认的 100 过渡到偏移 50 单位,即 150,效果如下:

不论 from-to 属性,还是 by 属性,它们的动画都只能进行一次过渡,而 values 属性可以使用分号进行多个关键帧设置,从而实现复杂的过渡效果。

values

values 用来设置目标属性在各个关键帧值的大小。它的值是一个由分号组成的列表,每项的类型取决于 attributeName 操作属性的值类型。

示例:

<rect x="0" y="0" height="5" width="7" fill="#f0f">
	<!-- 设置 rect 的 width 属性依次按照 7; 20; 0; 15; 7 来进行动画变化 -->
	<animate attributeName="width" values="7; 20; 0; 15; 7" dur="3s"></animate>
</rect>

<rect x="0" y="0" height="5" width="7" fill="#f0f">
	<!-- 设置 rect 的 fill 属性依次按照 #f0f; #0ff; #ff0; #f0f 来进行动画变化 -->
	<animate attributeName="fill" values="#f0f; #0ff; #ff0; #f0f" dur="3s"></animate>
</rect>

<!-- ..... -->

<feConvolveMatrix
	order="3,3"
	kernelMatrix="
		1 0 0
		0 0 0
		0 0 -1"
>
	<!-- 设置 feConvolveMatrix 的 kernelMatrix 属性依次按照 1 0 0 0 0 0 0 0 -1; -2 2 2 -2 0 2 -2 -1 0; 1 0 0 0 0 0 0 0 -1; 三个矩阵值来进行动画变化 -->
	<animate
		attributeName="kernelMatrix"
		values="
			1 0  0
			0 0  0
			0 0 -1;
			-2  2  2
			-2  0  2
			-2  -1 0;
			1 0  0
			0 0  0
			0 0 -1;
		"
		dur="1s"
		repeatCount="indefinite"
	></animate>
</feConvolveMatrix>

上面代码演示了如何使用 values 属性。可以看到,values 的值类型万有由 attributeName 指定的属性决定,values 必须配合 attributeName 属性,否则无效。

calcMode

calcMode 指定了动画插值的模式。

类型:calcMode = “discrete | linear | paced | spline”

  • discrete

    discrete 为离散型插值,此时动画会从上一个值直接切换到下一个值,不会产生平滑过渡的效果。

  • linear

    linear 为线性插值,此时动画一个值一个值进行平滑过渡,相邻两个值的过渡时间由 keyTimes 提供。

  • paced

    paced 为节奏型插值,此时动画一个值一个值的平滑过渡,并且整个动画是匀速的。

  • spline

    spline 为曲线过渡,此时动画会根据三次贝塞尔曲线重新分布每个时间段,相邻两个值的切换时间由 keyTimes 提供。每段时间的贝塞尔曲线使用 keySplines

    使用曲线模式时,因为插值时间按照曲线进行,其结果就是插值结果也是曲线进行。

    比如让宽度从 0 到 100,使用曲线就可以从慢到快来插值,其结果就是动画执行时宽度也是从慢到快进行增长的,因为插值按照贝塞尔曲线进行进行。详见 keySplines

下面演示离散型、线性和节奏型插值模式:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="200" height="150" viewBox="0 0 20 15">
	<rect x="0" y="0" height="5" fill="#f0f">
		<!-- 离散过渡 -->
		<animate
			calcMode="discrete"
			attributeName="width"
			values="0; 10; 11; 20; 0"
			dur="5s"
			repeatCount="indefinite"
		></animate>
	</rect>
	<rect x="0" y="5" height="5" fill="#0ff">
		<!-- 线性过渡 -->
		<animate
			calcMode="linear"
			attributeName="width"
			values="0; 10; 11; 20; 0"
			dur="5s"
			repeatCount="indefinite"
		></animate>
	</rect>
	<rect x="0" y="10" height="5" fill="#ff0">
		<!-- 节奏过渡 -->
		<animate
			calcMode="paced"
			attributeName="width"
			values="0; 10; 11; 20; 0"
			dur="5s"
			repeatCount="indefinite"
		></animate>
	</rect>
</svg>

效果如下:

可以较为明显的看到它们有以下特点:

calcMode相邻两个值的过渡时间过渡方式效果
discrete相等直接切换动画是跳跃式进行的,每步花费时间相同
linear相等插值过渡动画一步一步进行,每步花费时间相同
paced不一定相等插值过渡动画整体匀速播放,没有中间步骤

keyTimes

keyTimes 属性是一个以分号分割的时间列表,它被用来指定各个值之间的过渡时间。列表中的值在 [0, 1] 之间,0 为动画的启动时间,1 为动画的结束时间。

keyTimes 在不同模式中表现不同:

  • 当使用 linearspline 模式时,列表中的第一个值必须是 0,最后一个值必须是 1。过渡会依次按照 keyTimes 时间对各个值进行插值过渡。(keyTimes 值的数量应该和 values 相同)

  • 当使用 discrete 模式时,列表中的第一个值必须是 0。列表中的值对应了过渡值的切换时间。(keyTimes 值的数量应该和 values 相同)

  • 当使用 paced 模式时,该属性将被忽略。

示例:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="200" height="150" viewBox="0 0 20 10">
	<rect x="0" y="0" height="5" fill="#f0f">
		<!-- 离散过渡 -->
		<animate
			calcMode="discrete"
			attributeName="width"
			values="0; 10; 11; 20; 0"
			keyTimes="0; 0.05; 0.8; 0.9; 1"
			dur="5s"
			repeatCount="indefinite"
		></animate>
	</rect>
	<rect x="0" y="5" height="5" fill="#0ff">
		<!-- 线性过渡 -->
		<animate
			calcMode="linear"
			attributeName="width"
			values="0; 10; 11; 20; 0"
			keyTimes="0; 0.05; 0.8; 0.9; 1"
			dur="5s"
			repeatCount="indefinite"
		></animate>
	</rect>
</svg>

上面示例演示了 discrete (离散型)过渡和 linear (线性)过渡时,使用 keyTimes 的效果。每个值具体的过渡时间点为:

值区间时间区间实际过渡时间
0 ~ 100 ~ 0.050.05 * 5s = 0.25s
10 ~ 110.05 ~ 0.80.75 * 5s = 3.75s
11 ~ 200.8 ~ 0.90.1 * 5s = 0.5s
20 ~ 00.9 ~ 10.1 * 5s = 0.5s

最后的渲染效果如下:

linear 的插值时间是线性的,spline (曲线型)模式的过渡时间和 linear 类似,但是 spline 的插值时间是会使用曲线进行重分布,详情查看 keySplines

keySplines

keySplines 可以让过渡不是匀速的,比如让 width 属性在 10s 内从 0 到 100 进行过渡,匀速的情况下,动画每经过 1s,那么 width 的大小就会增加 10,这时插值时间是线性的。而 keySplines 可以改变这种线性过渡,使用曲线重新分布过渡效果。

keySplines 指定三次贝塞尔曲线控制插值时间,该属性仅在 spline 模式下生效。keySplines 每项由 4 个值组成,依次代表 x1、y1、x2、y2,它们会组成两个点 [x1, y1] 与 [x2, y2] 来作为曲线的控制点,曲线的起点为 [0, 0],终点为 [1, 1],点的坐标轴取值范围是 [0, 1]。keyTimes 将指定 n 个值,相邻的值依次组成 n - 1 个时间区间,那么 keySplines 将指定 n - 1 条三次贝塞尔曲线与其进行映射。

下面代码演示了一个矩形区域随着贝塞尔曲线过渡的效果,另外绘制了两条贝塞尔曲线对应矩形的变化规律:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="400" height="400" viewBox="0 0 3 1">
	<rect x="0" y="0" height="1" fill="#f0f">
		<animate
			id="Spline1"
			calcMode="spline"
			attributeName="width"
			values="0; 3; 0"
			keyTimes="0 ; 0.5 ; 1"
			keySplines="0 0.8 1 0.2;0.8 0 0.2 1"
			dur="10s"
			repeatCount="indefinite"
		></animate>
	</rect>
</svg>

小球基于 Y 轴上的移动就对应矩形过渡百分比,矩形从 0 到 3 又回到 0 的过程使用了两条曲线,所以拉长和收缩的过渡效果不同。效果如下:

另外两条曲线路径和动画使用曲线相同,额外绘制用于更清楚的了解动画运动过程。

参考