博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CSS3+JS实现静态圆形进度条【清晰、易懂】
阅读量:6589 次
发布时间:2019-06-24

本文共 4745 字,大约阅读时间需要 15 分钟。

在写这篇文章之前,笔者查看了多篇博客,无奈前辈大多只是贴了代码,没有清晰明了的注释,所以容易让新人看得云里雾里。这里,笔者在弄明白原理后,对代码进行了优化,决定写(总结)一篇清晰、明了的圆形进度条的实现,以便后人能快速搞懂。

一、实现原理

首先,我们来一个(黑色)。

接着,再来两个半圆,将黑色的圆遮住。(为了演示,左右两侧颜色不一样)
这时候,我们顺时针旋转右侧蓝色的半圆,下面的黑色圆就会暴露出来,比如我们旋转45度(12.5%),效果出来了。
如果我们将蓝色的右半圆同样设置成灰色,看效果,一个12.5%的饼图就出来了!

clipboard.pngclipboard.pngclipboard.pngclipboard.png

OK,我们再旋转更大的度数试试,比如40%(144度),50%(180度),60%(216度)如下图。

我们发现,旋转180度之后右半圆与左半圆重合了,如果再旋转,就会在右上角冒出来,显然不是我们想要的。

clipboard.pngclipboard.pngclipboard.png

我们希望的是,继续旋转被黑色遮住。。。嗯。。。怎么做呢?

我们将右侧的圆回归原位,把它刷成黑色(和底色一样),然后旋转左边的半圆(它在右侧半圆的更底层),这样,它就会被右侧半圆遮住了。好的,废话不多说,我们将左侧的半圆顺时针旋转45度,效果出来了。可以想象,继续旋转,180度的时候,就完全被右侧半圆遮住,而左侧底色全部暴露,这样100%显示出来了。

clipboard.pngclipboard.png

clipboard.png

最后,加上一个白色的小圆,放在正中间就行了。

好的,到这里,我们已经明白如何实现的了。

二、代码实现

html部分

60%

css部分

