动手实现抖音视频加载Loading
天天刷抖音,无意中发现抖音加载视频的loading蛮有趣的,是两个相互纠缠的小球。尝试用CSS实现一下。
动画分析
如果只看一只小球的话可以发现,小球在由远及近在做圆周运动,想象在三维空间中有一个球体,有人拿着它在与你视线平行的水平面上做圆周运动,你会发现呈现的就是图中单个球运动的效果了。
实现单个球体运动
创建dom元素画出小球。只看x轴的话,小球在水平移动,所以我们设置一个动画使小球左右移动,这个动画可以拆解为5个步骤:
- 初始位置,小球离我们最近,也使最大的时候,假设此时球心在中心位置
- 小球向右移动20个像素,大小缩放为原来的0.75倍
- 小球离我们最远,看起来最小,水平位置的话在中心位置
- 小球向左移动20个像素,大小缩放为原来的0.75倍
- 小球回到原点
代码如下:
@keyframes circle {
0%,100% {
transform: translateX(0px) scale(1);
}
25% {
transform: translateX(20px) scale(0.75);
}
50% {
transform: translateX(0px) scale(0.5);
}
75% {
transform: translateX(-20px) scale(0.75);
}
}
效果如图:
双球体运动
第二个球体的拆解步骤差不多,不同的地方是,球1最大的时候,球2是最小的,因此在动画中对换一下即可,代码如下:
@keyframes circleSecond {
0%,
100% {
transform: translateX(-25px) scale(0.5);
}
25% {
transform: translateX(-20px) scale(0.75);
}
50% {
transform: translateX(0px) scale(1);
z-index: 1;
}
75% {
transform: translateX(20px) scale(0.75);
}
}
两个小球在最大的时候均离我们最近,因而在最大时,给它们设置一个层级关系 z-index,效果如图:
可见动画上还存在两个不足,一个是重叠部分的效果,另一个就是动画看起不是那么平滑。
重叠
改变重叠部分的颜色可以使用CSS 的混合模式 mix-blend-mode。
代码:
.loading {
position: relative;
isolation: isolate;
}
.ball {
/* ... */
mix-blend-mode: multiply;
/* ... */
}
不同 mix-blend-mode 值的效果:
需要注意的是在容器中加上 isolation 属性,这样混合效果会只作用到容器中的元素,否则的话页面的背景颜色都会加入混合计算中去。如图:
平滑动画
总结一下实现 CSS 平滑动画的几种方式:
- 合理使用贝塞尔曲线,贝塞尔曲线在线制作工具。
- 尽可能的将每个阶段细分
- 使用canvas做动画
效果不太好,只能说大致还原了吧,动画过程节点还有待优化。
转载自:https://juejin.cn/post/7127896094922506248