这段时间在豆瓣上看有什么剧的时候,发现豆瓣的loading动画还挺棒的。因此决定模仿着来写一个。css
我经过CSS3
配合SVG
来完成此次模仿豆瓣的loading动画。没用过SVG
的也不用慌,我下面会写出相应的属性方便你去理解。由于这个真的超简单。那么咱们就直奔主题吧html
咱们须要先完成一个静态的笑脸
浏览器
始化SVG视图的大小bash
<svg width="100" height="100"></svg>
复制代码
我指定了一个宽高都为100px
的区域,width=”100”
和width=”100px”
是等价的。svg
咱们把嘴巴
给画出来,在svg
内先画一个圆函数
<circle class="mouth" cx="50" cy="50" r="14"></circle>
复制代码
cx
和 cy
属性定义圆点的 x
和 y
坐标。动画
看到浏览器上面多了一个填充的黑色圆点spa
接下来咱们给咱们的嘴巴加上css
样式3d
.mouth {
fill: none;
stroke: #00B51D;
stroke-width: 5;
stroke-linecap: round;
stroke-dasharray: 44, 44;
transform-origin: center; /* transform动画时以自身中心做为基点 */
}
复制代码
对应的属性调试
css属性 | 说明 | 此处 |
---|---|---|
fill | 填充颜色 | none(不填充) |
stroke | 轮廓的颜色 | #00B51D |
stroke-width | 轮廓的宽度 | 5 |
stroke-linecap | 开放路径两端的形状 | round |
stroke-dasharray | 建立虚线 | 44, 44 |
transform-origin | 旋转元素的基点位置 | center(自身中心) |
这里重点讲一下stroke-dasharray
,它的属性值可为none
、<dasharray>
和inherit
。
<dasharray>
它是一个<length>
和<percentage>
数列,数与数之间用逗号或者空白隔开,指定短划线和缺口的长度。
一个参数时: 实际上是表示虚线长度和每段虚线之间的间距
两个参数或者多个参数时:一个表示长度,一个表示间距
10
,间距10
,而后重复 虚线长10
,间距10
10
,间距5
,而后重复 虚线长10
,间距5
20
,间距10
,虚线长5
,接着是间距20
,虚线10
,间距5
,以后开始如此循环根据圆的周长公式L=2πr
,圆的半径r=14
,因此L=87.96452≈88
,那么咱们取虚线长度为44
,间距44
作一条虚线,恰好就是圆周长的一半。
可见此时咱们的嘴巴
部分已经完成了
接下来开始画眼睛
,我又画了一个circle
。
<circle class="eye" cx="50" cy="50" r="14"></circle>
复制代码
咱们依然能够经过stroke-dasharray
来画出一对眼睛
先把嘴巴
注释掉,避免影响咱们调试。
stroke-dasharray的虚线长度为0
的时,则能够获得无数个
点状的圆。根据上面圆的周长公式咱们能够获得周长为88
,那么咱们每1/4
个长度就为22
,此时咱们再把间距调整为66
。此时两个点的垂直距离恰好为90度
接下来咱们给咱们的眼睛加上css
样式
.eye {
fill: none;
stroke: #00B51D;
stroke-width: 5;
stroke-linecap: round;
stroke-dasharray: 0, 66;
}
复制代码
为了让嘴巴对齐,咱们左旋转45度
,给eye
加上transform
属性
transform-origin: center;
transform: rotate(-45deg);
复制代码
这样子咱们就完成了眼睛
了
通过我无数遍慢放(一帧一帧)的观察豆瓣的加载动画,终于找到了规律(哭)。
加动画效果,这也是最激动的一步,咱们先来看下嘴巴
部分
经过动画咱们能够看出嘴巴
部分是旋转了两圈
的,而且在旋转第一圈
的时候,两边的间距缩小为1/4
,在第二圈
的时候,间距恢复为1/2
,且最后有一段的停留时间
。
根据最后的一段停留时间
和旋转两圈
咱们能够经过transform
完成,简单
@keyframes mounthAni {
80%, 100% {
transform: rotate(720deg);
}
}
复制代码
第一圈
的时候两边间距缩小为1/4
,也就是此时stroke-dasharray
的值为 44, 22
,后续再恢复为1/2
@keyframes mounthAni {
40% {
stroke-dasharray: 44, 22; /* 间距改成1/4 */
}
80%, 100% {
stroke-dasharray: 44, 44; /* 间距恢复为1/2 */
transform: rotate(720deg);
}
}
复制代码
动画的运行速度为开始快,结束慢,因此咱们使用ease-out
做为贝塞尔曲线函数值
这样嘴巴
的动画就完成了
一样的,经过动画咱们能够看出眼睛
部分一样是旋转了两圈
,而且在旋转第一圈
的时候,两边的间距增大为7/8
,在第二圈
的时候,间距恢复为3/4
,且最后有一段的停留时间
。
@keyframes eyeAni {
40% {
stroke-dasharray: 0, 77; /* 间距改成7/8 */
}
80%, 100% {
transform: rotate(675deg); /* 间距恢复为3/4 */
stroke-dasharray: 0, 66;
}
}
复制代码
动画的运行速度为开始和结束慢,因此咱们使用ease-in-out
做为贝塞尔曲线函数值
至此咱们的眼睛
动画也就完成了
咱们把两个动画整合起来,这样就完成了模仿豆瓣的loading动画了,特简单。
html
<svg width="100" height="100">
<circle class="mouth" cx="50" cy="50" r="14"></circle>
<circle class="eye" cx="50" cy="50" r="14"></circle>
</svg>
复制代码
css
.mouth {
fill: none;
stroke: #00B51D;
stroke-width: 5;
stroke-linecap: round;
stroke-dasharray: 44, 44;
transform-origin: center; /* transform动画时以自身中心做为基点 */
animation: mounthAni 2.3s ease-out infinite;
}
.eye {
fill: none;
stroke: #00B51D;
stroke-width: 5;
stroke-linecap: round;
stroke-dasharray: 0, 66;
transform-origin: center;
transform: rotate(-45deg);
animation: eyeAni 2.3s ease-in-out infinite;
}
@keyframes mounthAni {
40% {
stroke-dasharray: 44, 22; /* 间距改成1/4 */
}
80%, 100% {
stroke-dasharray: 44, 44; /* 间距恢复为1/2 */
transform: rotate(720deg);
}
}
@keyframes eyeAni {
40% {
stroke-dasharray: 0, 77; /* 间距改成7/8 */
}
80%, 100% {
transform: rotate(675deg); /* 间距恢复为3/4 */
stroke-dasharray: 0, 66;
}
}
复制代码
CSS3
动画已足够强大,可是若是要实现上面那种间距可变大变小
的动画效果,只用CSS
的话我仍是没有想到怎么实现,若是各位有方法的话欢迎评论告诉我😀,因此使用了SVG
加CSS
来完成,眼睛
部分本来想过使用animateMotion
来完成,奈何看了半天仍是不会用🤣,因此就想着只用CSS
的动画效果完成了此次的动画,没想到意外的简单,因此把方法分享给你们。整个loading动画都围绕着stroke-dasharray
展开,用到的SVG
属性真的是冰山一角,上面的内容若是有什么错误的话还望各位多多指教。