/*支持IE9及以上*/    .circle-bar { font-size:200px; width: 1em; height: 1em; position: relative;  background-color: #333; }    .circle-bar-left,.circle-bar-right { width: 1em; height: 1em; background-color: #eee; }    /*        这里采用clip剪切了圆,实现左右两个半圆,右半圆在后面,因此在更上一层,        clip的用法参考:http://www.w3school.com.cn/cssref/pr_pos_clip.asp     */    .circle-bar-right { clip:rect(0,auto,auto,.5em); }    .circle-bar-left { clip:rect(0,.5em,auto,0); }        .mask { width: 0.8em; height: 0.8em;  background-color: #fff;text-align: center;line-height: 0.2em; color:rgba(0,0,0,0.5); }    .mask :first-child { font-size: 0.3em; height: 0.8em; line-height: 0.8em; display: block;  }    /*所有的后代都水平垂直居中,这样就是同心圆了*/    .circle-bar * {  position: absolute; top:0; right:0; bottom:0; left:0; margin:auto; }    /*自身以及子元素都是圆*/    .circle-bar, .circle-bar > * { border-radius: 50%; }

JavaScript实现

//反正CSS3中的border-radius属性IE8是不支持了,所以这里就用新方法吧getElementsByClassName()走起    window.onload = function(){        var circleBar    = document.getElementsByClassName('circle-bar')[0];        var percent      = parseInt(circleBar.getElementsByClassName('percent')[0].firstChild.nodeValue);        var color        = circleBar.css('background-color');        var left_circle  = circleBar.getElementsByClassName('circle-bar-left')[0];        var right_circle = circleBar.getElementsByClassName('circle-bar-right')[0];        if( percent <= 50 ) {            var rotate = 'rotate('+(percent*3.6)+'deg)';            right_circle.css3('transform',rotate);        }else {            var rotate = 'rotate('+((percent-50)*3.6)+'deg)';            right_circle.css ('background-color',color);//背景色设置为进度条的颜色            right_circle.css3('transform','rotate(0deg)');//右侧不旋转            left_circle.css3 ('transform',rotate);//左侧旋转        }    }    //封装了css3函数,主要是懒得重复书写代码,既然写了css3函数,顺便写个css吧,统一样式,好看一些    Element.prototype.css = function(property,value){                if ( value ) {            //CSS中像background-color这样的属性,‘-’在JavaScript中不兼容,需要设置成驼峰格式            var index = property.indexOf('-');            if( index != -1 ) {                var char = property.charAt(index+1).toUpperCase();                property.replace(/(-*){1}/,char);            }            this.style[property] = value;        }else{            //getPropertyValue()方法参数类似background-color写法,所以不要转驼峰格式            return window.getComputedStyle(this).getPropertyValue(property);        }    }    //封装一个css3函数,用来快速设置css3属性    Element.prototype.css3 = function(property,value){        if( value ){            property = capitalize(property.toLowerCase());            this.style['webkit'+property] = value;            this.style['Moz'+property] = value;            this.style['ms'+property] = value;            this.style['O'+property] = value;            this.style[property.toLowerCase()] = value;        }else{            return window.getComputedStyle(this).getPropertyValue(                    ('webkit'+property)||('Moz'+property)||('ms'+property)||('O'+property)||property);                    //老实说,我不知道为什么要把不带浏览器标记的放在最后,既然都这么用,我也这么做吧。不过这样对现代浏览器来说可能并不好,判断次数变多了        }                //首字母大写        function capitalize(word){            return word.charAt(0).toUpperCase() + word.slice(1);        }    }

jQuery实现

$(function(){        var percent = parseInt($('.mask :first-child').text());        var baseColor = $('.circle-bar').css('background-color');        if( percent<=50 ){            $('.circle-bar-right').css('transform','rotate('+(percent*3.6)+'deg)');        }else {            $('.circle-bar-right').css({                'transform':'rotate(0deg)',                'background-color':baseColor            });            $('.circle-bar-left').css('transform','rotate('+((percent-50)*3.6)+'deg)');        }    })

jQuery这么简单好用,为什么还要写JavaScript?

一来,学习JavaScript的使用,毕竟有些方法可能是不太熟悉的,多查查文档,混个眼熟。

二来,万一项目中不需要使用jQuery呢,以后还得实现。

三、总结体会

在规定圆的大小的时候,使用了font-size属性,而长度大小则基于font-size,也就是em为单位,这样有一个好处,只要修改font-size的值,就可以改变圆的大小了,非常方便。

另外,写css的时候,尽可能将相同功能的代码提取出来,将某个功能写在一个{}中,起一个好名字,以后方便复用,bootstrap就是这么玩的,简洁、易读,通过classname基本就能知道标签有哪些特性了。

转载地址:http://ygkio.baihongyu.com/

你可能感兴趣的文章
这么说吧,NIO很简单,其实就是个牛逼IO
查看>>
使用Python快速获取公众号文章定制电子书(二)
查看>>
iOS下JS与OC互相调用(七)--Cordova 基础
查看>>
Three.js 关于立方体贴图产生边缘锯齿问题
查看>>
Nacos v0.7.0:对接CMDB,实现基于标签的服务发现能力
查看>>
【开发问题记录①】关于滑动CollectionView时ContentSize变化的问题
查看>>
java中GC的基本概念
查看>>
building xxx gradle project info的解决办法
查看>>
Vagrant (一) - 基本知识
查看>>
在 CentOS 7 上搭建 Jenkins + Maven + Git 持续集成环境
查看>>
数据结构与算法 | Leetcode 19. Remove Nth Node From End of List
查看>>
一起来读you don't know javascript(一)
查看>>
[LeetCode] 862. Shortest Subarray with Sum at Least K
查看>>
【分享】终端命令工具 自动生成vue组件文件以及修改router.js
查看>>
[LeetCode] Student Attendance Record I
查看>>
PHP回顾之多进程编程
查看>>
spring boot + redis
查看>>
Ajax技术细节
查看>>
nuxt.js部署vue应用到服务端过程
查看>>
删除数组中的指定元素 | JavaScript
查看>>