盡管網上有很多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。
