实现路径动画的方案
路径动画在增强用户体验过方面还是挺有用的。当然你也可以用个gif图来实现,gif是万能的,但是前提是一定要满足业务对页面性能的要求。我们这里主要介绍的是现有的技术方案。
SVG SMIL animation
SMIL(Synchronized Multimedia Integration Language,同步多媒体集成语言)的首字母缩写简称,是有标准的。
SMIL允许你做下面这些事情:
- 动画元素的数值属性(X, Y, …)
- 动画属性变换(平移或旋转)
- 动画颜色属性
- 沿着运动路径运动
比如:
<svg width="320" height="320" xmlns="https://www.w3.org/2000/svg">
<g>
<text font-family="microsoft yahei" font-size="20" y="160" x="160">a2doc.com</text>
<animateTransform attributeName="transform" begin="0s" dur="10s" type="rotate" from="0 160 160" to="360 160 160" repeatCount="indefinite"/>
</g>
</svg>
展示出来就是下面的样子
看起来效果不错哈,兼容性也很好。

再给一个按照路径移动的例子:
<svg width="360" height="200" xmlns="https://www.w3.org/2000/svg">
<text font-family="microsoft yahei" font-size="40" x="0" y="0" fill="#cd0000">a2doc.com
<animateMotion path="M10,80 q100,120 120,20 q140,-50 160,0" begin="0s" dur="3s" rotate="auto" repeatCount="indefinite"/>
</text>
<path d="M10,80 q100,120 120,20 q140,-50 160,0" stroke="#cd0000" stroke-width="2" fill="none" />
</svg>
还有个优点是SMIL的动画是可以组合展示的,而且可以通过Javascript DOM API 操作动画启动和停止。
// svg指当前svg DOM元素
// 暂停
svg.pauseAnimations();
// 重启动
svg.unpauseAnimations()
具体的使用方法参考:SVG Animation SMIL Animation
PS:SMIL动画都是在CPU上运行的, 性能需要考量。
CSS offset-path
“SVG SMIL animation”虽然强大,但是由于是基于HTML属性生成的各类效果,因为就容易存在复用的问题,例如不同的位置的不同元素的不规则路径动画是一样的,那么我在设置的时候,要么冗余啰嗦,要么交叉不利于维护,有点早些年在HTML标签上写style
样式的味道。
或许是这个原因,Chrome浏览器开始有了放弃“SVG SMIL animation”的迹象,转而拥抱经过几十年成功验证的CSS来实现,offset-path
几乎可以看成是Chrome浏览器让元素沿着不规则路径运动的新宠儿。但毕竟是新宠儿,因此,相比较“SVG SMIL animation”,其兼容性还是差了两条街的。

之前叫motion-path,后来改成offset-path,看官方文档。先给个例子:
.horse-run {
/*之前语法 始于2015年9月,M58版本会移除,大约2017年4月*/
motion-path: path("M10,80 q100,120 120,20 q140,-50 160,0");
/*当前规范上的语法 2016年12月支持*/
offset-path: path("M10,80 q100,120 120,20 q140,-50 160,0");
animation: move 3s linear infinite;
}
@keyframes move {
/*之前语法*/
100% { motion-offset: 100%;}
/*当前规范语法*/
100% { offset-distance: 100%;}
}
<img src="horse.png" width="40" height="43" class="horse-run">
<svg width="280" height="150" viewBox="0 0 280 150">
<path d="M10,80 q100,120 120,20 q140,-50 160,0" stroke="#cd0000" stroke-width="2" fill="none" />
</svg>
展示效果:
a2doc.com
Canvas结合SMIL
其实只要有path路径,canvas能做任何事情。怎么运动都是小kiss。先给个库:canvas2svg ,这个库做的很好。但是我们在开发中可能不需要这么复杂的功能,我做了一个精简版,这里主要用于通过canvas自动获取形状轮廓的svg path,这样就可以做轮过动画了。
项目:canvas-svg-path, 可以先看下在线例子:https://chalecao.github.io/canvas-svg-path/demos/
这个方案是先用canvas获取边界,生成path路径,然后通过smil来做动画,但是有个明显的问题,就是SMIL动画都是在CPU上运行的,这样性能肯定不好。
Canvas粒子动画
以绘制圆角矩形的loading动画为例,已知宽W, 高H和圆角半径R(R <= H/2),假设loading的线宽是2px,那么可以计算圆角矩形的周长L:
L = 2 * W + 2 * pi * R + 2(H-R)
由于线宽是2px,那么总共粒子数量N:
N = L / 2
可以计算所有粒子的坐标W:
W = [{x1,y1},{x1,y1},{x1,y1} … ]
假设要用10个粒子绘制动画,计算每个粒子的颜色,然后按照W来运动就好了。