CSS绘制正五角星原理(数学模型)
尽管网上有很多CSS绘制五角星的代码案例,但是对于初学者来说可以拿来移植使用,但是在不明白其原理的情况下,进行修改移植就比较困难了。譬如想要将五角星尺寸进行缩小或者放大等设计,就需要对原代码相关数据进行修改。如果不清楚代码实现时的原理,就无法对代码的各项数据进行正确的改动维护。和CSS绘制三角形的原理一样,CSS绘制五角星同样也是从数学模型上着手才能明白各项参数的作用,以及各项参数之间的关联关系。
基于三个特殊角度的全等三角形旋转构建正五角星
根据正五角星的数学特性,正五角星可以由特殊角度的三角形绕五角星外接圆圆心经过旋转72°与-72°而实现。满足正五角星的特征的特殊三角形△aEB的角度为36°、36°、108°。该三角形在三个位置的图案即组成满足要求的正五角星。
数学模型:过五角星ABCDE外接圆圆心O做BE的垂线,垂足为L。假设BE长度为t,五角星外接圆半径为R。用R表示t与线段OL的长度。
根据正五角星的数学特性,∠EOL=72°,∠0EL=18°,L为BE的中点,那么简单的三角函数关系:
OL/(t/2)=tan18°
即:
OL=R·sin18°
t=2R·cos18°
OL的值为三角形旋转基点的垂直数值。
tan18°=(√5-1)/√(10+2√5)≈0.32491969623291
cos18°=√(10+2√5)/4≈0.95105651629515
正五角星外接圆R=60px与正五角星边长则为:114.126px,根据几何关系△aEB的边长为217.08px、134.16px、134.16px。
根据CSS绘制三角形原理,可以获得绘制三角形的重要数据:78.86、108.54、108.54。参见CSS绘制三角形原理查看获取三个参数的计算过程。
HTML代码:
<div class='pentagram'>
</div>
CSS代码:
.pentagram { width:0; height:0; border-top-color: red; border-left-color: transparent; border-right-color: transparent; border-top-width: 78.86px; border-left-width: 108.54px; border-right-width: 108.54px; border-style:solid; }
采用伪元素的方式在父元素的位置绘制等大小的三角形,需要在父元素设置相对定位。
.pentagram { position:relative; }
采用伪元素的方式实现代码:
.pentagram::before { border-width:0; content: ''; display: block; width: 0; height: 0; border-top-color: red; border-left-color: transparent; border-right-color: transparent; border-top-width: 78.86px; border-left-width: 108.54px; border-right-width: 108.54px; border-style: solid; position:absolute; top:-78.86px; left:-108.54px; } .pentagram::after{ border-width:0; content: ''; display: block; width: 0; height: 0; border-top-color: red; border-left-color: transparent; border-right-color: transparent; border-top-width: 78.86px; border-left-width: 108.54px; border-right-width: 108.54px; border-style: solid; position:absolute; top:-78.86px; left:-108.54px; }
确定旋转中心点位置数据:108.54px 35.26px元素旋转是以元素的border-box盒模型来确定相关数值的,左上角为0 0。
所以最终完整的代码如下:
* { border: none; border-width:0; margin:0; } .pentagram { margin:100px; width: 0; height: 0; border-top-color: red; border-left-color: transparent; border-right-color: transparent; border-top-width: 78.86px; border-left-width: 108.54px; border-right-width: 108.54px; border-style: solid; /* 相对定位是与绘制三角形无关 */ position: relative; } .pentagram::before { border-width:0; content: ''; display: block; width: 0; height: 0; border-top-color: red; border-left-color: transparent; border-right-color: transparent; border-top-width: 78.86px; border-left-width: 108.54px; border-right-width: 108.54px; border-style: solid; position:absolute; top:-78.86px; left:-108.54px; transform:rotate(72deg); transform-origin:108.54px 35.26px; } .pentagram::after{ border-width:0; content: ''; display: block; width: 0; height: 0; border-top-color: red; border-left-color: transparent; border-right-color: transparent; border-top-width: 78.86px; border-left-width: 108.54px; border-right-width: 108.54px; border-style: solid; position:absolute; top:-78.86px; left:-108.54px; transform:rotate(-72deg); transform-origin:108.54px 35.26px; }
注意:虽然在CSS通配符中设置了border-width值为0,但是伪元素中若不设置border-width:0; 在chorme和UC浏览器中测试会导致伪元素中出现默认的3px宽黑色边框,似乎是一个 bug。