1. 程式人生 > 實用技巧 >CSS繪製正五角星原理(數學模型)

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。