CSS 实现电池充电动画
最近在学习 css,写了一个电池充电动画的实现效果,电量颜色会随着百分比变化,充电时显示类似水波的效果。今天就来分享一下这个项目的实现过程。
整体思路
这个电池组件的核心功能有以下几个:
- 电池外观:一个简单的矩形(顶部凸起懒得搞了,主要看充电动画效果)。
- 波浪效果:用 CSS 动画模拟波浪填充电池的效果。
- 电量控制:用滑块调节电量,动态更新波浪的高度和颜色。
- 颜色变化:电量高时为绿色,中等为黄色,低时为红色。
效果图
关键点解析
1. 波浪动画
波浪效果是通过 CSS 动画实现的。我定义了一个 @keyframes
,让 div
旋转 360 度,形成波浪的视觉效果。
// 波浪进度条样式
.wave-progress {
width: 200px;
height: 200px;
border-radius: 45%;
position: absolute;
left: -50%;
// 波浪动画
animation: wave 5s linear infinite;
}
@keyframes wave {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
2. 电量控制和颜色变化
通过 batteryProgress
变量和 el-slider
组件,实现了电量的动态调节。getStyle
计算属性会根据电量百分比动态更新波浪的高度和颜色。然后当电量为 0 或 100 的时候暂停动画,圆角设置为 0,然后将旋转位置重置为 0。
// 计算波浪进度条的样式
const getStyle = computed(() => {
// 根据电量设置不同的颜色
const color = batteryProgress.value > 80 ? '#67C23A' : batteryProgress.value > 50 ? '#E6A23C' : '#F56C6C';
// 定义样式对象
const style = {
background: color,
top: 100 - batteryProgress.value + '%'
}
// 当电量为0或100时,暂停动画并调整样式
if ([0, 100].includes(batteryProgress.value)) {
style.animationPlayState = 'paused';
style.borderRadius = '0';
style.transform = 'rotate(0deg) !important';
}
return style;
})
完整代码
<template>
<!-- 整体布局容器 -->
<el-row class="body">
<div class="container">
<!-- 电池模拟容器 -->
<div class="battery">
<!-- 电池顶部左侧 -->
<div class="top top-left"></div>
<!-- 电池顶部右侧 -->
<div class="top top-right"></div>
<!-- 波浪进度条 -->
<div :style="getStyle" class="wave-progress"></div>
</div>
</div>
<!-- 滑块控制区域 -->
<div class="slider-demo-block">
<!-- 显示当前电量百分比 -->
<span class="demonstration">电量:{{ batteryProgress }}%</span>
<!-- 电量调节滑块 -->
<el-slider v-model="batteryProgress"/>
</div>
</el-row>
</template>
<script setup>
// 电池进度
import {computed, ref} from "vue";
// 定义电池进度的响应式变量
const batteryProgress = ref(100);
// 计算波浪进度条的样式
const getStyle = computed(() => {
// 根据电量设置不同的颜色
const color = batteryProgress.value > 80 ? '#67C23A' : batteryProgress.value > 50 ? '#E6A23C' : '#F56C6C';
// 定义样式对象
const style = {
background: color,
top: 100 - batteryProgress.value + '%'
}
// 当电量为0或100时,暂停动画并调整样式
if ([0, 100].includes(batteryProgress.value)) {
style.animationPlayState = 'paused';
style.borderRadius = '0';
style.transform = 'rotate(0deg) !important';
}
return style;
})
</script>
<style lang="scss" scoped>
// 整体页面样式
.body {
height: 100vh;
width: 100%;
background: rgba(255, 103, 0, 0.51);
display: flex;
flex-direction: column;
align-content: center;
justify-content: center;
}
// 电池样式
.battery {
width: 100px;
height: 150px;
background: white;
overflow: hidden;
position: relative;
// 波浪进度条样式
.wave-progress {
width: 200px;
height: 200px;
border-radius: 45%;
position: absolute;
left: -50%;
// 波浪动画
animation: wave 5s linear infinite;
}
}
// 波浪动画关键帧
@keyframes wave {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
// 滑块控制区域样式
.slider-demo-block {
width: 100px;
}
</style>
评论区