2025-01-25 前端水波进度实现

使用 CSS 动画和 JavaScript 动态控制波浪形状,通过 clip-path 裁剪出波浪效果,结合进度计算实现水位上升动画。

HTML 结构

<div class="container">
  <div class="wave-container">
    <div class="wave wave1"></div>
    <div class="wave wave2"></div>
  </div>
  <div class="progress-text">0%</div>
</div>

CSS 样式

.container {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: #e0e0e0;
  position: relative;
  overflow: hidden;
}

.wave-container {
  position: absolute;
  width: 200%;
  height: 200%;
  left: -50%;
  top: 30%; /* 初始水位 */
  animation: wave-up 3s linear infinite;
}

.wave {
  position: absolute;
  width: 100%;
  height: 100%;
  background: #2196f3;
  opacity: 0.8;
}

.wave1 {
  animation: wave-animation 4s infinite linear;
  clip-path: polygon(
    0% 60%, 
    10% 65%, 
    20% 60%, 
    30% 55%, 
    40% 50%, 
    50% 55%, 
    60% 60%, 
    70% 65%, 
    80% 60%, 
    90% 55%, 
    100% 50%, 
    100% 100%, 
    0% 100%
  );
}

.wave2 {
  animation: wave-animation 6s infinite linear;
  clip-path: polygon(
    0% 50%, 
    10% 55%, 
    20% 60%, 
    30% 65%, 
    40% 60%, 
    50% 55%, 
    60% 50%, 
    70% 45%, 
    80% 50%, 
    90% 55%, 
    100% 60%, 
    100% 100%, 
    0% 100%
  );
  opacity: 0.5;
}

@keyframes wave-animation {
  0% { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

@keyframes wave-up {
  to { top: -70%; } /* 根据进度调整 */
}

.progress-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 24px;
  color: #333;
}

JavaScript 控制

function setProgress(percent) {
  const container = document.querySelector('.wave-container');
  const text = document.querySelector('.progress-text');
  
  // 计算水位高度 (100%对应top:-70%)
  const waterLevel = 30 - percent * 1; // 初始30%对应0%
  container.style.top = waterLevel + '%';
  
  // 重置动画保证流畅
  container.style.animation = 'none';
  void container.offsetWidth; // 触发重绘
  container.style.animation = `wave-up ${3 + percent/20}s linear forwards`;
  
  text.textContent = `${percent}%`;
}

// 示例:3秒内进度从0%到75%
let progress = 0;
const timer = setInterval(() => {
  progress += 1;
  setProgress(progress);
  if(progress >= 75) clearInterval(timer);
}, 30);

增强功能建议

  1. 颜色渐变:使用 background: linear-gradient() 实现水面颜色渐变
  2. 3D效果:添加 box-shadow 和旋转动画模拟光照
  3. 响应式:通过 CSS 变量控制尺寸
  4. 触摸支持:添加事件监听实现拖动调节

实现效果

  • 双波浪层交错运动
  • 平滑的水位上升动画
  • 动态百分比显示
  • 波浪形变模拟真实液体效果

这个方案结合了 CSS 动画的性能优势和 JavaScript 的动态控制能力,通过分层设计实现了逼真的水波效果。实际使用时可以根据需求调整波浪形状、动画速度和颜色参数。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容