Vue环形进度条

  • 环形进度条可设置背景颜色,遮罩层,文字,百分值默认保存两位小数
  • sizeOut:底圈半径 Number 默认值:100
  • sizeIn里圈半径 Number 默认值:80
  • size进度条大小 Number 默认值:10 注意:需要满足sizeOut>sizeIn+size
  • colorBg背景色 String 默认值:#fff 支持rgb\rgba\十六进制(3位或者6位)\hsl\hsla
  • colorTop进度条颜色 String 默认值:#0f0 支持rgb\rgba\十六进制(3位或者6位)\hsl\hsla
  • colorBottom进度条打底色 String 默认值:#ccc 支持rgb\rgba\十六进制(3位或者6位)\hsl\hsla
  • target进度的百分比 Number默认值:0
  • total:总数 Number默认值100
  • index:当前完成的个数 默认值0 注意:如果选择target会优先使用target,如果没有传入target可以采用total配合index的方式,由本组建进行计算
  • text:显示文本 String 默认值:进行中
  • textSize文本大小 Number 默认值:20
  • textcolor文本颜色 String 默认值:#f50 支持rgb\rgba\十六进制(3位或者6位)\hsl\hsla
  • percentageSize:百分比文字颜色 String默认值#ff6321 支持rgb\rgba\十六进制(3位或者6位)\hsl\hsla
  • percentageSize:百分数文字大小 Number 默认值 30
  • encumbrances:百分值保留多少位小数 Number 默认值 2
  • hasMask:是否有遮罩层 Boolean 默认值false
<template>
    <div :class="hasMask?'hasmask':''">
        <svg ref="svg" :class="['yh-progress-box',hasMask?'hasmask':'']" :style="{height:sizeOut*2+'px',width:sizeOut*2+'px',backgroundColor:colorBg}">
            <circle cx="75" cy="75" :r="sizeIn" fill="transparent" :stroke="colorBottom" :stroke-width="size" :stroke-dasharray="2*sizeIn*3.14"
                stroke-dashoffset="0" class="yh-progress-bottom" :style="{transformOrigin:`${sizeOut}px 75px`,width:sizeIn*2+'px',height:sizeIn*2+'px'}"></circle>
            <circle cx="75" cy="75" :r="sizeIn" fill="transparent" :stroke="colorTop" :stroke-width="size" :stroke-dasharray="2*sizeIn*3.14"
                :stroke-dashoffset="show" class="yh-progress-top" :style="{transformOrigin:`${sizeOut}px 75px`,width:sizeIn*2+'px',height:sizeIn*2+'px'}" >
            </circle>
            <text :x="sizeOut" :y="sizeOut" text-anchor="middle" :fill="percentageColor" :font-size="percentageSize" font-weight="600">
                {{percentage}}%
            </text>
            <text :x="sizeOut" :y="sizeOut+percentageSize" text-anchor="middle" :font-size="textSize" :fill="textcolor">
                {{text}}
            </text>
        </svg>
    </div>
</template>

<script>

 function CheckIsColor(bgVal) {
      let type='';
      if(/^rgb\(/.test(bgVal)){
          //如果是rgb开头,200-249,250-255,0-199
         type = "^[rR][gG][Bb][\(]([\\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\\s]*,){2}[\\s]*(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)[\\s]*[\)]{1}$";
      }else if(/^rgba\(/.test(bgVal)){
          //如果是rgba开头,判断0-255:200-249,250-255,0-199 判断0-1:0 1 1.0 0.0-0.9
         type = "^[rR][gG][Bb][Aa][\(]([\\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\\s]*,){3}[\\s]*(1|1.0|0|0.[0-9])[\\s]*[\)]{1}$";
      }else if(/^#/.test(bgVal)){
          //六位或者三位
         type = "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$"
      }else if(/^hsl\(/.test(bgVal)){
          //判断0-360 判断0-100%(0可以没有百分号)
         type = "^[hH][Ss][Ll][\(]([\\s]*(2[0-9][0-9]|360|3[0-5][0-9]|[01]?[0-9][0-9]?)[\\s]*,)([\\s]*((100|[0-9][0-9]?)%|0)[\\s]*,)([\\s]*((100|[0-9][0-9]?)%|0)[\\s]*)[\)]$";
      }else if(/^hsla\(/.test(bgVal)){
          type = "^[hH][Ss][Ll][Aa][\(]([\\s]*(2[0-9][0-9]|360|3[0-5][0-9]|[01]?[0-9][0-9]?)[\\s]*,)([\\s]*((100|[0-9][0-9]?)%|0)[\\s]*,){2}([\\s]*(1|1.0|0|0.[0-9])[\\s]*)[\)]$";
      }
      let re = new RegExp(type);
      if (bgVal.match(re) == null){
         return false
      }else{
         return true
     }
    }
export default {
    name:'progressBar',
    props:{
        sizeOut:{
            type:Number,
            default:100
        },
        sizeIn:{
            type:Number,
            default:80,
        },
        size:{
            type:Number,
            default:10
        },
        colorBg:{
            type:String,
            default:'#fff',
            validator:function(value){
                CheckIsColor(value)
            }
        },
        colorTop:{
            type:String,
            default:'#0f0',
            validator:function(value){
                CheckIsColor(value)
            }
        },
        colorBottom:{
            type:String,
            default:'#ccc',
             validator:function(value){
                CheckIsColor(value)
            }
        },
        target:{
            type:Number,
            default:0
        },
        total:{
            type:Number,
            default:100
        },
        index:{
            type:Number,
            default:0
        },
        text:{
            type:String,
            default:'进行中'
        },
        textSize:{
            type:Number,
            default:20
        },
        textcolor:{
            type:String,
            default:'#f50',
            validator:function(value){
                CheckIsColor(value)
            }
        },
        percentageSize:{
            type:Number,
            default:30,
        },
        percentageColor:{
            type:String,
            default:'#ff6321',
            validator:function(value){
                CheckIsColor(value)
            }
        },
        hasMask:{
            type:Boolean,
            default:false
        },
        encumbrances:{
            type:Number,
            default:2
        }
    },
    computed:{
        show: function(){
            if(this.target){
                return ((100-this.target)*2*this.sizeIn*3.14/100).toFixed(this.encumbrances)
            }else{
                return ((1-this.index/this.total)*2*this.sizeIn*3.14).toFixed(this.encumbrances)
            }
        },
        percentage: function(){
            if(this.target){
                return this.target.toFixed(this.encumbrances)
            }else{
               return ((this.index/this.total)*100).toFixed(this.encumbrances)
            }
        }
    },
}
</script>


<style lang="less">
.yh-progress-box{
    position: relative;
    border-radius: 50%;
    .yh-progress-bottom,.yh-progress-top{
        position: absolute;
        z-index: inherit;
        transform: rotate(-90deg);
    }
}
.hasmask{
    width: 100%;
    height: 100%;
    background-color:rgba(0, 0, 0, 0.3);
    position: fixed;
    top: 0;
    left: 0;
    .yh-progress-box{
        top: 50%;
        left:50%;
        transform: translate(-50%,-50%);
    }
}
</style>

测试用例

<template>
    <progress-bar :sizeOut="100" :index="20" :total="100" />
</template>
<script>
import progressBar from '@/components/progress-bar'
export default {
  components:{
    progressBar
  }
}
</script>

Vue环形进度条_第1张图片

你可能感兴趣的:(vue,js,html,css)