这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战
介绍
很早之前看过一个大神写的华为手机充电,感觉非常惊艳,一直记忆犹新,最近仿照着也动手实现了一个。本期也作为充电水滴动画的一次扩展延伸,我们将带大家一起通过使用scss从零开始完成这个手机充电动画的案例,里面包含了一些css小技巧,希望大家喜欢。
接下来,我们先来一睹为快吧:
正文
1.基础结构
<div id="app">
<div class="loading">
<h5>60%</h5>
<div class="loading-warrper">
<div class="loading-circle"></div>
<div class="loading-drop">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
</div>
@use "sass:math";
@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro:400);
$color:#79f77f;
$num:12;
#app{
width: 100%;
height: 100vh;
background-color: black;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.loading{
width: 360px;
height: 360px;
position: relative;
h5{
width: 180px;
height: 180px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-family: 'Source Code Pro', monospace;
font-size: 48px;
font-weight: normal;
color: white;
z-index: 9;
display: flex;
align-items: center;
justify-content: center;
}
.loading-warrper{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-color: black;
display: flex;
align-items: center;
justify-content: center;
filter: contrast(10) hue-rotate(0);
}
}
一开始我们会引入sass:math和字体,字体是为了电量文字使用,而引入sass:math是因为这个项目用了vite搭建使用了最新sass,而且最新的sass已经不支持“/”符号做除法了,取而代之的是Math.div(a,b),即a/b。然后我们定义了num分别代表了主色与span的数量。
div#app作为主屏,用黑色铺满全屏,h5主要为了显示当前电量,用绝对定位压住下面的div.loading-warrper目的是为了不被div.loading-warrper的filter属性影响,而且div.loading-warrper我们用fixed定位,铺满全屏,他的目的是后面的div.loading-drop一直置于底部,不管多长的屏幕都可以适配,div.loading-circle则就是后面马上要说的了,用他去做旋转。
2.圆环旋转
.loading-circle{
position: relative;
width: 300px;
height: 300px;
box-sizing: border-box;
filter: blur(8px);
&::before {
content: "";
position: absolute;
width: 180px;
height: 180px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
background-color:black;
z-index: 10;
}
&::after {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 205px;
height: 205px;
transform: translate(-50%, -50%);
background-color: $color;
border-radius:42% 37% 55% 48% / 47% 43%;
animation: rotate 10s infinite linear;
}
}
@keyframes rotate {
50% {
border-radius:47% 43% / 42% 37% 55% 48%;
}
100% {
transform: translate(-50%, -50%) rotate(720deg);
}
}
这里要说明的就是div.loading-circle一定要带上filter: blur属性,他和上层的filter: contrast(10)配合,就是完成粘连效果两个必要属性。而其内部则是两个伪类,伪类after是绘制了一个椭圆,我们通过animation去完成一次旋转并改变其椭圆形状。伪类before则是绘制一个黑色圆形专门去遮盖伪类after,其实只显示边缘位置。
3.充电动画
.loading-drop{
position: absolute;
bottom: -90px;
left: 50%;
margin-left: -50px;
width: 120px;
height: 120px;
border-radius: 50%;
background-color: $color;
filter: blur(8px);
span{
width: 25px;
height: 25px;
display: block;
position: absolute;
border-radius: 50%;
background: $color;
@for $i from 0 through $num {
&:nth-child(#{$i}) {
$size:25 + random(7) + px;
left: 20 + random(80) + px;
top: 50%;
transform: translate(-50%, -50%);
width: $size;
height: $size;
animation: up #{random(5) + 5}s ease-in-out infinite;
animation-delay: -#{math.div(random(10000),1000)}s;
}
}
}
}
@keyframes up {
90% {
opacity: 0.7;
}
100% {
opacity: .5;
transform: translate(-50%, calc(-50vh + 60px));
}
}
这里在div.loading-drop依然要给他一个filter: blur属性,也是粘连效果。我们要画一个小圆用定位给他置于最下方,这样多高的屏幕他都会在最下面使他漏出一个小半圆来,然后我们给其下的span用过scss的@for方法去遍历他们,致使他们通过@random去随机获得大小、偏移还有动画的执行周期和延时。接下来动画就很简单了,我们最终目的是要让他往上飘,所以要改变其translateY的位置,我这里使用了css的计算方法,让往上飘到一边屏幕然后在加上一个圆的外围距离,这样就会兼容到所有高度了。
4.变色动画
.loading-warrper{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
filter: contrast(10) hue-rotate(0);
animation: changeColor 5s infinite linear;
background-color: black;
display: flex;
align-items: center;
justify-content: center;
}
@keyframes changeColor {
100% {
filter: contrast(50) hue-rotate(360deg);
}
}
我们期望颜色会随着时间不断发生变化,之前我们用了hsl去改变其第一个值H即灰度,这里就不用这么麻烦了,这里可以直接使用了filter: hue-rotate去改变,让其旋转360度,颜色就会随着时间推移而改变,这样是不是很方便。
结语
不知道你从中有收获了么,你可以看到粘连效果的又一次实践,也看到颜色变化除了hsl还有filter: hue-rotate方案。也可以了解到scss中@for,@random,math等的一些用法。
另外,本次在线演示案例中我用了pug模板语法,让整个html结构更加干净高效,大家也可以去了解一下。