饼状图在网页中的运用极为普遍,比如简单的统计图表、进度指示器、定时器等,通常人们会用图像处理软件来制作,那么今天我们一起学习下如何通过纯CSS的方法来实现任意比率的饼状图。
知识点: CSS线性渐变:linear-gradient; CSS动画:@keyframes规则和animation引用;
1、固定比率(<=50%)的饼状图
首先我们制作一个绿色背景的圆形
HTML <div class="pie></div> CSS .pie{ width: 500px; height: 500px; background: yellowgreen; border-radius: 50%; }
如果我们打算用棕色(#655)来表示比率的话,那么需要先把上面圆形的一半设置为棕色,只需要一个简单的线性渐变即可实现:
background-image: linear-gradient(to right, transparent 50%, #655 0);
接着我们通过设置伪元素的样式(背景颜色与圆形背景颜色相相同:yellowgreen)将棕色部分进行遮盖,添加代码如下:
.pie::before{ content: ''; display: block; margin-left: 50%; height: 100%; background: yellowgreen; }
然后去掉矩形突出圆形的多余部分,可以给 .pie 设置 overflow: hidden,或是给伪元素指定合适的border-radius属性来把它变成一个半圆。
pie::before{ content: ''; display: block; margin-left: 50%; height:100%; background:yellowgreen; border-radius:0 100% 100% 0/50%; }
最后,我们可以通过rotate()旋转属性让这个伪元素转起来,当然我们希望它是绕着圆形的中心来旋转的,对他自己来说,这个旋转中心就是它左边缘的中心点,因此,可以把它的 transform-origin 设置为:0 50%,或者干脆写成left也可以。如果我们要显示出30%的比率,就可以指定其旋转值为108deg(30% × 360 = 108)。
pie::before{ .content: ''; display: block; margin-left: 50%; height: 100%; background:yellowgreen; border-radius:0 100% 100% 0/50%; transform-origin: left; transform: rotate(108deg);
2、固定比率(>=50%)的饼状图
如果不加修改直接用上面的方法来制作比率大于50%的饼状图,你会发现一个明显的bug,如下图显示60%的比率时所出现的问题,本该显露的部分不但没有显示出来已有的部分反而被覆盖了一部分。
要解决这个问题很简单,将覆盖层即伪元素部分的背景颜色修改为棕色(#655),在旋转时只需旋转大于50%的部分,如:要显示60%的比率时只需要旋转10%的度数36°即可
.pie::before{ content: ''; display: block; margin-left: 50%; height: 100%; background: #655; border-radius:0 100% 100% 0/50%; transform-origin: left; transform: rotate(36deg); }
3、比率从0到100%动态显示
通过上面两种方法我们已经可以实现任意比率的饼状图了,那么结合CSS的动画属性便可以实现一个饼状图从0变化到100%的动画(也可以看做是一个进度指示器)。
@keyframes scoll{ to{transform: rotate(180deg);} } @keyframes bg{ 50%{background: #655;} } .pie::before{ content: ''; display: block; margin-left: 50%; height: 100%; border-radius:0 100% 100 0/50%; background: yellowgreen; animation: scoll 3s linear infinite, bg 6s step-end infinite; }
4、通过负的动画延时实现任意比率的静态饼状图
既然我们已经可以动态显示从0到100%比率的饼状图,在此基础上如果可以让动画根据需要定格在某一时刻,那么就不用再像方法1和方法2那样区别对待50%前后的两种情况了。这里我们可以用负的动画延时来直接眺至动画中的任意时间点,并通过暂停属性paused把它定格在那里。
假设动画持续时间为100s,那么只需要把animation-delay设置为-30s,就可以显示出30%的比率了(如果是-60s就表示60%比率)。
.pie::before{ /*其余的样式代码与方法三中保持一致*/ animation: scoll 50s linear infinite, bg 100s step-end infinite; animation-delay: -30s; animation-play-state: paused; }