
在svg中,为图形元素添加动态效果是提升用户体验和视觉吸引力的关键。本教程将指导您如何通过smil(synchronized multimedia integration language)动画,为静态的svg线条和圆形元素创建逼真的振动或摆动效果。
1. 核心原理:将直线转换为路径进行动画
对于简单的直线(<line>),直接进行复杂的曲线振动动画并不直观。为了实现线条的弯曲和摆动,我们通常需要将其转换为一个<path>元素。路径元素通过一系列命令(如M移动、L画线、C贝塞尔曲线)来定义形状,这使得我们能够更灵活地控制其形态变化。
在本例中,我们将一条直线转换为三次贝塞尔曲线路径。虽然它在初始状态下看起来像一条直线,但通过调整控制点,我们可以使其在动画过程中呈现出弯曲的效果。
<svg viewBox="0 -50 300 200" width="300">
<!-- 初始直线转换为三次贝塞尔曲线路径 -->
<path stroke="black" stroke-width="3" fill="red" d="M10,50C100,50 200,50 250,50">
<!-- 使用SMIL动画路径的d属性 -->
<animate
attributeName="d"
values="M10,50C100,50 200,50 250,50; /* 初始状态 */
M10,50C100,50 200,50 248,80; /* 向下弯曲 */
M10,50C100,50 200,50 250,50; /* 返回初始状态 */
M10,50C100,50 200,50 248,20; /* 向上弯曲 */
M10,50C100,50 200,50 250,50;" /* 返回初始状态 */
dur="5s"
repeatCount="indefinite"/>
</path>
</svg>代码解析:
- <path d="M10,50C100,50 200,50 250,50">:定义了一个从(10,50)开始,到(250,50)结束,并经过两个控制点(100,50)和(200,50)的三次贝塞尔曲线。在初始状态下,所有点的y坐标相同,因此它看起来是水平的。
- <animate>:这是SMIL动画的核心元素。
- attributeName="d":指定要动画的属性是路径的d属性。
- values="...":定义了动画过程中d属性将依次经历的值列表。通过改变终点和控制点的y坐标,我们模拟了线条的上下摆动。
- dur="5s":动画持续时间为5秒。
- repeatCount="indefinite":动画将无限次重复播放。
2. 同步动画:路径与圆形元素的联动
为了使动画更加生动和连贯,通常需要将与线条相关的其他元素(如末端的圆形)进行同步动画。圆形的位置应与路径的终点保持一致,以模拟整体的振动效果。
<svg viewBox="0 -50 300 200" width="300">
<path stroke="black" stroke-width="3" fill="red" d="M10,50C100,50 200,50 250,50">
<animate
attributeName="d"
values="M10,50C100,50 200,50 250,50;
M10,50C100,50 200,50 248,80;
M10,50C100,50 200,50 250,50;
M10,50C100,50 200,50 248,20;
M10,50C100,50 200,50 250,50;"
dur="5s"
repeatCount="indefinite"/>
</path>
<!-- 动画圆形元素 -->
<circle cx="250" cy="50" r="20" stroke="black" stroke-width="3" fill="red" >
<!-- 动画圆心的x坐标 -->
<animate
attributeName="cx"
values="250;248;250;248;250"
dur="5s"
repeatCount="indefinite"/>
<!-- 动画圆心的y坐标 -->
<animate
attributeName="cy"
values="50;80;50;20;50"
dur="5s"
repeatCount="indefinite"/>
</circle>
</svg>代码解析:
- <circle>元素:定义了一个半径为20的圆形,初始圆心在(250,50)。
- animate attributeName="cx":动画圆心的cx(x坐标)属性,使其在250和248之间摆动,与路径终点的x坐标变化同步。
- animate attributeName="cy":动画圆心的cy(y坐标)属性,使其在50、80、20之间摆动,与路径终点的y坐标变化同步。
- 两个animate元素的dur和repeatCount属性与路径动画保持一致,确保了两者动画的同步性。
3. 高级应用:在动画圆形中嵌入图像
如果希望在振动的圆形中显示图像而非纯色填充,可以使用<symbol>、<clipPath>和<use>元素组合来实现。这种方法允许我们裁剪图像以适应圆形形状,并像动画其他SVG元素一样动画化整个图像容器。
<svg viewBox="0 -50 300 200" width="300">
<!-- 定义裁剪路径,用于将图像裁剪成圆形 -->
<clipPath id="cp">
<circle cx="20" cy="20" r="20" stroke="black" stroke-width="3" fill="red" />
</clipPath>
<!-- 路径动画保持不变 -->
<path stroke="black" stroke-width="3" fill="red" d="M10,50C100,50 200,50 250,50">
<animate
attributeName="d"
values="M10,50C100,50 200,50 250,50;
M10,50C100,50 200,50 248,80;
M10,50C100,50 200,50 250,50;
M10,50C100,50 200,50 248,20;
M10,50C100,50 200,50 250,50;"
dur="5s"
repeatCount="indefinite"/>
</path>
<!-- 定义一个symbol,包含要裁剪的图像 -->
<symbol id="s">
<!-- 图像通过clip-path引用上面定义的圆形裁剪路径 -->
<image xlink:href ="https://assets.codepen.io/222579/darwin300.jpg" width="40" height="40" clip-path="url(#cp)"/>
</symbol>
<!-- 使用use元素引用symbol,并对其进行动画 -->
<use xlink:href="#s" x="230" y="30">
<!-- 动画use元素的x坐标 -->
<animate
attributeName="x"
values="230;228;230;228;230"
dur="5s"
repeatCount="indefinite"/>
<!-- 动画use元素的y坐标 -->
<animate
attributeName="y"
values="30;60;30;0;30"
dur="5s"
repeatCount="indefinite"/>
</use>
</svg>代码解析:
- <clipPath id="cp">:定义了一个裁剪路径,其中包含一个圆形。这个圆形的cx和cy是相对于裁剪路径自身的坐标系,与外部动画无关。
- <symbol id="s">:用于封装可重用的SVG图形片段。在这里,它包含一个<image>元素。
- <image xlink:href="..." width="40" height="40" clip-path="url(#cp)"/>:嵌入了一个外部图片,并使用clip-path="url(#cp)"将其裁剪成上面定义的圆形形状。
- <use xlink:href="#s" x="230" y="30">:通过xlink:href="#s"引用了定义的<symbol>。x和y属性定义了symbol实例的初始位置。
- animate attributeName="x" 和 animate attributeName="y":与之前动画圆形的方式类似,我们现在动画的是<use>元素的x和y属性,使其整体在屏幕上振动,从而带动内部的图像一起摆动。注意这里的values需要根据use元素的初始x和y进行相应调整,以实现同步的振动效果。
4. 注意事项与总结
- SMIL动画的兼容性: SMIL在现代浏览器中得到了广泛支持,但部分旧版浏览器可能存在兼容性问题。在实际项目中,可以考虑使用CSS动画或Web Animations API (WAAPI)作为替代方案,它们提供了更强大的控制能力和更好的性能。
- 路径的灵活性: 将线条转换为<path>是实现复杂形状动画的关键。通过调整贝塞尔曲线的控制点,您可以创建各种各样的弯曲和波动效果。
- 同步性: 确保所有相关元素的动画参数(如dur和repeatCount)保持一致,是实现流畅同步动画的基础。values属性的设置也需要仔细计算,以使各个元素的运动轨迹协调一致。
- 坐标系统: 理解SVG的viewBox和元素自身的坐标系统对于精确控制动画至关重要。viewBox定义了SVG画布的用户坐标系统,而元素的x、y、cx、cy等属性则在此坐标系统内定位。
通过本教程,您应该已经掌握了如何利用SMIL动画为SVG图形添加生动的振动效果,无论是简单的线条和圆形,还是包含复杂图像的动态元素。这些技术能够极大地提升SVG图形的表现力,为您的Web应用或数据可视化项目注入生命力。










