之前做过CSS动画、canvas动画,但svg动画第一次做,最终效果如下图所示。
分析
由上图可以看出,波浪动画是由多个不同的‘波浪’组成,而每个波浪则是由近似正弦图形组成,最后的‘波动’效果,其实是静态的波浪循环向左运动产生的。
同时介绍后面会用到的几个svg相关标签:
path:定义形状的基础元素,其中d属性就是图形的路径。静态的波浪就是这个元素绘制的,后面会再单独介绍
animateTransform:定义目标元素的变形属性,波浪的循环移动就是使用这个属性实现的
g:组合对象的容器
绘制单个静态波浪
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path
d="
M0 70
Q 75 39, 150 70
T 300 70
V 100 H 0 V 0"
fill="#ccc">
</path>
</svg>
上面是写好的单个波浪,其中d属性绘制了形状,fill属性表示填充的颜色。
d属性中使用了以下几个命令:
M:M x y表示移动到(x, y)点( svg中左上角是(0,0)点 )
Q:Q x1 y1, x2 y2表示绘制二次贝塞尔曲线,x1 y1为二次贝塞尔的控制点,x2 y2为终点,可以使用贝塞尔生产曲线工具帮助生成。
T:T x y表示生成上一个二次贝塞尔曲线的镜像,其终点坐标为(x,y)
V:V y表示从当前点(x0,y0)垂直移动到(x0, y)
H:H x表示从当前点(x0, y0)水平移动到(x, y0)
所以上面代码可以翻译后为:首先移动到(0,70)处,再绘制起点为(0,70),终点为(150,70),控制点为(75,39)的二次贝塞尔曲线,接着绘制已(300,70)为终点的镜像二次贝塞尔曲线,最后依次移动到(100,70),(0,70),(0,0),从而形成闭合曲线。
动起来
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="300"
height="200">
<g >
<path
d="M 0 70 Q 75 39, 150 70 T 300 70 T 450 70 T 600 70 T 750 70 V 100 H 0 V 0"
fill="#ccc">
</path>
<animateTransform
attributeName="transform"
attributeType="XML"
type="translate"
from="0" to="-300" dur="1.5s"
repeatCount="indefinite">
</animateTransform>
</g>
</svg>
增加了animateTransform后就动其来了,该标签的几个属性含义为:
attributeName:需要运动的属性
type:具体运动的类型
from:运动初始值
to:运动终点值
dur:运动时间
repeatCount:重复次数,indefinite为无限循环
看了后就发现其实很简单,有一下几个点需要注意,首先path绘制图形的路径至少是svg宽加上from-to的宽,第二,to的值为周期的n/2倍,这个可以想象一下正弦的波形。注意了这两点,波浪看起来已经有点模样了。
多个波浪合成
只有一个波浪,看起来还是不够逼真,将多个不同周期波浪合成,并填充不同透明度的颜色形成最终效果。
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300" height="200">
<g fill="rgba(106,127,239,0.1)">
<path d="M 0 70 Q 75 39, 150 70 T 300 70 T 450 70 T 600 70 T 750 70 V 100 H 0 V 0"></path>
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="0" to="-300" dur="1.5s" repeatCount="indefinite"></animateTransform>
</g>
<g fill="rgba(106,127,239,0.15)">
<path d="M 0 70 Q 87.5 47, 175 70 T 350 70 T 525 70 T 700 70 T 875 70 T 1050 70 V 100 H 0 V 0"></path>
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="0" to="-350" dur="3s" repeatCount="indefinite"></animateTransform>
</g>
<g fill="rgba(106,127,239,0.18)" transform="translate(-903.868 0)">
<path d="M 0 70 Q 135 36, 270 70 T 540 70 T 810 70 T 1080 70 V 100 H 0 V 0" transform="translate(-38.232284367796474, 0)"></path>
<animateTransform attributeName="transform" attributeType="XML" type="translate" from="0" to="-540" dur="2s" repeatCount="indefinite"></animateTransform>
</g>
</svg>
抽象成组件
当手写两个波浪之后,就会发现很多地方是相同的,总结之后会发现只有svg的宽高、周期、峰值、移动速度、初始偏移量(即正弦的初相位)、填充颜色、叠加波浪个数这几个是变化的,因此可以做成组件,隐藏内部的复杂度。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。