CSS制作环形进度条
参考来源
《Radial progress indicator using CSS》,该文核心是用纯CSS来做一个环形的进度条。纯css的意思就是连百分比这种数字,都是css生成的。文章作者采取的方式是生成100个span标签,然后为这100个标签生成100段css代码(用less生成,代码量倒不大,只是生成的代码量会很大),不知道有没有更NB更省资源的css方案。
而我的需求很简单,只需要学习怎么画环进进度条即可,进度掌控当然得由js来通知(比如下载进度,或者音乐播放进度)
对E文没有恐惧感的话,建议直接看原作者的文,我这不是全文翻译,而是自己的练习。
注:为了方便,我只对chrome写了样式,所以如果要运行我在jsfiddle里面写的例子,最好选webkit系的浏览器
起步
原作者讲解得很详细,我们直接跳过吧,自己学习css3关于动画的部分,总之,先成功一个例子再说:
html
<div class="radial-progress">
<div class="circle">
<div class="mask">
<div class="fill"></div>
</div>
</div>
</div>
一个容器,一个一环形元素,再加一个mask,和fill,后面介绍
css
为了直接在jsfiddle上使用,我也用less吧,毕竟只要一句js声明即可客户端解析(插一句,工程项目建议用sass,因为有compass这个库,大大减轻工作量)
@size:120px;
@bgcolor:#ddd;
@bgcolor1:#cc7;
@duration:1s;
*{margin:0;padding:0;}
.radial-progress{
margin:30px 50px;
position: relative;
.comm(){
width:@size;
height:@size;
position: absolute;
top:0;
left:0;
border-radius: 50%;
}
.circle{
.comm;
background: @bgcolor;
.mask{
clip:rect(0,@size,@size,@size/2);
.comm;
}
.fill{
background: @bgcolor1;
clip:rect(0,@size/2,@size,0);
transition:-webkit-transform @duration;.comm;}
}
}
js
$('head style[type="text/css"]').attr('type', 'text/less');
less.refreshStyles();
$(function(){
var m=$(".fill"),el=$("#deg").val(60),cur=$("#cur");
$("#start").click(function(){
var deg=el.val()||60;
m.css("transform","rotate("+deg+"deg)");
cur.text(deg);
el.val(Math.ceil(Math.random()*180));
});
$("#start").click();
});
讲解
- 要想弧形运动,首先想到了css3的rotate,并且rotate的旋转原点正好是中心,不需要额外设置,所以我们选择了这个属性。
- 其次,进度条从无到有,显然不能像直线进度条一样,设置宽度和高度即可,我们只能选择一个层从另一个层的遮挡中逐渐出现这种方案,这就是我们取名叫mask和fill的原因.
- 上面就是我们的实现:把进度条所属的块只显示左半边,而盛放进度条用的容器,却只显示右半边,(只显示半边是怎么做到的?学习CSS3 clip),这样,我们看不到任何进度条所属的色块,因为它压根就没出现在容器范围内。
- 然后我们让左边的进度条色块进行旋转,一旦旋转到右侧,色块自然就能在右侧看到了(容器一直在右侧,但是无底色,只有进度条有底色,所以核心就是让进度条色块通过旋转,进入到容器所在的位置内
- 此图表示左边色块大概转了一百多度转到了右边
- 最后,加上50%的弧度,圆形就出现了
- 看看效果:http://jsfiddle.net/walker/smMzz/,饼图是制作成功了
360度
上面的例子做完后,你应该发现这种转法,最多只能转180度啊!好吧,于是我们如法泡制,画一个左边的容j器和右边的色块:
html
<div class="radial-progress">
<div class="circle">
<div class="mask left">
<div class="fill"></div>
</div>
<div class="mask right">
<div class="fill"></div>
</div>
</div>
</div>
css
@size:120px;
@bgcolor:#ddd;
@bgcolor1:#cc7;
@duration:1s;
*{margin:0;padding:0;}
.radial-progress{margin:30px 50px; position: relative;
.comm(){
width:@size;height:@size;position: absolute;top:0;left:0;border-radius: 50%;
}
.circle{
background: @bgcolor;.comm;
.mask,.fill{.comm;}
.fill{
background: @bgcolor1;
transition:-webkit-transform @duration;
}
.left{
clip:rect(0,@size/2,@size,0);
.fill{clip:rect(0,@size,@size,@size/2);}
}
.right{
clip:rect(0,@size,@size,@size/2);
.fill{clip:rect(0,@size/2,@size,0);}
}
}
}
js不变,直接运行http://jsfiddle.net/walker/smMzz/1/
显然不是我们要的效果
改进
这时作者做了大胆的改动,别的进度条方案我还没来得及研究,总之他这种是非常“别扭”的,管它呢,先实现,后面的就都不贴代码了,每一节后面都有我贴的jsfiddle的地址,可以直接去看源码。
- 首先,去掉了“左,右”蒙板的概念,而是把两个蒙板都并列摆在右侧(一个叫half,一个叫full),蒙板包含的色块仍然叫fill,这样js一次就同时旋转了两个色块。
- 这样的结果肯定是没有任何变化啊!因为两个层仍然是叠在一起的。所以,作者又让
.full
这个层整个蒙板也旋转同样的角度!【注意】,此时两个蒙板其实已经不重合了。这样,本来两个重叠的色块,因为某一个容器继续旋转了同样的角度,比如30度,视觉上就出现了60度范围的色块! - 所以说别扭,是别扭在,我们封装这种进度条,其实最大只需要旋转180度。
- 见结果:http://jsfiddle.net/walker/smMzz/2/
- 最后,因为事实上是两个色块拼接的,拼接处有一条细线(只有在动画进行的过程中才有),仔细看上面链接的演示。于是作者继续给出解决方案:在half层里面添加一个色块,class也是fill,所以也会被js控制进行旋转,但是这个fix的fill是直接按2倍角度旋转的,这样在旋转的过程中,因为速度的不同,它就挡住了那条白线(这里才需要对js进行一点修改,2倍旋转fix层)。
- 如果对用户体验没这么关心(怎么可能!),其实这件事可以不做的。修改后见:http://jsfiddle.net/walker/smMzz/3/
把饼图改成环图
至此已经大功告成,我们中间再添加一个跟底色一样的div把它变圆不就可以了吗?
对的,顺便还加了点内阴影外阴影,这样就有3D甜甜圈的效果了:http://jsfiddle.net/walker/smMzz/4/
如果要看代码,就注意一下,这一步只是添加了一个.inset
和一个.shadow
,对应的css看源码。
我们这里就不要3D了,简化一下,把3D啊,阴影啊,都去掉:http://jsfiddle.net/walker/smMzz/5/
模拟进度条
至此,我参考的老外原文已经和我下面的东西不沾边了,感兴趣他怎么用纯css来实现动态进度条的可继续在原文观看,我这里基本上是js部分了,目的是让进度条响应当前进度。
- 我们添加一个div来放数字,位置就在
.inset
里面,以百分号表示 - 我们封装一个js方法,见源码的
run
和process
方法,其中process
其实就是把前面onclick的内容给提取了出来,只需要传入一个100以内的数字 - 而run方法则包含了一定业务逻辑此处的逻辑是传入一个开始进度和结束进度,我就每1%调用一次进度条(真实的业务逻辑一般为:我监测下载进度,或歌曲播放进度,一旦有变化,就通知这个函数更改UI)
- 讲解得比较抽象,运行一下结果再看代码:http://jsfiddle.net/walker/smMzz/6/
- 补充一句,前面之所以要有1秒的动画切换时间,纯粹为了好看(各种js生成的图表,也是为了展示这个生成过程,好看),而我们用来做“被通知”的进度条的时候,就没必要了,比如你现在在89%,要跳到90%,那就直接转到90%即可,而不是需要这1S的转场时间。因为事实上我们已经有这个时间了:下载的时间,歌曲播放的时间。所以我把transition去掉了。
模拟播放器
上面的例子是模拟下载或者上传进度条。什么意思?不管是上传,还是下载,进度只是一个“状态”,你不能手动更改这个状态,而播放器则不同,你更改这进度条的百分比,应该能影响歌曲或影片从哪个时间点开始播放,因此,我们需要响应点击事件,同时还要会计算点击位置的角度:
- 我们选择
.circle
作为点击事件的响应对象,因为不受.mask
和.fill
元素是否可见的影响。并把其鼠标状态改为手形 - 一旦进度条出现,就会覆盖在
.circle
上面,所以我们又要把.mask
和.fill
这两个层设为鼠标穿透(用pointer-events:none
实现),以免点击不到.circle
元素 - 计算角度的函数见源码,我也是网上搜的,有效。
- 角度转化成百分比,调用run函数,it works
- 最后,干脆替换一个播放器按钮
- 见示例: http://jsfiddle.net/walker/smMzz/7/
CSS制作环形进度条的更多相关文章
- iOS 开发技巧-制作环形进度条
有几篇博客写到了怎么实现环形进度条,大多是使用Core Graph来实现,实现比较麻烦且效率略低,只是一个小小的进度条而已,我们当然是用最简单而且效率高的方式来实现. 先看一下这篇博客,博客地址:ht ...
- 【CSS】环形进度条
效果图 原理剖析 1.先完成这样一个半圆(这个很简单吧) 2.overflow: hidden; 3.在中间定位一个白色的圆形做遮挡 4.完成另一半 5.使用animate配合时间完成衔接 源码 &l ...
- 微信小程序纯css制作圆形进度条所遇到的问题
wrapBox:最外层盒子,背景色为进度条的颜色 leftBox/rightBox:半宽等长 左/右浮动的盒子,背景色为灰色 roundMask:居中的盒子 用来遮盖leftBox和rightBox ...
- 利用jQuery和CSS实现环形进度条
实现原理 原理非常的简单,在这个方案中,最主要使用了CSS3的transform中的rotate和CSS3的clip两个属性.用他们来实现半圆和旋转效果. 半环的实现 先来看其结构. HTML < ...
- 图解CSS3制作圆环形进度条的实例教程
圆环形进度条制作的基本思想还是画出基本的弧线图形,然后CSS3中我们可以控制其旋转来串联基本图形,制造出部分消失的效果,下面就来带大家学习图解CSS3制作圆环形进度条的实例教程 首先,当有人说你能不能 ...
- [Swift通天遁地]一、超级工具-(2)制作美观大方的环形进度条
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- 【css】如何实现环形进度条
最近团队的童鞋接到了一个有关环形进度条的需求,想要还原一个native的沿环轨迹渐变进度条的效果,看到这个效果的时候,笔者陷入了沉思.. 环形进度条的效果,最先想到的就是使用CSS利用两个半圆的hac ...
- N 种仅仅使用 HTML/CSS 实现各类进度条的方式
本文将介绍如何使用 HTML/CSS 创建各种基础进度条及花式进度条及其动画的方式,通过本文,你可能可以学会: 通过 HTML 标签 <meter> 创建进度条 通过 HTML 标签 &l ...
- iOS一分钟学会环形进度条
有几篇博客写到了怎么实现环形进度条,大多是使用Core Graph来实现,实现比较麻烦且效率略低,只是一个小小的进度条而已,我们当然是用最简单而且效率高的方式来实现.先看一下这篇博客,博客地址:htt ...
随机推荐
- Trojan.Backdoor分析
总结:这是一个HTTP的后门,以安装(-in)||移除(-re)||配置(-c)为目的运行此程序时, 必须指定abcd为最后一个参数. 安装时他会把自身拷贝到%SYSTEMROOT%\WINDOWS\ ...
- Spark 中Java实现数据库Row转Rating
Dataset<Row> ratings = mlsc.sql("SELECT user,movie,rating FROM data");JavaRDD<Row ...
- XAMPP本地服务器打不开解决方案
第一步:先开启相关服务:如图 第二步:在浏览器上输入localhost:端口号,(或127.0.0.1:端口号),按回车,就成功登陆本地服务器. =========================== ...
- SpringBoot Actuator
SpringBoot Actuator 提供了检查项目内部信息的一整套API,通常在项目启动时可以看到. 1.引入依赖包 <dependency> <groupId>org.s ...
- python 提取字符串中的指定字符 正则表达式
例1: 字符串: '湖南省长沙市岳麓区麓山南路麓山门' 提取:湖南,长沙 在不用正则表达式的情况下: address = '湖南省长沙市岳麓区麓山南路麓山门' address1 = address.s ...
- @EnableHystrix
@EnableHystrix 启动熔断降级服务 @Component把普通的pojo类实例到spring容器中去,相当于配置文件中的<bean id="" class=&qu ...
- json格式字符串用Uncaught SyntaxError: Unexpected token ' Uncaught SyntaxError: Unexpected number
Unexpected number(index)的错误用的json字符串如 var jsonStr = "{1:'北京note备注信息',2:'上海note备注信息',3:'广东note备注 ...
- 1019. General Palindromic Number (20)
生词以及在文中意思 forward 向前地 backward 向后地 palindromic 回文的 base 基数(如十进制的10 和二进制的2) numeral system 数制 decimal ...
- Spring Factory
BeanFactory和FactoryBean均为接口: BeanFactory为IOC容器的创建提供了一个最底层的规范,主要方法包括contains(bean), getBean(class, be ...
- eclipse安装反编译插件(附jad下载)
eclipse安装反编译插件(附jad下载) 博客分类: eclipse 一.eclipse反编译插件Jadclipse jadclips插件网站: http://jadclipse.sou ...