当前位置: 首页 > Web前端 > CSS

css3实现圆形进度条

时间:2023-03-30 17:02:57 CSS

在开发微信小程序的时候遇到了圆形进度条的需求。用canvas绘图比较麻烦:1、为了实现不同屏幕的适配,必须动态计算进度条的大小;2.在小程序中,canvas的画布级别最高,不易扩展。但是使用css3和js来实现进度条可以很轻松的避免这个问题。注:本文使用jquery实现,但原理是一样的。您只需要在小程序中定义和更改相应的变量即可。1.进度条的样式在平时的开发中,经常会用到元素的边框来显示圆形的Circular图案,在使用css3实现圆形进度条的时候也会用到这个技巧。为了实现上圆形边框和动态覆盖下圆形边框,一共需要一个圆,两个矩形,两个半圆:一个圆用于显示底层背景,两个半圆用于覆盖底层背景显示进度,另外两个矩形用于覆盖不需要显示的进度。如下图:最下面的圆圈是进度条的背景,底部左右有两个矩形,用来遮住不显示的进度条。两个矩形内各有一个半圆表示进度。一般情况下,用正方形画出的半圆,其直径与水平面的夹角为45度。为了让两个半圆刚好覆盖整个圆,需要使用css3中的rotate对原来的正方形进行旋转,达到覆盖整个背景的效果。如下图(为了表达清楚,这里用正方形表示):如图,将矩形内的半圆向右(顺时针)旋转45度,可以得到一张图片进度覆盖整个背景。将半圆向左(逆时针)旋转135度以获得仅包含进度条背景的图像。为什么一直向左旋转而不是一直向右旋转,当然是因为要达到的效果是:进度从最上面开始,顺时针结束。至此,思路就很清晰了。只需要通过百分比来控制左右进度显示即可。实际这部分的html和css代码如下:html代码

css代码:.progressbar{position:relative;边距:100px自动;宽度:100px;高度:100px;边框:20px实心#ccc;border-radius:50%;}.left-container,.right-container{position:absolute;宽度:70px;高度:140px;顶部:-20px;溢出:隐藏;z-index:1;}.left-container{left:-20px;}.right-container{right:-20px;}.left-circle,.right-circle{position:absolute;顶部:0;宽度:100px;高度:100px;边框:20px实心透明;边界半径:50%;变换:旋转(-135deg);过渡:所有.5s线性;z-index:2;}.??left-circle{left:0;边框顶部颜色:20px纯蓝色;左边框颜色:20pxsolidblue;}.right-circle{border-right-color:20pxsolidblue;border-bottom-color:20px纯蓝色;right:0;}二:控制进度条的js让进度条的逻辑更加健壮,js部分的实现需要考虑四种情况:1.基础值和变化值在同一个上progressontheright,2.基本值在右边,变化值在左边。3.基础值变化后的值在同一个Left,4.基础值在左边,变化后的值在右边。不管怎样,核心只需要考虑两点:角度的变化和使用时间。第一种情况比较简单,可以很容易计算出角度的变化和使用时间。首先,您需要设置改变整个半圆所需时间的值。设置完成后,只需根据比例计算出改变角度所需的时间值即可。代码如下:time=(curPercent-oldPercent)/50*baseTime;//判断时间值为正curPercent-oldPercent>0?'':时间=-时间;deg=curPercent/50*180-135;第二种情况,麻烦一点。因为中间有一个从右进度到左进度的过渡。为了让进度变化顺利,这里我们需要用到一个定时器。更改右侧部分后,修改左侧部分。代码如下://设置右边的进度time=(50-oldPercent)/50*baseTime;deg=(50-oldPercent)/50*180-135;$rightBar.css({transform:'rotate('+deg+'deg)',transition:'all'+time+'slinear'})//延迟设置左边进度条的变化setTimeout(function(){time=(curPercent-50)/50;deg=(curPercent-50)/50*180-135;$leftBar.css({transform:'rotate('+deg+'deg)',transition:'all'+time+'slinear'})},Math.floor(时间*1000));000));第三种情况和第四种情况与前面的情况类似,这里不再赘述。控制进度条的完整函数代码如下(使用jQuery实现):/***设置进度条的变化*@param{number}oldPercent进度条变化前的半点比例*@param{number}curPercent当前进度条设置值*@return{boolean}设置成功则返回true,否则返回fasle*/functionsetProgessbar(oldPercent,curPercent){var$leftBar=$('#left-酒吧');var$rightBar=$('#右栏');//将传入的参数转换为允许字符串表示的数字oldPercent=+oldPercent;当前百分比=+当前百分比;//检查参数,如果不是数字类型或者不在0-100之间,则不执行if(typeofoldPercent==='number'&&typeofcurPercent==='number'&&oldPercent>=0&&oldPercent<=100&&curPercent<=100&&curPercent>=0){varbaseTime=1;//默认改变半圆进度的时间,以秒为单位vartime=0;//进度条变化的时间vardeg=0;//进度条角度变化if(oldPercent>50){//原来的进度大于50if(curPercent>50){//设置进度在左边time=(curPercent-oldPercent)/50*baseTime;//判断时间值为正curPercent-oldPercent>0?'':时间=-时间;deg=curPercent/50*180-135;$leftBar.css({transform:'rotate('+deg+'deg)',transition:'all'+time+'slinear'})}else{//设置左进度时间=(oldPercent-50)/50*基准时间;deg=(oldPercent-50)/50*180-135;$leftBar.css({transform:'rotate('+deg+'deg)',transition:'all'+time+'slinear'})//延迟设置右边进度条的变化setTimeout(function(){time=(50-curPercent)/50;deg=(50-curPercent)/50*180-135;$rightBar.css({transform:'rotate('+deg+'deg)',transition:'all'+time+'slinear'})},Math.floor(time*1000));}}else{//当原来的进度小于50时if(curPercent>50){//设置进度在合适的时间=(50-oldPercent)/50*baseTime;deg=(50-oldPercent)/50*180-135;$rightBar.css({transform:'rotate('+deg+'deg)',transition:'all'+time+'slinear'})//延迟设置左侧进度条的变化setTimeout(function(){time=(curPercent-50)/50;deg=(curPercent-50)/50*180-135;$leftBar.css({transform:'rotate('+deg+'deg)',transition:'all'+time+'线性'})},Math.floor(time*1000));}else{//设置进度在右边time=(curPercent-oldPercent)/50*baseTime;//确保时间值为正curPercent-oldPercent>0?'':时间=-时间;deg=curPercent/50*180-135;$rightBar.css({transform:'rotate('+deg+'deg)',transition:'all'+time+'slinear'})}returntrue;}}else{返回错误;}}写在最后:新开的公众号:海恨笔记,微信公众号:haihenbiji,二维码如下,欢迎搜号,或扫码关注,共同成长