来嘛来嘛~在React中感受动态水波进度条的美妙~

前言

好久好久没有更文,也好久没有通过文章来讲述近况了。今天有点空余时间,不想吹牛皮就想着来写一篇文章,毕竟闲下来还是要多总结总结,这样才能稳步前进呀。

这次要聊的是前段时间经历的一个需求,美术设计了一个水滴进度条效果,下面就来看看如何实现一个类似水滴的进度条效果的。gogogo→

背景

这次的需求就是在小程序上实现一个进度条效果,如下:

这里给的设计图倒是看不到进度条内水荡来荡去的效果,需求就是这么一个需求,鉴于该效果是在小程序中使用的vue3技术栈进行开发的,下面会使用react将代码翻译后在PC端作为组件来实现,至于需要vue3实现代码的请评论区留言。

开发

首先就在项目中创建一个WaterProgress.tsx文件,具体代码如下:

typescript 复制代码
import React from 'react';
import './index.less'

interface Iprops {
  percentNumber: number;
}

const WaterProgress = (props:  Iprops) => {
  const { percentNumber=40 } = props;

  return (
      <div className="progress-box">
        <div className='percent-number-inner'>{ percentNumber }%</div>
        <div className="wave-progress">
          <div className="wave"></div>
          <div className="wave-mask" style={{top: percentNumber === 100 ? '-30%' : `${100 - percentNumber}%`}}></div>
        </div>
      </div>
  )
}

export default WaterProgress

这个就是最简单的代码,该组件只需要外部调用时传入一个percentNumber表示进度百分比即可。

接着创建一个index.less文件。具体代码,如下:

css 复制代码
.progress-box{
  position: relative;
  .percent-number-outer {
    color: #000;
    display: flex;
    justify-content: center;
  }

  @keyframes spin {

    50% {
      transform: translate(-50%, -100%) rotate(180deg);
    }
    100% {
      transform: translate(-50%, -100%) rotate(360deg);
    }
  }

  .wave-progress {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: #ffffff;
    overflow: hidden;
    position: relative;
    border: 8px solid #C280FF;
    box-sizing: border-box;

    .wave {
      position: relative;
      width: 100%;
      height: 100%;
      background-image: linear-gradient(-180deg, #E6CCFF 13%, #E6CCFF 100%);
      border-radius: 50%;
    }

    .wave-mask {
      position: absolute;
      width: 200%;
      height: 200%;
      top: 0;
      left: 50%;
      border-radius: 42%;
      transform: translate(-50%, -100%) rotate(0);
      animation: spin 16s linear infinite;
      z-index: 20;
      background-color: #FFFFFF;
    }
  }
}

上述代码就没有啥详细展开的了,主要的就是在外层增加了一个一直运动的节点来模拟水在盒子荡来荡去的效果,其实这也是该组件最核心的地方,其他都是小问题。来看看效果,如下所示:

到这里这个水滴进度条组件就可以使用了,但是作为组件,内部的一些属性可能在不同的场景想要不同的效果,所以下面就来把该组件丰富一下,使其更加灵活。

首先为该组件设置需要改变的一些属性类型,如下:

typescript 复制代码
interface Iprops {
  percentNumber: number; // 必传,进度百分比
  numPlace?: boolean; // 可传,进度数字在内部还是外部
  color?: string; // 可传,数字颜色
  borderColor?: string; // 可传,进度边框颜色
  bgColor?: string; // 可传,水波颜色
}

接着在代码中做如下修改,如下:

ini 复制代码
const WaterProgress = (props:  Iprops) => {
  const { percentNumber, numPlace=true, color, borderColor, bgColor='#E6CCFF' } = props;

  return (
      <div className="progress-box">
        <div className={numPlace ? 'percent-number-inner' : 'percent-number-outer'} style={{color}}>{ percentNumber }%</div>
        <div className="wave-progress" style={{borderColor}}>
          <div className="wave" style={{'--bgColor': `${bgColor}`}}></div>
          <div className="wave-mask" style={{top: percentNumber === 100 ? '-30%' : `${100 - percentNumber}%`}}></div>
        </div>
      </div>
  )
}

可以看到代码为上面的某些属性值设置了默认值,然后就根据外部调用传入的值进行判断使用对应的样式即可。其中需要提出来说的就只有style={{'--bgColor': ${bgColor}}},这里需要去改变水波的颜色,水波的颜色是渐变的,如果在内联样式中写就会导致代码很长,所以这里就使用了在内联样式中声明一个变量,然后再样式文件中使用该变量即可。

样式文件也做对应的修改,如下:

到这里就把该组件扩展完了,下面就看看在项目中调用时改变属性值看看效果。如下:

ini 复制代码
<WaterProgress percentNumber={85} color={'red'} borderColor={'#50c127'} bgColor={'#b0ecbd'} />

至此,实现一个水波荡漾的进度条就搞定了,如果需要拿到小程序中使用,就只需要把CSS中的像素单位换为rpx即可。最后,希望看完本文你也能搞定这个需求,栓Q~

后语

小伙伴们,如果觉得本文对你有些许帮助,点个👍或者➕个关注再走吧^_^ 。另外如果本文章有问题或有不理解的部分,欢迎大家在评论区评论指出,我们一起讨论共勉。

相关推荐
szarron3 分钟前
国产手持式频谱分析仪选型攻略:TFN RC系列 vs HTOOL SA8T频谱分析仪 专业参数对比(军工/路测/调试全覆盖)
开发语言·前端·状态模式
Beyond_System|系统之外7 分钟前
一个网页如何同时适配投影仪、1366×768 和 1920×1080?我重新理解了“自适应布局”
开发语言·css·html
开开心心就好11 分钟前
免费桌签打印工具,支持批量导入名字
前端·javascript·人工智能·docker·jupyter·智能手机·语音识别
涛涛ing12 分钟前
2026 年 9 月,整个 npm 生态的「心脏」都被 Rust 换了
前端
IT_陈寒16 分钟前
明明设了默认值,为什么我的JavaScript函数参数还是undefined?
前端·人工智能·后端
CappuccinoRose17 分钟前
Web Components 基础
前端·javascript·交互·web component·shadow dom
晴天1619 分钟前
前端 Monorepo 入门分享:从概念到实践
前端
lytao12334 分钟前
90% 覆盖率不等于没 Bug:用风险配置测试组合
前端·javascript·bug·软件工程
Claire_8838 分钟前
从零搭建网页:我用AI生成HTML/CSS/JS的实践与工具整理
css·人工智能·html
mayaairi38 分钟前
Vue2 组件通讯(一):Props传值完全指南
前端·javascript·vue.js