CSS3教程:真·任意角度扇形画法

Posted 化龙科技

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSS3教程:真·任意角度扇形画法相关的知识,希望对你有一定的参考价值。

如果去网上搜索,很多种画法,无论是用伪元素的还是用多个DIV的,其实都是假扇形。

假扇形缺点:

1.占用完整圆形空间:因为都是遮罩实现,但要遮罩就一定无法透明,因为透明遮不住任何东西。

2.无法独立操作:同样因为遮罩实现,所以看到的是扇形,实际上并不是!

3.饼型图多个扇形结构复杂:在同一个圆里处理多个遮罩夹角,并不容易处理层级问题。

那么,有没有真扇形的绘制方法呢?当然有!

先看一下成果:

首先,事情的研究一定是探寻事物的本质,让我们看看它去掉圆角(border-radius)的样子:

CSS3教程:真·任意角度扇形画法

接着,我们去掉旋转(transform:rotate):

CSS3教程:真·任意角度扇形画法

这样其实已经很清晰了,可能绿色的部分是一个干扰,OK,让我们把它也去掉:

CSS3教程:真·任意角度扇形画法10%

CSS3教程:真·任意角度扇形画法30%

CSS3教程:真·任意角度扇形画法60%

90%

可以看到,实际上我是在一个正方形下完成的绘制,上面四张图刚好是四个不同的阶段,我们逐一来讲解:

第一阶段:这个阶段是最简单的阶段,典型的锐角扇形,实际上就是一个三角形,除中心点外,其余的两个点都在第一条边上,这时我们只要绘制一个三角形即可,一切也都由此为基础,那么如何确定角度呢?很简单,第一个点为左上[0,0]原点不变,中心点为[50%,50%]不变,此时控制角度的点为右上方的点我们称之为移动点,当移动点刚好在右上角时,则夹角刚好为90度,由此可以得出结论:当移动点横向座标位址为100%时,为90度,因此我们可以得出代码:横向座标百分比=所需角度 / 90 * 100; 例如18度角则是 18 / 90 * 100,得出移动点横向座标为20%,所以我们可以写CSS:clip-path:polygon(0% 0%,20% 0%,50% 50%);分别是左上角座标,移动点座标,中心点座标,记得一定把中心点放在最后,否则接下来超过90度的角会出问题,这样我们就得到一个中心夹角为18度的三角形。

第二阶段:这个阶段开始有所不同,因为夹角超过了90度,如果继续用三角形,原点和移动点之间的连线会直接斜穿可见区域,因此不能用三角形了,我的做法是拆分角度,首先超过90度的角度就说明第一区域必然填满,所以我把它分为90+N的方式,首先绘制原点,右上角顶点,然后是移动点,中心点依旧放在最后。由三角形变为四边形,多了一个右上角顶点,同时因为移动点落在竖边上,座标变为Y座标,座标只计算超出90的部分,也就是90+N的N,公式变为:纵向座标百分比=(所需角度 - 90) / 90 * 100,例如108度角为 (108 - 90) / 90 * 100,同样得出20%,不同的是这20%落在右边的边上,CSS:clip-path:polygon(0% 0%, 100% 0%, 100% 20%, 50% 50%),这样的到的4边型与上面30%的图是一致的,因为360度的30%就是108度。

第三和第四阶段:这两个阶段与第二阶段类似,只是方向是反的,第三阶段是从右向左逐渐加大,第四阶段则是从下向上,因此座标要反转一下,例如198度在第三阶段是去掉已经填满的两个90度,也就是剩18度,但是剩余的18度位址是由右下角开始向左20%,所以X的座标应该是100% - 20% = 80%,而不是20%。第四阶段同样,减去已填充满的3个90度,同样因为是从下向上反向增长所以要将剩余的取返。


