重构-线性进度条

动画:
	传递颜色数组后,颜色过渡
	宽度改变有0.6s过渡

参数:
  percentage: PropTypes.number,		进度数值,0-100
  onSuccess: PropTypes.func,		当加载到100%时,触发回调,第一个参数是状态
  colors: PropTypes.array,			颜色数组,会根据传递的颜色,在不同进度现实不同颜色,默认为蓝色		
  suffix: PropTypes.bool,			后置图标,在整个轨道后出现,未实现逻辑,仅是展现,需自定义设置
  show: PropTypes.bool,			    是否在进度条尾部现实数字
  width: PropTypes.string,			进度条长度
  height: PropTypes.string,			进度条高度
  borderRadius: PropTypes.string,   进度条圆角
  fontSize: PropTypes.string,		数字和图标字体大小
  outerColor: PropTypes.string,	    轨道颜色
  innerColor: PropTypes.string,     进度颜色
  percentColor: PropTypes.string,	数字颜色

效果图:
在这里插入图片描述
在这里插入图片描述
代码示例:
使用:

import React,{useState,useRef,useEffect,useCallback} from 'react'
import Progress from './progress/progress'

function App(){
  let [value,setValue] =useState(0);
  const valf = useRef(null);
  valf.current = value;


  const _onClick = function ()
  {
      setInterval(() => {
    
            setValue(v=>v+1);      
      },1000)

  }

  
  
  
  const _onSuccess = function (state)
  {
    console.log(state);
  }


  return(

    <div>
      <Progress colors={['#aaa', 'brown', 'blue', 'green']} percentage={value} onSuccess={_onSuccess} show ></Progress>
      <br />
      <br/>
      <button onClick={_onClick}>开始</button>

    </div>
  )
}

export default App

progress.jsx:

import React,{useState,useEffect,useCallback,useRef,useMemo} from 'react'
import PropTypes from 'prop-types'
import './progress.css'

function App(props){

  const progressf = useRef(null);
  const innerf = useRef(null);

  // 初始样式设置
  useEffect(() => {
    _styleHandler('width', props.width);
    _styleHandler('height', props.height);
    _styleHandler('borderRadius', props.borderRadius);
    _styleHandler('fontSize', props.fontSize);
    _styleHandler('outerColor', props.outerColor);
    _styleHandler('innerColor', props.innerColor);
    _styleHandler('percentColor', props.percentColor);
  },[])

  // 进度改变过程设置
  useEffect(() => {
    innerf.current.style.width = _percentHandler + '%';

    props.percentage === 100 && props.onSuccess(true);
    props.suffix && _situationHandler();
    
    if(props.colors.length)
    {
      let index = Math.floor(100 / props.colors.length);
      _percentColorHandler(_percentHandler, index);
    }

  },[props.percentage])

  //统一处理初始化样式
  const _styleHandler = useCallback((key, value) => {
    props[key] && progressf.current.style.setProperty('--' + key, value)
    
  },[])

  //计算属性返回当前数值
  const _percentHandler =useMemo(function ()
  {
    return Math.floor(Math.max(0,Math.min(100,props.percentage)))
  },[props.percentage])

  //如果传入数组的颜色变化
  const _percentColorHandler =useCallback(function(num,index)
  {
    
    let _index = Math.floor(num / index);
    (_index == props.colors.length) &&( _index = props.colors.length - 1);
    
    innerf.current.style.backgroundColor=props.colors[_index]
  },[])


  //当有后置图标时,根据进度清空,对图标的处理函数
  const _situationHandler = useCallback(() => {
    // console.log(_percentHandler);

  },[_percentHandler])

  return(

    <div className='jf-progress-container' ref={progressf}>
      <div className='jf-progress-outer'>
        <div className='jf-progress-inner' ref={innerf}>{props.show && <div className='jf-progress-num'>{_percentHandler}%</div>}</div>
      </div>
      {props.suffix && <span className='jf-progress-suffix'></span>}
    </div>
  )
}

App.propTypes = {
  percentage: PropTypes.number,
  onSuccess: PropTypes.func,
  colors: PropTypes.array,
  suffix: PropTypes.bool,
  show: PropTypes.bool,
  width: PropTypes.string,
  height: PropTypes.string,
  borderRadius: PropTypes.string,
  fontSize: PropTypes.string,
  outerColor: PropTypes.string,
  innerColor: PropTypes.string,
  percentColor: PropTypes.string,
}

App.defaultProps = {
  percentage: 0,
  onSuccess: () => { },
  colors:[]
}

export default React.memo(App);

progress.css:

.jf-progress-container {
  display: inline-block;
  box-sizing: border-box;
  width: var(--width);
  height: var(--height);
  position: relative;
  vertical-align: middle;

  --width: 400px;
  --height: 20px;
  --borderRadius: 20px;
  --outerColor: #ebeef5;
  --innerColor: #409eff;
  --innerWidth: px;
  --percentColor: white;
  --fontSize: 12px;
}

.jf-progress-outer {
  width: 100%;
  height: 100%;
  position: relative;
  background-color: var(--outerColor);
  border-radius: var(--borderRadius);
  overflow: hidden;
  vertical-align: middle;
  /* display: flex; */
}

.jf-progress-inner {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  background-color: var(--innerColor);
  border-radius: var(--borderRadius);
  text-align: right;

  line-height: var(--height);
  font-size: 0;
  transition: width 0.6s ease, background-color 1s;
}

.jf-progress-num {
  display: inline-block;
  vertical-align: middle;
  font-size: var(--fontSize);
  color: var(--percentColor);
}
.jf-progress-suffix {
  position: absolute;
  top: 0;
  right: 0;
  font-size: var(--fontSize);
  line-height: var(--height);
  transform: translateX(120%);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值