SVG动画进阶:SMIL技术深度解析与应用实战

本文深入探讨SMIL在SVG动画中的高级应用,包括路径动画、同步控制与变换技巧,通过实际案例展示如何超越CSS动画限制,实现复杂动态效果。

Smashing Animations Part 3: SMIL未死,宝贝,SMIL未死

虽然CSS动画能为设计注入活力,但在SVG中添加简单的SMIL(同步多媒体集成语言)动画能实现更强大的效果。Andy Clarke将解释SMIL动画如何在CSS力所不及之处发挥作用。

SMIL规范由W3C于1998年推出,用于多媒体同步,远早于CSS动画或基于JavaScript的动画库。它内置于SVG 1.1中,这也是我们今天仍能使用它的原因。

你可能听说过SMIL已死,但事实并非如此。谷歌在近十年前撤销了弃用该技术的决定,它对于希望以简单语义方式添加动画的设计师和开发者来说仍是绝佳选择。

基础动画原理

动画本质上通过几种基本技术随时间改变元素的外观和位置:通过上下左右移动元素创造运动感(如瑜伽熊在屏幕上移动);围绕固定点旋转物体可创建从简单旋转到自然运动的效果(如降落伞下的熊从天而降);缩放使元素放大、缩小或拉伸,增加戏剧性、创造透视或模拟深度;改变颜色和透明度可增添氛围、创造情绪并增强视觉叙事。

这些效果均可通过CSS动画实现,但某些SVG属性无法用CSS动画化。幸运的是,通过SMIL动画我们能做得更多——结合复杂动画、沿路径移动对象,并精确控制其启动、停止和中间过程。

构建动画

<animate>是SVG中多个动画元素之一。结合attributeName值,它能基于元素的一个或多个属性实现动画。

大多数动画教程从移动基本形状开始,比如这个圆形:

1
2
3
<circle r="50" cx="50" cy="50" fill="#062326" opacity="1">
  <animate attributename="cx" from="50" to="500" dur="1s"></animate>
</circle>

若需更精确控制,可用分号分隔的值序列替代fromto

1
<animate attributename="cx" values="50; 250; 500; 250;" dur="1s"></animate>

还可定义动画重复次数(repeatCount)及重复停止时间(repeatDur):

1
<animate attributename="cx" values="50; 250; 500; 250;" dur="1s" repeatcount="indefinite" repeatdur="180s"></animate>

实际应用案例

在1959年"Brainy Bear"剧集的标题卡中,瑜伽熊处于疯狂科学家的大脑实验中,能量围绕他辐射。通过SMIL实现:

  1. 为三个路径元素添加透明度动画:
1
2
3
<path opacity="1" stroke="#fff" stroke-width="5">
  <animate attributename="opacity" values="1; .25; 1;" dur="1s" repeatcount="indefinite"></animate>
</path>
  1. 通过begin属性错开动画开始时间:
1
2
3
<animate begin="0s"></animate>
<animate begin="0.5s"></animate>
<animate begin="1s"></animate>
  1. 组合多个动画属性:
1
2
<animate attributename="opacity" ...></animate>
<animate attributename="stroke-width" values="5;7;5" ...></animate>
  1. 使用fill="freeze"保持动画最终状态:
1
<animate attributename="fill" values="#50D9E0; #E18C50;" dur="5s" fill="freeze"></animate>

animateTransform元素

<animateTransform>用于动画化变换效果,包括旋转、缩放、倾斜和平移:

1
<animatetransform attributename="transform" type="rotate" values="0;360" dur="2s"></animatetransform>

通过additive="sum"accumulate="sum"属性可实现相对变换和累积效果。

高级控制技巧

  1. 延迟启动:
1
<animate begin="2s"></animate>
  1. 点击触发:
1
<animate begin="click"></animate>
  1. 组合触发条件:
1
<animate begin="click + 0.5s"></animate>

同步动画

通过ID引用和相对时间实现复杂同步:

1
2
3
<animateTransform id="yogi" ...></animateTransform>
<animateTransform begin="yogi.end + 0.5s" ...></animateTransform>
<animateTransform begin="yogi.begin + 2s" ...></animateTransform>

路径动画

<animateMotion>元素使元素沿指定路径运动:

1
<animateMotion dur="2s" path="M0,0 L100,100 ..."></animateMotion>

或引用预定义路径:

1
2
3
4
5
6
<defs>
  <path id="motionPath" d="..."/>
</defs>
<animateMotion>
  <mpath href="#motionPath"/>
</animateMotion>

通过keyPointskeyTimes精确控制运动速度:

1
<animateMotion keyPoints="0;0.35;0.5;0.65;1" keyTimes="0;0.1;0.5;0.95;1"></animateMotion>

结论

SMIL动画在SVG中仍然是强大工具,能够控制变换、动画复杂运动路径并同步多个动画,无需框架或JavaScript依赖。其紧凑性使其非常适合小型SVG效果。

SMIL包含的begin属性使动画链式调用比CSS更直观,且SMIL存在于SVG文件内部,非常适合随资源传输的动画。虽然SMIL按现代标准不算新颖且可能有些小众,但它仍然充满魔力。

不要被"SMIL已死"的误解阻碍使用这一出色工具。谷歌近十年前就撤销了弃用SMIL的决定,它对于寻求简单语义方式添加动画的设计师和开发者来说仍是绝佳选择。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计