这样我们就在方形中填充了一个多边形,从第一阶段的三角形到第四阶段的六边形。甚至这种填充比圆形还酷。如果想要全动画,那么可以在一开始就按六边形写,只不过第一阶段四个点重合,每到一个顶点留下一个点,剩余的继续沿边走。transitions补间要求clip-path顶点数相同才能补间。

接下来就是完善了,首先原点与中心点的连线不能改变!所以当你需要的起始边方向不是左上45度时,只需要整体旋转一定角度,这就是为什么我的示例最开始是转了45度的,因为饼型图起始是正上方,所以我需要把起始线简单的旋转到中间。

然后是扇形,很简单,只是加上border-radius属性就好,

这里并不需要给外部添加,因为clip-path是基于方形裁切的,直接给我们的多边形加上圆角,在圆角之外的部分就不会显示出来了,border-radius只对原始的矩形div生效,所以不会给扇形的每个角加上圆角,不需要在外面套一层加overflow:hidden遮罩。

灰色背景只是背景,多边形并不是套在灰色的DIV里面的,背景和多边形是同级的。

这样的扇形是真正的扇形,并且经过clip-path裁剪的图形是精确的图形,也就是说,只有扇形本身是有效的,透明区域都可以直接点到下方,不会有透明的部份遮挡下方点击事件。

特别说明,本例使用饼型图作为案例,因此是一个完整的圆形,如果只要一个扇形(中心角度不超过135度),完全可以把中心点放到正下方,这样可以去掉不使用的第三阶段的部份,原始div高度减少一半。如果想做大一些,中心不超过90度的扇形,可以把中心点移到矩形的一个顶点,但是这样角度算法会有所不同,因为如果中心点在一个顶点,那要达到90度移动点就要到右下角,跨越两条边,不太建议这样做。

最后贴上代码:

html

<piearea> <!--大的边界-->  <pie></pie> <!--背景-->  <pie-content1></pie-content1> <!--多边形--></piearea>

JS

percent = 0.20//0-1百分比
var angle = 360 * percent; if(angle > 360) angle = 360; var polygon = "";          if(angle > 270){ //第四阶段 var addonAngle = (angle - 270) / 90; var trans = (1 - addonAngle) * 100; polygon = 'polygon(0% 0%,100% 0%,100% 100%,0% 100%,0% ' + trans + '%,50% 50%)';          }else if(angle > 180){ //第三阶段 var addonAngle = (angle - 180) / 90; var trans = (1 - addonAngle) * 100; polygon = 'polygon(0% 0%,100% 0%,100% 100%,' + trans + '% 100%,50% 50%)';          }else if(angle > 90){ //第二阶段 var addonAngle = (angle - 90) / 90; var trans = addonAngle * 100; polygon = 'polygon(0% 0%,100% 0%,100% ' + trans + '%,50% 50%)';          }else//第一阶段 var addonAngle = angle / 90; var trans = addonAngle * 100; polygon = 'polygon(0% 0%,' + trans + '% 0%,50% 50%)'; }
          $("pie-content1").css("clip-path",polygon);

CSS:

piearea { position: relative; display: block; width: 200px; height: 200px; margin-top: 100px; transform: rotate(0deg); } pie { position: absolute; display: block; top: 0px; left: 0px; width: 100%; height: 100%; border-radius: 0%; background-color: lightgray; transition: 300ms; }    pie-content1{ position: absolute; display: block; top: 0px; left: 0px; width: 100%; height: 100%; border-radius: 100%; clip-path:polygon(0% 0%,50% 0%,50% 50%); background-color: lightblue; transition: 300ms;    }    pie-content1:hover { filter: brightness(1.1); }


以上是关于CSS3教程:真·任意角度扇形画法的主要内容,如果未能解决你的问题,请参考以下文章

如何用css3实现一个扇形?

如何使用纯css制作扇形图,合并起来形成饼图

用css3 绘制画圆与扇形

H5扇形

CSS3教程盒子旋转动态图

帆软报表(finereport)入门 3-图表——扇形图/等弧度的玫瑰图