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程式碼:
<divclass='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。