svg简单动画
就是等同于c3的那些动画变换。例如:rotate 旋转,skewX 和 skewY 斜切,scale 缩放,translate 位移。
.rect {
transform: rotate(30deg) translate(20px, 50px);
}
<!-- svg标签属性不需要指定单位。并且class形式的变换优先级大 -->
<svg width="500" height="200" viewBox="0 0 500 200" style="border: 1px solid black;">
<rect
class="rect"
x="5"
y="5"
stroke="red"
stroke-width="3"
width="100"
height="50"
transform="translate(20, 50) rotate(30)"
>
</rect>
</svg>
如图,可以看出采取的是classs属性的变换。先旋转后位移。
svg复杂动画
通过transform属性的matrix属性值来使图形不规则变换。
CSS函数 matrix()
指定了一个由指定的 6 个值组成的 2D 变换矩阵。这种矩阵的常量值是隐含的,而不是由参数传递的;其他的参数是以列优先的顺序描述的。
matrix(a, b, c, d, tx, ty)
-
a b c d 描述线性变换的
<number>
。 -
tx ty 描述如何应用这个变换的
<number>
。
<svg width="500" height="200" viewBox="0 0 500 200" style="border: 1px solid black;">
// 变化前的矩形
<rect x="5" y="5" stroke="red" stroke-width="3" width="100" height="50">
</rect>
// 变化后的矩形
<rect x="5" y="5" stroke="red" stroke-width="3" width="100" height="50" transform="matrix(1, 0, -1, 1, 0, 50)">
</rect>
</svg>
前后图形点的计算公式:变换之前点的坐标(x1, y1) 变换之后点的坐标(x2, y2) 计算公式:x1a+y1c+tx=x2, x1b+y1d+ty=y2
通过使用svg属性来做一些高级动画
实现高级动画之前,我们首先需要介绍一下svg的stroke-dasharray, stroke-dashoffset属性。
stroke-dasharray
指定短划线和缺口的长度。
- 如果提供了奇数个值,则这个值的数列重复一次,从而变成偶数个值。因此,5,3,2等同于5,3,2,5,3,2。
- 如果提供了偶数个值,则这些值依次表示短划线长度,缺口长度,短划线长度,缺口长度...。
<svg width="500" height="200" viewBox="0 0 500 200" style="border: 1px solid black;">
<rect x="5" y="5" stroke="red" stroke-width="3" width="100" height="50" stroke-dasharray="10 20 30 40" fill="none">
</rect>
</svg>
<svg width="500" height="200" viewBox="0 0 500 200" style="border: 1px solid black;">
<rect x="5" y="5" stroke="red" stroke-width="3" width="100" height="50" stroke-dasharray="10 20 30" fill="none">
</rect>
</svg>
具体请访问mdn: developer.mozilla.org/zh-CN/docs/…
stroke-dashoffset
属性指定了dash模式到路径开始的距离。简单来说就是图标在视口中的偏移量。他是从右往左偏移。 需要配合stroke-dashoffset使用才有效果。
<svg width="500" height="200" viewBox="0 0 500 200" style="border: 1px solid">
<line x1="0" y1="10" x2="500" y2="10" stroke="red" stroke-width="10" stroke-dashoffset="100" stroke-dasharray="500">
</line>
</svg>
案例1:环形进度条
这个案例其实很简单,我们需要通过circle标签绘制两个大小一样的圆。后面的圆用于绘制动画。通过控制stroke-dasharray属性值来控制动画。由于动画的起始是从圆的右侧开始的,所以需要根据具体情况来改变起始位置,通过matrix。
关键知识点:
- keyframes 动画
- stroke-dasharray 使用技巧
- matrix 计算公式
.circle {
animation: circle 5s linear infinite;
}
@keyframes circle {
from {
stroke-dasharray: 0 1069;
}
to {
stroke-dasharray: 1069 0;
}
}
<div>
<svg width="440" height="440" viewbox="0 0 440 440">
<circle cx="220" cy="220" r="170" stroke-width="50" stroke="#D1D3D7" fill="none"></circle>
<circle
class="circle"
cx="220"
cy="220"
r="170"
stroke-width="50"
stroke="#00A5E0"
fill="none"
transform="matrix(0,-1,1,0,0,440)"
/>
</svg>
</div>
同样的方法我们实现一个矩形进度条,核心代码:
<svg width="200" height="200" viewBox="0 0 200 200">
<rect x="0" y="0" width="200" height="200" fill="none" stroke="grey" stroke-width="8"></rect>
<rect x="0" y="0" width="200" height="200" fill="none" stroke="blue" stroke-width="8" class="rect" transform="matrix(0,1,-1,0,200,0)"></rect>
</svg>
matrix 计算方法:
案例2:描边动画
实现要素:通过stroke-dasharray使图标先绘制出来。在使用stroke-dashoffset实现图标的从无到有。(totalPath -> 0)。
获取图标的路径总长度。
const path = document.getElementById('id');
const pathLen = path.getTotalLength();
.class-name {
fill: none;
stroke: #333;
stroke-width: 1;
animation: logo 5s linear infinite forwards;
}
@keyframes logo {
from {
stroke-dasharray: totalPath;
stroke-dashoffset: totalPath;
}
to {
stroke-dasharray: totalPath;
stroke-dashoffset: 0;
}
}