画个饼图做成CSS进度指示器了

 2016-09-30 13:48

饼图

饼图在网页中运用极为普通,比如简单的统计图表、进度指示器、时钟等。尽管如此,饼图在很长的一段时间里完全无法通过Web技术创建出来。

过去要实现饼图,要么动用一个外部的图像处理软件来为饼图多个值制作多张图片,要么动用专门辅助的JavaScript。

尽管这件大事情已经不像过去那样“难于上青天”,但也依然不存在一行代码万事大吉的捷径。眼下,的确有一些更便捷、更易维护的方法了。

基于transform的方法

这个方法在结构层里面是最佳选择:它只需一个元素作为容器,而其他部分由伪元素、变形属性和CSS渐变来实现。

假设我们目前的需求是一个最简单的饼图,其展示的比率是固定的20%。首先,我们需要一个圆形,以它作为背景。

.bingtu{
    width:100px;height:100px;
    border-radius:50%;
    background:yellowgreen;
}

我们可能会想到用斜向拉伸变形来处理比率扇区,但稍微思考下就会发现这是个死胡同。

于是我们换种思路,把圆形的左右两部分指定两种颜色,然后用伪元素覆盖上去,再通过旋转来决定露出多大的扇区。


.bingtu::before{
    content: '';
    display: block;
    margin-left: 50%;
    height: 100%;
    background: rgba(20,20,20,.2);
}

这里我们可以看到,伪元素和右侧已经重叠,我们给它一个透明让它看起来明显点,其实它还没有开始工作。在开始前,我们要考虑好它有什么功能。

  • 我们希望它能遮罩圆形中的棕色部分,因此应该给它一个绿色背景。通过background-color:inherit声明,我们可以让它和主体代码一致;

  • 我们希望它是绕圆心旋转的,对它来说,这个中心点就是它左边边缘的中点。因此,我们应该把transform-origin设置为0 50%,或者干脆写成left

  • 我们不希望它是矩形,它应该是个圆形,准确的说是个半圆形。我们可以用border-radius属性来做,也可以给它设置一个溢出不显示的命令overflow:hidden

思路出来了,那么我们在上面增加改动下就可以了:

.bingtu::before{
    content: '';
    display: block;
    margin-left: 50%;
    height:100%;
    background-color:inherit;
    border-radius:0 100% 100% 0 / 50%;
    /* 或者是 overflow: hidden; */
    transform-origin:0 50%;
}

剩下就是让伪元素旋转起来了。如果我们要显示出20%的比率,我就用rotate()制定旋转72deg,写成.2turn (0.2x360=72)会更加直观些。

其实,在开始做这个的时候你就有点奇怪,这种遮罩法在0~50%的时候可能会有效,但要是得到一个70%的代码如何做呢?我们可以运用这个方法的反向版本:设置一个棕色的伪元素,让它在0至.5turn的范围旋转。因此得到70%比例的饼图代码应该是这个样子的:

.bingtu::before{
    content: '';
    display: block;
    margin-left: 50%;
    height:100%;
    background-color:#655;
    border-radius:0 100% 100% 0 / 50%;
    /* 或者是 overflow: hidden; */
    transform-origin:0 50%;
    transform: rotate(.2turn);
}

问题又来了,怎么把这两个衔接起来呢?其实,我们可以通过animation命令,让它在.5turn的时候出现一个变化,比且还可以加上过渡时间,形成一个漂亮的进度指示器。

@keyframes spin{
    to {transform:rotate(.5turn);}
}
@keyframes bg{
    50% {background:#655}
}
.bingtu::before{
    content: '';
    display: block;
    margin-left: 50%;
    height:100%;
    background-color:inherit;
    border-radius:0 100% 100% 0 / 50%;
    /* 或者是 overflow: hidden; */
    transform-origin:0 50%;/*left*/
    animation: spin 3s linear infinite,
            bg 6s step-end infinite;
}


作者头像

作者:紫铜炉

自由博主,网页设计师。我关注科技产品和个人博客发展,注重用户体验和界面优化。

 发表评论: