巧用 CSS 实现酷炫的充电动画
知识点
使用 filter: hue-rotate() 对渐变色彩进行色彩过渡变换动画,
而我们无法对一个渐变色直接进行 animation ,这里通过滤镜对色相进行调整,从而实现了渐变色的变换动画。
我们知道,低电量时,电量通常表示为红色,高电量时表示为绿色。我们给色块添加点阴影的变化,有呼吸的感觉,让充电的效果看起来确实是在动,这是一个可以用在对要求不高的地方。我们看代码
代码如下:
<div class="container">
<div class="battery"></div>
</div>
//css
html,
body {
width: 100%;
height: 100%;
display: flex;
background: #e4e4e4;
}
.container {
position: relative;
width: 140px;
margin: auto;
}
.battery {
height: 220px;
box-sizing: border-box;
border-radius: 15px 15px 5px 5px;
filter: drop-shadow(0 1px 3px rgba(0,0,0,0.22));
background: #fff;
z-index: 1;
}
.battery::before {
content: "";
position: absolute;
width: 26px;
height: 10px;
left: 50%;
top: 0;
transform: translate(-50%, -10px);
border-radius: 5px 5px 0 0;
background: rgba(240, 240, 240, .88);
}
.battery::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 90%;
background: linear-gradient(to bottom, #7abcff 0%, #00BCD4 44%, #2196F3 100%);
border-radius: 0px 0px 5px 5px;
box-shadow: 0 14px 28px rgba(33, 150, 243, 0), 0 10px 10px rgba(9, 188, 215, 0.08);
animation: charging 6s linear infinite;
filter: hue-rotate(90deg);
}
@keyframes charging {
50% {
box-shadow: 0 14px 28px rgba(0, 150, 136, 0.83), 0px 4px 10px rgba(9, 188, 215, 0.4);
}
95% {
top: 5%;
filter: hue-rotate(0deg);
border-radius: 0 0 5px 5px;
box-shadow: 0 14px 28px rgba(4, 188, 213, .2), 0 10px 10px rgba(9, 188, 215, 0.08);
}
100% {
top: 0%;
filter: hue-rotate(0deg);
border-radius: 15px 15px 5px 5px;
box-shadow: 0 14px 28px rgba(4, 188, 213, 0), 0 10px 10px rgba(9, 188, 215, 0.4);
}
}
添加波浪效果
刚刚算一个小里程碑,接下来再进一步。电量的顶部为一条直线有点呆呆的感觉,这里我们进行改造一下,如果能将顶部直线,改为波浪滚动,效果会更为逼真一点。
改造之后的效果:
知识点
1.运用border-radius
如果一个正方形,给它添加 border-radius: 50%,将会得到一个圆形。
那么 border-radius 没到 50%,但是接近 50% ,我们会得到一个怎么样的图形呢?
那我们让这个图形滚动起来(rotate) 呢,如再加上背景颜色
让我们看看代码:
<div class="container">
<div class="header"></div>
<div class="battery">
</div>
<div class="battery-copy">
<div class="g-wave"></div>
<div class="g-wave"></div>
<div class="g-wave"></div>
</div>
</div>
html,
body {
width: 100%;
height: 100%;
display: flex;
background: #e4e4e4;
}
.container {
position: relative;
width: 140px;
margin: auto;
}
.header {
position: absolute;
width: 26px;
height: 10px;
left: 50%;
top: 0;
transform: translate(-50%, -10px);
border-radius: 5px 5px 0 0;
background: rgba(255, 255, 255, .88);
}
.battery-copy {
position: absolute;
top: 0;
left: 0;
height: 220px;
width: 140px;
border-radius: 15px 15px 5px 5px;
overflow: hidden;
}
.battery {
position: relative;
height: 220px;
box-sizing: border-box;
border-radius: 15px 15px 5px 5px;
box-shadow: 0 0 5px 2px rgba(255, 255, 255, 0.22);
background: #fff;
z-index: 1;
&::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 80%;
background: linear-gradient(to bottom, #7abcff 0%, #00BCD4 44%, #2196F3 100%);
border-radius: 0px 0px 5px 5px;
box-shadow: 0 14px 28px rgba(33, 150, 243, 0), 0 10px 10px rgba(9, 188, 215, 0.08);
animation: charging 10s linear infinite;
filter: hue-rotate(90deg);
}
}
.g-wave {
position: absolute;
width: 300px;
height: 300px;
background: rgba(255, 255, 255, .8);
border-radius: 45% 47% 44% 42%;
bottom: 25px;
left: 50%;
transform: translate(-50%, 0);
z-index: 1;
animation: move 10s linear infinite;
}
.g-wave:nth-child(2) {
border-radius: 38% 46% 43% 47%;
transform: translate(-50%, 0) rotate(-135deg);
}
.g-wave:nth-child(3) {
border-radius: 42% 46% 37% 40%;
transform: translate(-50%, 0) rotate(135deg);
}
@keyframes charging {
50% {
box-shadow: 0 14px 28px rgba(0, 150, 136, 0.83), 0px 4px 10px rgba(9, 188, 215, 0.4);
}
95% {
top: 5%;
filter: hue-rotate(0deg);
border-radius: 0 0 5px 5px;
box-shadow: 0 14px 28px rgba(4, 188, 213, .2), 0 10px 10px rgba(9, 188, 215, 0.08);
}
100% {
top: 0%;
filter: hue-rotate(0deg);
border-radius: 15px 15px 5px 5px;
box-shadow: 0 14px 28px rgba(4, 188, 213, 0), 0 10px 10px rgba(9, 188, 215, 0.4);
}
}
@keyframes move {
100% {
transform: translate(-50%, -160px) rotate(720deg);
}
}
当图片变成动画就是我们需要的效果了。
到这里,加上数字变化已经算是一个比较不错的效果了。当然上面的效果看上去还是很 CSS 的,就是一眼看到就觉得用 CSS 是可以做到的。
2.使用强大的 CSS 滤镜来实现安卓充电动画效果
如果你是用的安卓手机是不是很熟悉,ok 我们今天最终就是来盘它!
<div class="g-container">
<div class="g-number">98.7%</div>
<div class="g-contrast">
<div class="g-circle"></div>
<ul class="g-bubbles">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
html,
body {
width: 100%;
height: 100%;
display: flex;
background: #000;
overflow: hidden;
}
.g-number {
position: absolute;
width: 300px;
top: 27%;
text-align: center;
font-size: 32px;
z-index: 10;
color: #fff;
}
.g-container {
position: relative;
width: 300px;
height: 400px;
margin: auto;
}
.g-contrast {
filter: contrast(15) hue-rotate(0);
width: 300px;
height: 400px;
background-color: #000;
overflow: hidden;
animation: hueRotate 10s infinite linear;
}
.g-circle {
position: relative;
width: 300px;
height: 300px;
box-sizing: border-box;
filter: blur(8px);
}
.g-circle::after {
content: "";
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%) rotate(0);
width: 200px;
height: 200px;
background-color: #00ff6f;
border-radius: 42% 38% 62% 49% / 45%;
animation: rotate 10s infinite linear;
}
.g-circle::before {
content: "";
position: absolute;
width: 176px;
height: 176px;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
background-color: #000;
z-index: 10;
}
.g-bubbles {
position: absolute;
left: 50%;
bottom: 0;
width: 100px;
height: 40px;
transform: translate(-50%, 0);
border-radius: 100px 100px 0 0;
background-color: #00ff6f;
filter: blur(5px);
}
li {
position: absolute;
border-radius: 50%;
background: #00ff6f;
}
@for $i from 0 through 15 {
li:nth-child(#{$i}){
$width: 15 + random(15) + px;
left: 15 + random(70) + px;
top: 50%;
transform: translate(-50%, -50%);
width: $width;
height: $width;
animation: moveToTop #{random(6) + 3}s ease-in-out -#{random(5000)/1000}s infinite;
}
}
@keyframes rotate {
50% {
border-radius: 45% / 42% 38% 58% 49%;
}
100% {
transform: translate(-50%, -50%) rotate(720deg);
}
}
@keyframes moveToTop {
90% {
opacity: 1;
}
100% {
opacity: .1;
transform: translate(-50%, -180px);
}
}
@keyframes hueRotate {
100% {
filter: contrast(15) hue-rotate(360deg);
}
}
总结
其中最主要的其实是用到了 filter: contrast() 以及 filter: blur() 这两个滤镜,可以很好的实现这种融合效果。
单独将两个滤镜拿出来,它们的作用分别是:
filter: blur(): 给图像设置高斯模糊效果。
filter: contrast(): 调整图像的对比度。
再有就是这里用到的Scss for循环@for $i from 0 through 15
通过调节 filter: blur() 及 filter: contrast() 属性的值,动画效果其实会有很大程度的变化,好的效果需要不断的调试。当然,经验在其中也是发挥了很重要的作用,说到底还是要多尝试。