原文链接
为了之后产品可能的动画需求,我们需要调研各种可行的前端动画技术。相信 CSS3 动画和 JS 动画我们平常已经接触很多了,而 SVG 技术则很少用,事实上 SVG 也是一种强大的动画解决方案,可以帮我们解决传统动画做不到的技术痛点。
SVG 简介
SVG(Scalable Vector Graphics),可缩放矢量图形,具有放大缩小不失真的特性,可以用来创建矢量图。
SVG1.1 于 2003 年 1 月 14 日成为 W3C 推荐标准。
SVG 本质上是用 XML 语言描述的,所以它可以和 DOM 结构一样被 CSS 和 JS 编程控制,通过连续地改变 SVG 图形属性就可以创建 SVG 动画。
SVG 可用文本编辑器编辑,也可通过 Adobe Illustator 等专业编辑软件处理。
SVG 文件可单独使用,使用 XML 定义并包含 DTD 声明:
<?xml version=”1.0″ standalone=”no”?>
<!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1//EN”
“http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd”>
<svg xmlns=”http://www.w3.org/2000/svg” version=”1.1″>
<circle cx=”100″ cy=”50″ r=”40″ stroke=”black”
stroke-width=”2″ fill=”red” />
</svg>
在现代浏览器中,我们可以直接在 HTML 代码中嵌入 SVG 代码:
<div class=”svg-wrap”>
<svg xmlns=”http://www.w3.org/2000/svg” version=”1.1″>
<circle cx=”100″ cy=”50″ r=”40″ stroke=”black” stroke-width=”2″ fill=”red” />
</svg>
</div>
SVG path
SVG 可以绘制许多形状,这里不一一介绍,重点介绍下 svg path,它是 svg 形状中功能最为强大的一个,也是我们前端动画会经常用到的形状。
顾名思义,path 定义的是一组路径,你可以用 path 元素绘制矩形(直角矩形或者圆角矩形)、圆形、椭圆、折线形、多边形,以及一些其他的形状,例如贝塞尔曲线、2 次曲线等曲线。path 元素的形状是通过它的 d 属性决定的,d 属性中通常以字母为命令,如下所示:
M = moveto
L = lineto
H = horizontal lineto
V = vertical lineto
C = curveto
S = smooth curveto
Q = quadratic Bézier curve
T = smooth quadratic Bézier curveto
A = elliptical Arc
Z = closepath
以下 path 定义了一个三角形:它开始于位置 150 0,到达位置 75 200,然后从那里开始到 225 200,最后在 150 0 关闭路径。
<svg xmlns=”http://www.w3.org/2000/svg” version=”1.1″>
<path d=”M150 0 L75 200 L225 200 Z” />
</svg>
注意:绘制复杂的 path 路径应尽可能借助设计工具,人为计算 path 的 d 属性耗时耗力,也不是目前的学习重点。
path 的其他常用属性有:
stroke 定义路径颜色
stroke-width 定义路径宽度,单位像素
stroke-dasharray 用于创建虚线
fill 定义 path 闭合区域的填充颜色
基于 svg path 实现图片路径动画
点击这里查看 demo:
WPS Logo Demo
这个效果的实现并不复杂,首先我们需要 wps logo 的 svg 资源,可以借助 photoshop 和 Adobe Illustrator 从图片中生成 svg 路径。
第一步,使用 ps 魔棒工具去除白色背景,并选中路径,然后右键,建立工作路径:
点击菜单 -> 文件 -> 导出 -> 导出路径到 ai:
在 ai 中选中路径,存储为 svg 格式。然后在编辑器中打开 svg 即可查看到 path 的 d 属性了!
之后,在代码里创建 svg 图形,并指定其 stroke-width 等属性。
动画方面,使用 css animation 控制 path 的 stroke-dasharray 属性来实现动画,这个属性可以将 path 绘制为虚线。
如 stroke-dasharray: 10px 20px; 就定义了实线的长度是 10px,空白的长度是 20px,如下图所示:
利用这个原理,我们将实线的长度从 0 逐渐变为 path 总长度,将空白的长度逐渐变为 0,就可以实现类似“绘图”的效果了~
#wps-logo-path {
animation: wpsLogo 3s ease-in-out forwards;
}
@keyframes wpsLogo {
0% {
stroke-dasharray: 0 1078px;
}
100% {
stroke-dasharray: 1078px 0;
}
}
path 的总长度可以这样计算 $(‘#wpsLogoPath’)[0].getTotalLength()
动画过程中,可以设置监听,在动画的不同阶段执行不同的钩子函数:
document.addEventListener(‘webkitAnimationEnd’, function(e) {
}
代码中,我们还定义了线性渐变,用来填充 path 闭合区域内的背景值,fill: url(#wpslinear)
<defs>
<linearGradient id=”wpslinear” x1=”0%” y1=”0%” x2=”0%” y2=”100%”>
<stop offset=”0%” stop-color=”#FB5A43″/>
<stop offset=”100%” stop-color=”#FD3258″/>
</linearGradient>
</defs>
到这一步,svg path 动画的 demo 就基本做完了,我们可利用这个原理实现更复杂的 svg path 动画,如多个 path 的过渡动画,物体沿不规则 path 移动等等。svg 技术本身还是很复杂的,短时间掌握 svg 有一定的难度,必要时可以借助 svg 动画库实现需要的设计效果,做到技术灵活服务于产品。