本节主要讲解如何实现以下几种动画
- 图表展示-圆环
- 操作成功,操作失败动画
- Logo 线条绘制动画
- Loading 加载动画
通过普通的div实现方式与svg的实现做对比,体验使用SVG做动画的好处,以及SVG在实际项目中应用
并使用Vue及React封装一个基于SVG的圆环图表展示组件
CSS3 版本的实现
效果来源 sweetAlert 插件
CSS3实现鸡蛋饼饼状图loading
使用多层遮罩+css动画
成功的动画
结构
<!-- 深色环 --> |
圆环动画:半圆遮罩旋转,漏出下面深色圆环,旋转一周之后,回位,重新遮盖住,显示浅色圆环
对号动画,线段的位移
CSS.ui-icon-success{
&.active{
&:after{
animation: rotatePlaceholder 4.25s ease-in;
}
.ui-icon-success__line-tip{
animation: animateSuccessTip 0.75s;
}
.ui-icon-success__line-long{
animation: animateSuccessLong 0.75s;
}
}
}
@keyframes rotatePlaceholder {
0% { transform: rotate(-45deg); }
5% { transform: rotate(-45deg); }
12% { transform: rotate(-405deg); }
100% { transform: rotate(-405deg); }
}
@keyframes animateSuccessLong {
0% { width: 0; right: 46px; top: 54px; }
65% { width: 0; right: 46px; top: 54px; }
84% { width: 55px; right: 0px; top: 35px; }
100% { width: 47px; right: 8px; top: 38px; }
}
@keyframes animateSuccessTip {
0% { width: 0; left: 1px; top: 19px; }
54% { width: 0; left: 1px; top: 19px; }
70% { width: 50px; left: -8px; top: 37px; }
84% { width: 17px; left: 21px; top: 48px; }
100% { width: 25px; left: 14px; top: 45px; }
}
loading动画
使用三个半圆 + 深色圆环 + 浅色圆环
结构
<div class="ui-icon-circle"> |
- 浅色圆环
ui-icon-circle
- 右边半圆遮罩
ui-icon-circle:after
旋转180后隐藏 - 左边圆遮罩
ui-icon-circle:before
旋转180 - 右边半圆带深色环遮罩
ui-icon-circle __half
用于修复被遮罩的半环
css
.ui-icon-circle{ |
线条动画原理回顾
两个关键的属性
stroke-dasharray
: 逗号或空格分隔的数值列表。表示各个虚线端的长度。可以是固定的长度值,也可以是百分比值stroke-dashoffset
: 表示虚线的起始偏移
两种实现方式
- 使用stroke-dasharray, 改变 线段的长度
- 使用stroke-dashoffset, 改变起始偏移的距离
SVG微交互的实际应用
loading、占位图、圆环进度、各种图表、H5活动
获取Path的总长度
el.getTotalLength()
只能获取Path的长度
其它形状的获取,可以从AI或sketch的属性面板中获取或通过公式计算得出
常用SVG标签参数解析
Circle 圆
<circle cx="100" cy="100" r="50" fill="#fff"></circle> |
- r 半径
- cx 圆心x位置, 默认为 0
- cy 圆心y位置, 默认为 0
Path 路径
这里只列举用到的圆弧的表示方法
两点之间的弧形可能有四种情总,两种小弧形,两种大弧形
a 45 45, 0, 0, 0, 125 125
参数说明:起点坐标、large-arc-flag(大小弧标记,0小,1大)、sweep-flag(弧线方向,0逆时针,1顺时针)、终点
<svg width="325px" height="325px" version="1.1" xmlns="http://www.w3.org/2000/svg"> |
更多关于Path的参数说明,请查看 SVG PATH MDN
Line 直线
<line x1="10" x2="50" y1="110" y2="150"/> |
- x1 起点的x位置
- y1 起点的y位置
- x2 终点的x位置
- y2 终点的y位置
polyline 折线
<polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/> |
points 点集数列,每个数字用空白、逗号、终止命令符或者换行符分隔开,每个点必须包含2个数字,一个是x坐标,一个是y坐标 如0 0, 1 1, 2 2”
SVG成功动画
结构
一个背景环,一个动画环,一条折线
<g id="Group-3" transform="translate(2.000000, 2.000000)"> |
动画
先发生环的填充和收缩动画,再延时执行对号的成功动画
@keyframes ani-success-circle { |
SVG失败动画
结构
背景环、动画环、X
号的两条线
<g id="Group-2" transform="translate(2.000000, 2.000000)"> |
动画
先环进行动画,然后 X
号的右边线开始描边动画,然后左边线开始描边动画
@keyframes ani-error-line{ |
SVG加载动画
结构
一个圆环<div class="ui-loading">
<div class="ui-loading-inner" :style="innerStyle">
<svg viewBox="0 0 100 100">
<circle class="ui-loading-path" cx="50" cy="50" r="40" fill="none" :style="strokeStyle"></circle>
</svg>
</div>
<span class="ui-loading-text"><slot><slot></span>
</div>
动画
不停的旋转,并增长线段的长度@keyframes ui-loading-spin {
0%{transform:rotate(0); stroke-dasharray:0, 251.327px;}
100%{transform:rotate(360deg); stroke-dasharray:251.327px, 251.327px;}
}
SVG Logo动画
原理: 多个文字路径叠加,不同的描边长度,同时动画
结构
<svg version="1.1" viewBox="0 0 1000 600" xmlns="http://www.w3.org/2000/svg"> |
动画
.use-text:nth-child(1) { |
封装成组件
将圆环进度封装成Vue及React组件
React组件 - Circle
使用方法
React.createClass({ |
配置参数
{ |
实现细节
- 使用
Math.PI * 2 * r
来计算出圆的周长 - 使用
Path
来绘制两段弧形组成圆形 - 使用
stroke-dashoffset
来实现描边动画 - 组件的大小由来层包装的容器决定
var Circle = React.createClass({ |
Vue组件 - ui-progress-circle
基本原理与设置同上
使用方法
<progress-circle |
配置参数
'size': { |
实现细节
<div class="progress-circle"> |