《css揭秘》笔记(十一), 简单饼图效果

本文介绍了如何使用CSS创建一个简单的固定比率20%的饼图效果。通过结合元素、伪元素、变形属性和CSS渐变,实现了一个圆形背景上的扇区遮罩。文章详细解释了设置伪元素的样式、旋转角度以及如何通过动画实现不同比率的饼图展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单饼图效果

基于transform的解决方案

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

假设我们目前需要一个简单的饼图,其展示的比率是固定的20%,首先把这个元素设置为一个圆形,以它为背景。然后使用棕色来显示比率。

把圆形的左右两部分指定为上述两种颜色,然后用伪元素覆盖上去,通过旋转决定露出多大的扇区。

.box1{
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: yellowgreen;
  background-image:
    linear-gradient(to right, transparent 50%, #655 0);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PDbryZbr-1590112080510)(3图形/img/54.png)]

我们可以继续设置伪元素的样式,让它起到遮盖层的作用:

.box1::before{
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
}

然而此时它只是一个透明的矩形,我们还需要继续考虑为它设置其它的属性以达到我们想要的效果。

我们希望它能遮盖圆形的棕色部分,因此应该给它指定绿色的背景,这里使用background-color: inherit让它与其宿主颜色保持一致。

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

我们不希望它呈现出矩形的形状,否则它会突破整个饼图的圆形范围,因此要么给.box设置overflow: hidden的样式,要么给这个伪元素指定合适的border-radius属性来把它变成一个半圆。

把上述思路转换成css则是:

.box1{
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: yellowgreen;
  background-image:
    linear-gradient(to right, transparent 50%, #655 0);
}
.box1::before{
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
}

然后通过设置rotate()变形属性来让这个伪元素转起来。例如,我们要显示出20%的比率,可以指定旋转角度为72deg(0.2*360=72),写成.2turn更加直观。

.box1{
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: yellowgreen;
  background-image:
    linear-gradient(to right, transparent 50%, #655 0);
}
.box1::before{
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
  transform: rotate(.2turn);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cfAB8KUO-1590112080520)(3图形/img/55.png)]

然而由于一开始为圆形设置一半棕色一半绿色,所以当rotate()的值超过.5turn时,它就是完整的绿圆形状。

我们可以使用上述技巧的反向版本来实现这个范围的比率:设置一个棕色的伪元素,让它在0至.5turn的范围内旋转。

因此一个60%比率的饼图的形状就是:

.box2{
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: yellowgreen;
  background-image:
  linear-gradient(to right, transparent 50%, #655 0);
}
.box2::before{
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: #655;
  transform-origin: left;
  transform: rotate(.1turn);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aA3kyU3B-1590112080533)(3图形/img/56.png)]

甚至可以用一个css动画来实现一个饼图从0到100%的动画,从而得到一个酷炫的进度指示器。

.box3{
  margin: 20px;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: yellowgreen;
  background-image:
  linear-gradient(to right, transparent 50%, #655 0);
}
@keyframes spin {
  to {
    transform: rotate(.5turn);
  }
}
@keyframes bg{
  50% {
    background: #655;
  }
}
.box3::before{
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
  animation: 
    spin 3s linear infinite, 
    bg 6s step-end infinite;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0UzL4du6-1590112080544)(3图形/img/57.gif)]

我们可以通过以上的动画中的任意时间点状态得到我们想要的比率,比如说动画持续时间是6s,饼图上显示的比率就是我们animation-delay设置为-1.2s,就能显示出20%的比率。这里的动画是处于暂定状态的,因此不会有副作用。

我们可以用内联的方式为div设置anitmation-delay: inherit属性,因此我们让饼图显示为20%的结构代码为:

<div class="box5" style="animation-delay: -20s">
</div>

我们为动画准备的css代码就会变成这样:

.box4{
  margin: 20px;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: yellowgreen;
  background-image:
  linear-gradient(to right, transparent 50%, #655 0);
}
@keyframes spin{
  to {
    transform: rotate(.5turn);
  }
}
@keyframes bg{
  50% {
    background: #655;
  }
}
.box4::before{
  content: '';
  display: block;
  margin-left: 50%;
  height: 100%;
  border-radius: 0 100% 100% 0 / 50%;
  background-color: inherit;
  transform-origin: left;
  animation: 
    spin 50s linear infinite,
    bg 100s step-end infinite;
  animation-play-state: paused;
  animation-delay: inherit;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DGGC6K3C-1590112080552)(3图形/img/58.png)]

本篇文章是《css揭秘》一书的笔记,如果侵犯了原著作者权益,请联系我删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值