级别: 初级 Brian John Venn (vennb@uk.ibm.com), 软件测试员, IBM Business Integration,Hursley Park
2003 年 9 月 01 日 可伸缩向量图形(Scalable Vector Graphics,SVG)是一种用于绘制二维图形的基于 XML 的语言。听上去没有吸引力?它的作用还远不止这一点。SVG 具有许多令人激动的可用特性,例如转换、alpha 蒙片、滤镜效果和动画。本篇技巧文章提供了一些工作示例,向您演示了如何将 SVG 动画的五种形式应用于您的 SVG 文档。
可伸缩向量图形(SVG)动画使用了同步多媒体集成语言级别 2(Synchronized Multimedia Integration Language Level 2,SMIL — 发音是“smile”),它是一种类 HTML 的语言,使人们能够简单地创作出一些交互式视听表示。在 SMIL 中指定特性的起始值和结束值以及持续时间。这些内容被传递给某类查看程序(例如 RealPlayer),后者负责处理动画。
如果您已经基本了解 SVG,那么本篇技巧文章将对您有所帮助。
developerWorks教程“
Introduction to Scalable Vector Graphics”是一个极佳的起点。
注:要查看本技巧文章中的 SVG 文档,您需要一个 SVG 查看器,该查看器(和一个包含所有相关文件的 .zip 文件)可在
参考资料中找到。
 |
告诫
SVG 查看器一直都在朝着好的方向在发展,但相对而言,它们仍然处于初级阶段。尽管它们可以象说明的那样很好地工作,并且本文描述的动画在每一点上都能有平滑的效果,但是,例如,如果您尝试用 SVG 动画技术来重新创建动画电影“Toy Story”,那么输出将是十分缓慢且有停顿的。因此别尝试制作大批动画。
|
|
动画的五种形式
SVG 具有五种内置的动画类型:
-
animate 、
-
animateMotion 、
-
animateTransform 、
-
animateColor 、
-
set
animate
首先我将从相应的名为
animate 的类型入手:
在
清单 1 中,我绘制了一个以
x=250,y=250 为中心的圆。
animate 特性的工作方式是在声明的一段时间内将指定的特性从一个值变化为另一个值。这里,圆半径将在 5 秒内从 1 变为 50。
repeatCount 设置了动画的重复次数,它可以是大于 0 的任何数值,包括“indefinite”。
单击以查看该动画。
注:要查看 SVG 文档,需要一个 SVG 查看器,该查看器(以及包含所有相关代码文件的 .zip 文件)可在
参考资料中找到。
清单 1. 使圆产生动画效果
<svg>
<circle cx="250" cy="250" r="1" >
<animate attributeName="r" from="1" to="50" dur="5s"
repeatCount="indefinite" />
</circle>
</svg>
|
SVG 对象的任何特性都可以用这种方式来更改。例如,如果把
animate 行更改为:
<animate attributeName="cx" from="1" to="250" dur="5s"
repeatCount="indefinite" /> |
那么圆将从左向右滚。
可以在一个 SVG 对象上组合多个
animate 元素,以产生特殊效果。在清单 2 中,圆的 x 和 y 坐标及其半径同时产生动画效果。
清单 2. 使用多个特性产生动画效果
<svg>
<circle cx="250" cy="250" r="1" >
<animate attributeName="r" from="1" to="50" dur="5s"
repeatCount="indefinite" />
<animate attributeName="cx" from="1" to="250" dur="5s"
repeatCount="indefinite" />
<animate attributeName="cy" from="1" to="250" dur="5s"
repeatCount="indefinite" />
</circle>
</svg>
|
这一次,该圆从左上方滚向右下方,并在滚动的过程中不断变大。
单击这里以查看该动画。
可以使更多的简单元素(如大小和形状)产生动画效果。例如下面的示例:
清单 3. 使用渐变色产生动画效果
<svg>
<defs>
<radialGradient id="blueradial">
<stop offset="0" style="stop-color:white;"/>
<stop offset="100%" style="stop-color:blue;">
<animate attributeName="offset" from="1%" to="100%" dur="5s"
repeatCount="indefinite"/>
</stop>
</radialGradient>
</defs>
<circle cx="250" cy="250" r="200" style = "fill: url(#blueradial);"/>
</svg>
|
在
清单 3 中,蓝色渐变色的
stop offset 特性在 5 秒钟内渐渐变大,从而使白色渐变色向外变大并产生爆炸效果。
单击这里以查看该动画。
animateMotion
利用
animateMotion 元素,可以在指定的路径上移动任何 SVG 元素。
清单 4. 运动路径示例
<svg>
<!-- Draw the path -->
<path d="M50,125 C 200,25 250,525, 400, 125" style="fill: none;
stroke:black;"/>
<rect width="25" height="25" style="fill: cyan; stroke: red;" >
<!-- Move the rectangle along the path. -->
<animateMotion path="M50,125 C 200,25 250,525, 400, 125" dur="6s"
fill="freeze"/>
</rect>
</svg>
|
在
清单 4 中,首先将绘制矩形移动所遵循的确切路径,这样您就可以看到矩形将如何移动。然后绘制矩形,并且矩形沿着该路径进行移动。在
animateMotion 元素的末尾是
fill="freeze" 特性;该特性可用于所有
animate 元素,它指示 SVG 查看器在动画完成时让元素“冻结”在其最终位置上。
单击这里以查看该动画。
在查看该运动时,您会发现矩形在沿着路径移动的过程中其方向不会发生变化。矩形的左上角始终沿着路径移动,这是因为矩形的长边和短边是从左上角开始绘制的。
通过将
rotate="auto" 属性添加到
animateMotion 元素,可以使对象在沿着其路径移动的过程中使其 X 轴发生倾斜。
单击以查看该动画。还可以为
rotate 元素指定具体的值,因此如果您希望 SVG 元素在整个运动路径中旋转 45 度,那么可以使用
rotate="45" 。
在
清单 4 中,矩形遵循的运动路径出现了两次。通过使用
mpath 元素,可以避免这种重复情形,如下所示:
清单 5.
mpath 示例
<svg>
<path id="smoothCurve" d="M50,125 C 200,25 250,525, 400, 125"
style="fill: none; stroke:black;"/>
<rect width="25" height="25" style="fill: cyan; stroke: red;" >
<animateMotion dur="6s" fill="freeze" rotate="auto">
<mpath xlink:href="#smoothCurve"/>
</animateMotion>
</rect>
</svg>
|
清单 5 生成了完全相同的输出,但它更有效。当希望使多个元素沿着同一个运动路径产生动画效果时,
mpath 也是非常有用的。
 |
查看 SVG 内容
要查看 SVG 文档的源代码,请用鼠标右键单击 SVG 文档,然后选择
View Source。
|
|
animateTransform
SVG 包含五种可执行的转换:
-
translate
-
scale
-
rotate
-
skewX
-
skewY
使用
animateTransform 使它们产生动画效果。
清单 6.
animateTransform 示例
<svg>
<text x="5" y="15" style="font-size: 8pt;">animateTransform example
<animateTransform attributeName="transform" type="scale" from="1"
to="5" begin="1" dur="4s" fill="freeze"/>
</text>
</svg>
|
这次您正在使一个文本元素产生动画效果。
scale 特性从 1 增加到 5,因此文本的最终大小是原始大小的 5 倍。
单击这里以查看该动画。
还请注意
begin 属性的使用。这告诉 SVG 查看器何时开始动画。
还可以在同一个元素中组合多个转换动画。清单 7 包含了
scale 和
rotate 转换。
清单 7. 使用多个转换产生动画效果
<svg>
<text x="50" y="50" style="font-size: 8pt;">animateTransform Example
<animateTransform attributeName="transform" type="scale" from="1"
to="5" begin="0" dur="4s" fill="freeze" additive="sum"/>
<animateTransform attributeName="transform" type="rotate" from="0"
to="30" begin="0" dur="4s" fill="freeze" additive="sum"/>
</text>
</svg>
|
单击这里以查看该动画。当将多个转换组合在一个元素中时,必须将
additive 属性设置为
sum ,如
清单 7 所示;否则,列出的最后一个转换将覆盖以前的任何转换。如果清单 7 省去了这一设置,那么将只执行
rotate 转换。
animateColor
animateColor 将颜色从一个值变化为另一个值。
清单 8.
animateColor 示例
<svg>
<circle cx="250" cy="250" r="200" style="fill:red; stroke:blue;
stroke-width:5">
<animateColor attributeName="fill" from="red" to="green" dur="5s"
fill="freeze"/>
</circle>
</svg>
|
单击这里以查看该动画。可以组合各种设置颜色的方法来设置颜色。例如,可以用
##ff0000 代替
red ,而用
rgb(0,255,0) 代替
green ,但结果都一样。
还可以组合多种颜色的变化,以获得颜色循环的效果。在清单 9 中,圆的颜色从红色光谱变化为深蓝色光谱(
单击这里以查看该动画):
清单 9:颜色循环
<svg>
<circle cx="250" cy="250" r="200" >
<animateColor attributeName="fill" from="rgb(100%,0%,0%)"
to="orange" begin="0s" dur="5s"/>
<animateColor attributeName="fill" from="orange" to="yellow"
begin="prev.end" dur="5s"/>
<animateColor attributeName="fill" from="yellow" to="#00FFFF"
begin="prev.end" dur="5s"/>
<animateColor attributeName="fill" from="#00FFFF" to="blue"
begin="prev.end" dur="5s" />
<animateColor attributeName="fill" from="blue" to="indigo"
begin="prev.end" dur="5s" fill="freeze" />
</circle>
</svg>
|
请注意其中设置颜色的各种方法。由于是在多种颜色之间进行变化,因此需要将颜色转换写成脚本,这样它们就可以按照正确的顺序在各种光谱之间变动。要获得这种效果,请使用
begin="prev.end" 属性。该属性指示查看器在前一个动画结束时启动下一个动画。在对同一个对象编制多个动画的脚本时,可以将该属性用于任何动画元素。
set
set 动画类型将特性或属性设置为某个值,而不是随时间变化来执行更改。而是将该值立即设置为给定的值。在清单 10 中,3 秒钟后圆的半径将被设为 50,持续时间为 3 秒。3 秒后,半径将回到其原始值。
单击这里以查看该动画。
清单 10.
set 示例
<svg>
<circle id="circleSetExample" cx="250" cy="250" r="200"/>
<set id="animIdforSet" xlink:href="#circleSetExample"
attributeName="r" to ="50" begin="3s" dur="3s" />
</svg>
|
在本示例(
清单 10)中,
set 动画元素并未单独包含在
circle 元素中;而是通过
xlink:href 属性将
set 动画链接到圆的。究竟选择哪种方法来完成该工作只是个人喜好问题,但该方法确实允许将所有动画元素放在一起。
将它们组合在一起
本文描述的所有元素都可以组合在一起以产生各种效果。下面是三个动画,它们使用了本文中描述的各种动画效果。
-
日落(5K)— 在云慢慢漂浮经过的过程中,太阳落到了地平线下。随着太阳落下,天空逐渐变黑,而月亮和星星开始出现。太阳和云的移动是通过在 x 和 y 坐标上使用
animate 获得的。随着太阳落下地平线,使用
animateColor 来改变天空的颜色,通过变化月亮和星星的不透明性使它们渐渐显现出来。
-
彩虹(4K)— 旋转效果是通过使彩虹中每种颜色的
stroke-width 和
stroke-dashoffset 产生动画效果而获得的。
-
矩阵(8K)— 垂直滚动效果是通过利用不同的计时特性在文本上移动一系列矩形并改变不透明性而形成的。
需要特别注意的是这些动画的文件大小,最大的也只是极小的 8K 大小。请查阅这些动画的源代码,以了解它们的脚本是如何编制的。
参考资料
关于作者  | 
|  | Brian Venn 在为英国太空防御系统(British Aerospace Defence Systems)工作了三年后于 2000 年 10 月加入 IBM。他毕业于南安普敦大学,获得了天体物理学学士学位,并且通过了 DB2 和软件测试方面的认证。他目前在 Hursley Park 从事测试工作。这是他的第三篇
developerWorks文章,看看他所撰写的每篇文章,您会发现他的文章越来越棒了。可以通过
vennb@uk.ibm.com与 Brian 联系。
|
对本文的评价
|