CSS3+JS实现静态圆形进度条

更新日期: 2018-01-02阅读: 6.4k标签: 进度条

一、实现原理

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


OK,我们再旋转更大的度数试试,比如40%(144度),50%(180度),60%(216度)如下图。
我们发现,旋转180度之后右半圆与左半圆重合了,如果再旋转,就会在右上角冒出来,显然不是我们想要的。


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

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


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

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


二、代码实现

html部分

<div class="circle-bar">
    <div class="circle-bar-left"></div>
    <div class="circle-bar-right"></div>
    <!-- 遮罩层,显示百分比 -->
    <div class="mask">
        <span class="percent">60%</span>
    </div>
</div>

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基本就能知道标签有哪些特性了。

来源:segmentfault

链接: https://www.fly63.com/article/detial/304

原生JS+CSS或HTML5实现简单的进度条和滑动条效果

我们在客户端中见到的安装进度条效果以及滑块拖动效果,使用js+css都能够在页面中进行模拟,并且方法也并不复杂.我这里进行了简单的效果实现,记录一下以作巩固.

html自定义拖动进度条,包含样式和事件

将 mousedown 事件绑定在进度条的包裹层而非进度条本身,这是参考了主流视频播放器的效果后的设计,为了优化用户体验,鼠标在滚动条外的移动,本文使用 clientX 来计算

jQuery 实现一个文章阅读进度条功能

阅读进度虽然没啥具体的用处,但是我突然想起来了,随便做做也是极好的,获取元素 offset 高度、元素高度、滑动距离就能实现了

利用canvas实现环形进度条

有时候在项目中会有用到进度条的情况,使用css3也可以实现,但是对于性能不好的设备,或者网络不好的情况下,卡顿现象非常明显,避免出现不流畅的尴尬情况,所以记录一下,使用canvas来实现的方法。

在vue项目中使用Nprogress.js进度条

NProgress是一款在网页顶部添加细长进度条的工具,非常轻巧,使用起来也非常便捷,灵感来源于Google, YouTube。在路由页面跳转使用,同样在main.js中:

svg生成环形进度条

之前在项目中遇到一个环形进度条的需求,要求能实时更新进度,脑海中瞬间便蹦出css,svg,canvas3中方案,对于3种方案个人更偏向于svg,用法简单,代码量也很少,同时也便于实时控制。具体效果如下图:

js实现进度条代码

现在很多网站会用到进入网站特效,到网页没有加载完成的时候,会有一个loding特效,加载完了之后才能看到页面,今天就带着做一个js进度条效果,今天要做的效果是纯js进度条加载,没有用到框架

css进度条怎么写?

进度条经常运用于网页,即使我们意识到不是所有的东西都将瞬间被加载完成,这些进度条用于提醒使用者关于网页上具体的任务进程,譬如上传,下载,加载应用程序等。

AngularJS实现进度条功能示例

这篇文章主要介绍了AngularJS实现进度条功能,结合具体完整实例形式分析了AngularJS实现进度条功能的原理、相关知识点与注意事项,需要的朋友可以参考下

纯css设置单选框/进度条样式

设置radio样式原理:使用 :checked+label 切换样式图片。checkbox也可以这么做。进度条样式原理:为三个页面的进度条分别设置不同的value,由此切换背景图片。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!